Skip to content
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

Bridge rollback mechanism #18

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions contracts/blade/ChildERC1155Predicate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import "../interfaces/blade/IChildERC1155Predicate.sol";
import "../interfaces/blade/IChildERC1155.sol";
import "../interfaces/IStateSender.sol";
import "./System.sol";
import "../lib/Predicate.sol";

/**
@title ChildERC1155Predicate
@author Polygon Technology (@QEDK, @wschwab)
@notice Enables ERC1155 token deposits and withdrawals across an arbitrary root chain and child chain
*/
// solhint-disable reason-string
contract ChildERC1155Predicate is IChildERC1155Predicate, Initializable, System {
contract ChildERC1155Predicate is IChildERC1155Predicate, Predicate, System {
/// @custom:security write-protection="onlySystemCall()"
IStateSender public l2StateSender;
/// @custom:security write-protection="onlySystemCall()"
Expand All @@ -24,11 +25,6 @@ contract ChildERC1155Predicate is IChildERC1155Predicate, Initializable, System
address public rootERC1155Predicate;
/// @custom:security write-protection="onlySystemCall()"
address public childTokenTemplate;
bytes32 public constant DEPOSIT_SIG = keccak256("DEPOSIT");
bytes32 public constant DEPOSIT_BATCH_SIG = keccak256("DEPOSIT_BATCH");
bytes32 public constant WITHDRAW_SIG = keccak256("WITHDRAW");
bytes32 public constant WITHDRAW_BATCH_SIG = keccak256("WITHDRAW_BATCH");
bytes32 public constant MAP_TOKEN_SIG = keccak256("MAP_TOKEN");

mapping(address => address) public rootTokenToChildToken;

Expand Down Expand Up @@ -177,6 +173,7 @@ contract ChildERC1155Predicate is IChildERC1155Predicate, Initializable, System
newChildTokenTemplate != address(0),
"ChildERC1155Predicate: BAD_INITIALIZATION"
);
predicateInit();
l2StateSender = IStateSender(newL2StateSender);
stateReceiver = newStateReceiver;
rootERC1155Predicate = newRootERC1155Predicate;
Expand Down
7 changes: 3 additions & 4 deletions contracts/blade/ChildERC20Predicate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import "../interfaces/blade/IChildERC20Predicate.sol";
import "../interfaces/blade/IChildERC20.sol";
import "../interfaces/IStateSender.sol";
import "./System.sol";
import "../lib/Predicate.sol";

/**
@title ChildERC20Predicate
@author Polygon Technology (@QEDK)
@notice Enables ERC20 token deposits and withdrawals across an arbitrary root chain and child chain
*/
// solhint-disable reason-string
contract ChildERC20Predicate is IChildERC20Predicate, Initializable, System {
contract ChildERC20Predicate is IChildERC20Predicate, Predicate, System {
using SafeERC20 for IERC20;

/// @custom:security write-protection="onlySystemCall()"
Expand All @@ -27,9 +28,6 @@ contract ChildERC20Predicate is IChildERC20Predicate, Initializable, System {
address public rootERC20Predicate;
/// @custom:security write-protection="onlySystemCall()"
address public childTokenTemplate;
bytes32 public constant DEPOSIT_SIG = keccak256("DEPOSIT");
bytes32 public constant WITHDRAW_SIG = keccak256("WITHDRAW");
bytes32 public constant MAP_TOKEN_SIG = keccak256("MAP_TOKEN");

mapping(address => address) public rootTokenToChildToken;

Expand Down Expand Up @@ -141,6 +139,7 @@ contract ChildERC20Predicate is IChildERC20Predicate, Initializable, System {
newChildTokenTemplate != address(0),
"ChildERC20Predicate: BAD_INITIALIZATION"
);
predicateInit();
l2StateSender = IStateSender(newL2StateSender);
stateReceiver = newStateReceiver;
rootERC20Predicate = newRootERC20Predicate;
Expand Down
9 changes: 3 additions & 6 deletions contracts/blade/ChildERC721Predicate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import "../interfaces/blade/IChildERC721Predicate.sol";
import "../interfaces/blade/IChildERC721.sol";
import "../interfaces/IStateSender.sol";
import "./System.sol";
import "../lib/Predicate.sol";

/**
@title ChildERC721Predicate
@author Polygon Technology (@QEDK, @wschwab)
@notice Enables ERC721 token deposits and withdrawals across an arbitrary root chain and child chain
*/
// solhint-disable reason-string
contract ChildERC721Predicate is IChildERC721Predicate, Initializable, System {
contract ChildERC721Predicate is IChildERC721Predicate, Predicate, System {
/// @custom:security write-protection="onlySystemCall()"
IStateSender public l2StateSender;
/// @custom:security write-protection="onlySystemCall()"
Expand All @@ -24,11 +25,6 @@ contract ChildERC721Predicate is IChildERC721Predicate, Initializable, System {
address public rootERC721Predicate;
/// @custom:security write-protection="onlySystemCall()"
address public childTokenTemplate;
bytes32 public constant DEPOSIT_SIG = keccak256("DEPOSIT");
bytes32 public constant DEPOSIT_BATCH_SIG = keccak256("DEPOSIT_BATCH");
bytes32 public constant WITHDRAW_SIG = keccak256("WITHDRAW");
bytes32 public constant WITHDRAW_BATCH_SIG = keccak256("WITHDRAW_BATCH");
bytes32 public constant MAP_TOKEN_SIG = keccak256("MAP_TOKEN");

mapping(address => address) public rootTokenToChildToken;

Expand Down Expand Up @@ -169,6 +165,7 @@ contract ChildERC721Predicate is IChildERC721Predicate, Initializable, System {
newChildTokenTemplate != address(0),
"ChildERC721Predicate: BAD_INITIALIZATION"
);
predicateInit();
l2StateSender = IStateSender(newL2StateSender);
stateReceiver = newStateReceiver;
rootERC721Predicate = newRootERC721Predicate;
Expand Down
30 changes: 18 additions & 12 deletions contracts/blade/RootMintableERC1155Predicate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,33 @@ import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import "@openzeppelin/contracts/proxy/Clones.sol";
import "../interfaces/blade/IRootMintableERC1155Predicate.sol";
import "../interfaces/IStateSender.sol";
import "../lib/Predicate.sol";

// solhint-disable reason-string
contract RootMintableERC1155Predicate is Initializable, ERC1155Holder, IRootMintableERC1155Predicate {
contract RootMintableERC1155Predicate is Predicate, ERC1155Holder, IRootMintableERC1155Predicate {
IStateSender public l2StateSender;
address public stateReceiver;
address public childERC1155Predicate;
address public childTokenTemplate;
bytes32 public constant DEPOSIT_SIG = keccak256("DEPOSIT");
bytes32 public constant DEPOSIT_BATCH_SIG = keccak256("DEPOSIT_BATCH");
bytes32 public constant WITHDRAW_SIG = keccak256("WITHDRAW");
bytes32 public constant WITHDRAW_BATCH_SIG = keccak256("WITHDRAW_BATCH");
bytes32 public constant MAP_TOKEN_SIG = keccak256("MAP_TOKEN");
mapping(address => address) public rootTokenToChildToken;

/**
* @notice Initialization function for RootMintableERC1155Predicate
* @param newL2StateSender Address of L2StateSender to send deposit information to
* @param newStateReceiver Address of StateReceiver to receive withdrawal information from
* @param newChildERC1155Predicate Address of child ERC1155 predicate to communicate with
* @param newChildTokenTemplate Address of child token template to calculate child token addresses
* @param owner Address of the owner of the contract
* @dev Can only be called once.
*/
function initialize(
address newL2StateSender,
address newStateReceiver,
address newChildERC1155Predicate,
address newChildTokenTemplate
address newChildTokenTemplate,
address owner
) external initializer {
_initialize(newL2StateSender, newStateReceiver, newChildERC1155Predicate, newChildTokenTemplate);
_initialize(newL2StateSender, newStateReceiver, newChildERC1155Predicate, newChildTokenTemplate, owner);
}

/**
Expand All @@ -43,9 +42,13 @@ contract RootMintableERC1155Predicate is Initializable, ERC1155Holder, IRootMint
*/
function onStateReceive(uint256 /* id */, address sender, bytes calldata data) external {
require(msg.sender == stateReceiver, "RootMintableERC1155Predicate: ONLY_STATE_RECEIVER");
require(sender == childERC1155Predicate, "RootMintableERC1155Predicate: ONLY_CHILD_PREDICATE");
require(
sender == childERC1155Predicate || trustedRelayers[sender],
"RootMintableERC1155Predicate: ONLY_CHILD_PREDICATE_OR_TRUSTED_RELAYER"
);

if (bytes32(data[:32]) == WITHDRAW_SIG) {
bytes32 sig = bytes32(data[:32]);
if (sig == WITHDRAW_SIG || sig == ROLLBACK_SIG) {
_beforeTokenWithdraw();
_withdraw(data[32:]);
_afterTokenWithdraw();
Expand Down Expand Up @@ -124,15 +127,18 @@ contract RootMintableERC1155Predicate is Initializable, ERC1155Holder, IRootMint
address newL2StateSender,
address newStateReceiver,
address newChildERC1155Predicate,
address newChildTokenTemplate
address newChildTokenTemplate,
address owner
) internal {
require(
newL2StateSender != address(0) &&
newStateReceiver != address(0) &&
newChildERC1155Predicate != address(0) &&
newChildTokenTemplate != address(0),
newChildTokenTemplate != address(0) &&
owner != address(0),
"RootMintableERC1155Predicate: BAD_INITIALIZATION"
);
predicateInit(owner);
l2StateSender = IStateSender(newL2StateSender);
stateReceiver = newStateReceiver;
childERC1155Predicate = newChildERC1155Predicate;
Expand Down
2 changes: 1 addition & 1 deletion contracts/blade/RootMintableERC1155PredicateAccessList.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ contract RootMintableERC1155PredicateAccessList is AccessList, RootMintableERC11
bool newUseBlockList,
address newOwner
) public virtual onlySystemCall initializer {
_initialize(newL2StateSender, newStateReceiver, newChildERC1155Predicate, newChildTokenTemplate);
_initialize(newL2StateSender, newStateReceiver, newChildERC1155Predicate, newChildTokenTemplate, newOwner);
_initializeAccessList(newUseAllowList, newUseBlockList);
_transferOwnership(newOwner);
}
Expand Down
28 changes: 18 additions & 10 deletions contracts/blade/RootMintableERC20Predicate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import "@openzeppelin/contracts/proxy/Clones.sol";
import "../interfaces/blade/IRootMintableERC20Predicate.sol";
import "../interfaces/IStateSender.sol";
import "./System.sol";
import "../lib/Predicate.sol";

// solhint-disable reason-string
contract RootMintableERC20Predicate is IRootMintableERC20Predicate, Initializable, System {
contract RootMintableERC20Predicate is IRootMintableERC20Predicate, Predicate, System {
using SafeERC20 for IERC20Metadata;

/// @custom:security write-protection="onlySystemCall()"
Expand All @@ -21,9 +22,6 @@ contract RootMintableERC20Predicate is IRootMintableERC20Predicate, Initializabl
/// @custom:security write-protection="onlySystemCall()"
address public childTokenTemplate;

bytes32 public constant DEPOSIT_SIG = keccak256("DEPOSIT");
bytes32 public constant WITHDRAW_SIG = keccak256("WITHDRAW");
bytes32 public constant MAP_TOKEN_SIG = keccak256("MAP_TOKEN");
mapping(address => address) public rootTokenToChildToken;

/**
Expand All @@ -32,15 +30,17 @@ contract RootMintableERC20Predicate is IRootMintableERC20Predicate, Initializabl
* @param newStateReceiver Address of StateReceiver to receive deposit information from
* @param newChildERC20Predicate Address of child ERC20 predicate to communicate with
* @param newChildTokenTemplate Address of child token implementation to deploy clones of
* @param owner Address of the owner of the contract
* @dev Can only be called once.
*/
function initialize(
address newL2StateSender,
address newStateReceiver,
address newChildERC20Predicate,
address newChildTokenTemplate
address newChildTokenTemplate,
address owner
) public virtual onlySystemCall initializer {
_initialize(newL2StateSender, newStateReceiver, newChildERC20Predicate, newChildTokenTemplate);
_initialize(newL2StateSender, newStateReceiver, newChildERC20Predicate, newChildTokenTemplate, owner);
}

/**
Expand All @@ -51,9 +51,13 @@ contract RootMintableERC20Predicate is IRootMintableERC20Predicate, Initializabl
*/
function onStateReceive(uint256 /* id */, address sender, bytes calldata data) external {
require(msg.sender == stateReceiver, "RootMintableERC20Predicate: ONLY_STATE_RECEIVER");
require(sender == childERC20Predicate, "RootMintableERC20Predicate: ONLY_CHILD_PREDICATE");
require(
sender == childERC20Predicate || trustedRelayers[sender],
"RootMintableERC20Predicate: ONLY_CHILD_PREDICATE_OR_TRUSTED_RELAYER"
);

if (bytes32(data[:32]) == WITHDRAW_SIG) {
bytes32 sig = bytes32(data[:32]);
if (sig == WITHDRAW_SIG || sig == ROLLBACK_SIG) {
_beforeTokenWithdraw();
_withdraw(data[32:]);
_afterTokenWithdraw();
Expand Down Expand Up @@ -109,21 +113,25 @@ contract RootMintableERC20Predicate is IRootMintableERC20Predicate, Initializabl
* @param newStateReceiver Address of StateReceiver to receive deposit information from
* @param newChildERC20Predicate Address of root ERC20 predicate to communicate with
* @param newChildTokenTemplate Address of child token implementation to deploy clones of
* @param owner Address of the owner of the contract
* @dev Can be called multiple times.
*/
function _initialize(
address newL2StateSender,
address newStateReceiver,
address newChildERC20Predicate,
address newChildTokenTemplate
address newChildTokenTemplate,
address owner
) internal {
require(
newL2StateSender != address(0) &&
newStateReceiver != address(0) &&
newChildERC20Predicate != address(0) &&
newChildTokenTemplate != address(0),
newChildTokenTemplate != address(0) &&
owner != address(0),
"RootMintableERC20Predicate: BAD_INITIALIZATION"
);
predicateInit(owner);
l2StateSender = IStateSender(newL2StateSender);
stateReceiver = newStateReceiver;
childERC20Predicate = newChildERC20Predicate;
Expand Down
2 changes: 1 addition & 1 deletion contracts/blade/RootMintableERC20PredicateAccessList.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ contract RootMintableERC20PredicateAccessList is AccessList, RootMintableERC20Pr
bool newUseBlockList,
address newOwner
) public virtual onlySystemCall initializer {
_initialize(newL2StateSender, newStateReceiver, newChildERC20Predicate, newChildTokenTemplate);
_initialize(newL2StateSender, newStateReceiver, newChildERC20Predicate, newChildTokenTemplate, newOwner);
_initializeAccessList(newUseAllowList, newUseBlockList);
_transferOwnership(newOwner);
}
Expand Down
29 changes: 17 additions & 12 deletions contracts/blade/RootMintableERC721Predicate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,14 @@ import "@openzeppelin/contracts/proxy/Clones.sol";
import "../interfaces/blade/IRootMintableERC721Predicate.sol";
import "../interfaces/IStateSender.sol";
import "./System.sol";
import "../lib/Predicate.sol";

// solhint-disable reason-string
contract RootMintableERC721Predicate is Initializable, ERC721Holder, System, IRootMintableERC721Predicate {
contract RootMintableERC721Predicate is Predicate, ERC721Holder, System, IRootMintableERC721Predicate {
IStateSender public l2StateSender;
address public stateReceiver;
address public childERC721Predicate;
address public childTokenTemplate;
bytes32 public constant DEPOSIT_SIG = keccak256("DEPOSIT");
bytes32 public constant DEPOSIT_BATCH_SIG = keccak256("DEPOSIT_BATCH");
bytes32 public constant WITHDRAW_SIG = keccak256("WITHDRAW");
bytes32 public constant WITHDRAW_BATCH_SIG = keccak256("WITHDRAW_BATCH");
bytes32 public constant MAP_TOKEN_SIG = keccak256("MAP_TOKEN");
mapping(address => address) public rootTokenToChildToken;

/**
Expand All @@ -27,15 +23,17 @@ contract RootMintableERC721Predicate is Initializable, ERC721Holder, System, IRo
* @param newStateReceiver Address of StateReceiver to receive withdrawal information from
* @param newChildERC721Predicate Address of child ERC721 predicate to communicate with
* @param newChildTokenTemplate Address of child token template to calculate child token addresses
* @param owner Address of the owner of the contract
* @dev Can only be called once.
*/
function initialize(
address newL2StateSender,
address newStateReceiver,
address newChildERC721Predicate,
address newChildTokenTemplate
address newChildTokenTemplate,
address owner
) external virtual onlySystemCall initializer {
_initialize(newL2StateSender, newStateReceiver, newChildERC721Predicate, newChildTokenTemplate);
_initialize(newL2StateSender, newStateReceiver, newChildERC721Predicate, newChildTokenTemplate, owner);
}

/**
Expand All @@ -45,9 +43,13 @@ contract RootMintableERC721Predicate is Initializable, ERC721Holder, System, IRo
*/
function onStateReceive(uint256 /* id */, address sender, bytes calldata data) external {
require(msg.sender == stateReceiver, "RootMintableERC721Predicate: ONLY_STATE_RECEIVER");
require(sender == childERC721Predicate, "RootMintableERC721Predicate: ONLY_CHILD_PREDICATE");
require(
sender == childERC721Predicate || trustedRelayers[sender],
"RootMintableERC721Predicate: ONLY_CHILD_PREDICATE_OR_TRUSTED_RELAYER"
);

if (bytes32(data[:32]) == WITHDRAW_SIG) {
bytes32 sig = bytes32(data[:32]);
if (sig == WITHDRAW_SIG || sig == ROLLBACK_SIG) {
_beforeTokenWithdraw();
_withdraw(data[32:]);
_afterTokenWithdraw();
Expand Down Expand Up @@ -128,15 +130,18 @@ contract RootMintableERC721Predicate is Initializable, ERC721Holder, System, IRo
address newL2StateSender,
address newStateReceiver,
address newChildERC721Predicate,
address newChildTokenTemplate
address newChildTokenTemplate,
address owner
) internal {
require(
newL2StateSender != address(0) &&
newStateReceiver != address(0) &&
newChildERC721Predicate != address(0) &&
newChildTokenTemplate != address(0),
newChildTokenTemplate != address(0) &&
owner != address(0),
"RootMintableERC721Predicate: BAD_INITIALIZATION"
);
predicateInit(owner);
l2StateSender = IStateSender(newL2StateSender);
stateReceiver = newStateReceiver;
childERC721Predicate = newChildERC721Predicate;
Expand Down
2 changes: 1 addition & 1 deletion contracts/blade/RootMintableERC721PredicateAccessList.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ contract RootMintableERC721PredicateAccessList is AccessList, RootMintableERC721
bool newUseBlockList,
address newOwner
) public virtual onlySystemCall initializer {
_initialize(newL2StateSender, newStateReceiver, newChildERC721Predicate, newChildTokenTemplate);
_initialize(newL2StateSender, newStateReceiver, newChildERC721Predicate, newChildTokenTemplate, newOwner);
_initializeAccessList(newUseAllowList, newUseBlockList);
_transferOwnership(newOwner);
}
Expand Down
Loading
Loading