Skip to content

New messenger interface #825

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Nov 3, 2020
11 changes: 5 additions & 6 deletions contracts/SynthetixBridgeToBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import "./interfaces/ISynthetixBridgeToBase.sol";
import "./interfaces/ISynthetix.sol";

// solhint-disable indent
import "@eth-optimism/rollup-contracts/build/contracts/bridge/interfaces/CrossDomainMessenger.interface.sol";
import "@eth-optimism/contracts/build/contracts/iOVM/bridge/iOVM_BaseCrossDomainMessenger.sol";


contract SynthetixBridgeToBase is Owned, MixinResolver, ISynthetixBridgeToBase {
uint32 private constant CROSS_DOMAIN_MESSAGE_GAS_LIMIT = 3e6; //TODO: verify value
uint32 private constant CROSS_DOMAIN_MESSAGE_GAS_LIMIT = 3e6; //TODO: make this updateable

/* ========== ADDRESS RESOLVER CONFIGURATION ========== */
bytes32 private constant CONTRACT_EXT_MESSENGER = "ext:Messenger";
Expand All @@ -26,16 +26,15 @@ contract SynthetixBridgeToBase is Owned, MixinResolver, ISynthetixBridgeToBase {
CONTRACT_BASE_SYNTHETIXBRIDGETOOPTIMISM
];

//
// ========== CONSTRUCTOR ==========

constructor(address _owner, address _resolver) public Owned(_owner) MixinResolver(_resolver, addressesToCache) {}

//
// ========== INTERNALS ============

function messenger() internal view returns (ICrossDomainMessenger) {
return ICrossDomainMessenger(requireAndGetAddress(CONTRACT_EXT_MESSENGER, "Missing Messenger address"));
function messenger() internal view returns (iOVM_BaseCrossDomainMessenger) {
return iOVM_BaseCrossDomainMessenger(requireAndGetAddress(CONTRACT_EXT_MESSENGER, "Missing Messenger address"));
}

function synthetix() internal view returns (ISynthetix) {
Expand All @@ -48,7 +47,7 @@ contract SynthetixBridgeToBase is Owned, MixinResolver, ISynthetixBridgeToBase {

function onlyAllowFromOptimism() internal view {
// ensure function only callable from the L2 bridge via messenger (aka relayer)
ICrossDomainMessenger _messenger = messenger();
iOVM_BaseCrossDomainMessenger _messenger = messenger();
require(msg.sender == address(_messenger), "Only the relayer can call this");
require(_messenger.xDomainMessageSender() == synthetixBridgeToOptimism(), "Only the L1 bridge can invoke");
}
Expand Down
50 changes: 22 additions & 28 deletions contracts/SynthetixBridgeToOptimism.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import "./interfaces/IERC20.sol";
import "./interfaces/IIssuer.sol";

// solhint-disable indent
import "@eth-optimism/rollup-contracts/build/contracts/bridge/interfaces/CrossDomainMessenger.interface.sol";
import "@eth-optimism/contracts/build/contracts/iOVM/bridge/iOVM_BaseCrossDomainMessenger.sol";


contract SynthetixBridgeToOptimism is Owned, MixinResolver, ISynthetixBridgeToOptimism {
uint32 private constant CROSS_DOMAIN_MESSAGE_GAS_LIMIT = 3e6; //TODO: verify value, uint32 to uint in new version
uint32 private constant CROSS_DOMAIN_MESSAGE_GAS_LIMIT = 3e6; //TODO: from constant to an updateable value

/* ========== ADDRESS RESOLVER CONFIGURATION ========== */
bytes32 private constant CONTRACT_EXT_MESSENGER = "ext:Messenger";
Expand Down Expand Up @@ -43,8 +43,8 @@ contract SynthetixBridgeToOptimism is Owned, MixinResolver, ISynthetixBridgeToOp
//
// ========== INTERNALS ============

function messenger() internal view returns (ICrossDomainMessenger) {
return ICrossDomainMessenger(requireAndGetAddress(CONTRACT_EXT_MESSENGER, "Missing Messenger address"));
function messenger() internal view returns (iOVM_BaseCrossDomainMessenger) {
return iOVM_BaseCrossDomainMessenger(requireAndGetAddress(CONTRACT_EXT_MESSENGER, "Missing Messenger address"));
}

function synthetix() internal view returns (ISynthetix) {
Expand All @@ -71,6 +71,16 @@ contract SynthetixBridgeToOptimism is Owned, MixinResolver, ISynthetixBridgeToOp
require(activated, "Function deactivated");
}

function _rewardDeposit(uint amount) internal {
// create message payload for L2
bytes memory messageData = abi.encodeWithSignature("mintSecondaryFromDepositForRewards(uint256)", amount);

// relay the message to this contract on L2 via L1 Messenger
messenger().sendMessage(synthetixBridgeToBase(), messageData, CROSS_DOMAIN_MESSAGE_GAS_LIMIT);

emit RewardDeposit(msg.sender, amount);
}

// ========== MODIFIERS ============

modifier requireActive() {
Expand Down Expand Up @@ -104,20 +114,13 @@ contract SynthetixBridgeToOptimism is Owned, MixinResolver, ISynthetixBridgeToOp
function rewardDeposit(uint amount) external requireActive {
// move the SNX into this contract
synthetixERC20().transferFrom(msg.sender, address(this), amount);

// create message payload for L2
bytes memory messageData = abi.encodeWithSignature("mintSecondaryFromDepositForRewards(uint256)", amount);

// relay the message to this contract on L2 via L1 Messenger
messenger().sendMessage(synthetixBridgeToBase(), messageData, CROSS_DOMAIN_MESSAGE_GAS_LIMIT);

emit RewardDepositByAccount(msg.sender, amount);
_rewardDeposit(amount);
}

// ========= RESTRICTED FUNCTIONS ==============

// invoked by Messenger on L1 after L2 waiting period elapses
function completeWithdrawal(address account, uint amount) external {
function completeWithdrawal(address account, uint amount) external requireActive {
// ensure function only callable from L2 Bridge via messenger (aka relayer)
require(msg.sender == address(messenger()), "Only the relayer can call this");
require(messenger().xDomainMessageSender() == synthetixBridgeToBase(), "Only the L2 bridge can invoke");
Expand All @@ -130,7 +133,8 @@ contract SynthetixBridgeToOptimism is Owned, MixinResolver, ISynthetixBridgeToOp
}

// invoked by the owner for migrating the contract to the new version that will allow for withdrawals
function migrateBridge(address newBridge) external onlyOwner {
function migrateBridge(address newBridge) external onlyOwner requireActive {
require(newBridge != address(0), "Cannot migrate to address 0");
activated = false;

IERC20 ERC20Synthetix = synthetixERC20();
Expand All @@ -142,27 +146,17 @@ contract SynthetixBridgeToOptimism is Owned, MixinResolver, ISynthetixBridgeToOp
}

// invoked by RewardsDistribution on L1 (takes SNX)
function notifyRewardAmount(uint256 reward) external {
function notifyRewardAmount(uint256 amount) external requireActive {
require(msg.sender == address(rewardsDistribution()), "Caller is not RewardsDistribution contract");

// to be here means I've been given an amount of SNX to distribute onto L2

// create message payload for L2
bytes memory messageData = abi.encodeWithSignature("mintSecondaryFromDepositForRewards(uint256)", reward);

// relay the message to this contract on L2 via L1 Messenger
messenger().sendMessage(synthetixBridgeToBase(), messageData, CROSS_DOMAIN_MESSAGE_GAS_LIMIT);

emit RewardDeposit(reward);
_rewardDeposit(amount);
}

// ========== EVENTS ==========

event Deposit(address indexed account, uint amount);
event RewardDepositByAccount(address indexed account, uint reward);

event RewardDeposit(uint reward);

event BridgeMigrated(address oldBridge, address newBridge, uint amount);
event Deposit(address indexed account, uint amount);
event RewardDeposit(address indexed account, uint amount);
event WithdrawalCompleted(address indexed account, uint amount);
}
Loading