Skip to content

Commit

Permalink
evm: add custom initialization data
Browse files Browse the repository at this point in the history
  • Loading branch information
gator-boi committed Apr 12, 2024
1 parent 639a935 commit ae39d6c
Show file tree
Hide file tree
Showing 10 changed files with 193 additions and 55 deletions.
2 changes: 1 addition & 1 deletion evm/env/localnet/avalanche.env
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export RELEASE_FEE_RECIPIENT_ADDRESS=0xACa94ef8bD5ffEE41947b4585a84BdA5a3d3DA6E


### Token Router Proxy (evm address)
export RELEASE_TOKEN_ROUTER_ADDRESS=0xE204b657F73C61970104c461456f01fcad66813a
export RELEASE_TOKEN_ROUTER_ADDRESS=0x2adf8B30d4Dd24a05Ccd9aFbDc06A5b49C9c758d


############################### Matching Engine ###############################
Expand Down
6 changes: 1 addition & 5 deletions evm/forge/scripts/DeployMatchingEngineContract.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,9 @@ contract DeployMatchingEngineContracts is CheckWormholeContracts, Script {
MatchingEngine proxy =
MatchingEngine(address(new ERC1967Proxy(address(implementation), "")));

proxy.initialize();
proxy.initialize(abi.encodePacked(_ownerAssistantAddress, _feeRecipientAddress));

console2.log("Deployed MatchingEngine (chain=%s): %s", _chainId, address(proxy));

// Set the owner assistant and fee recipient.
proxy.updateOwnerAssistant(_ownerAssistantAddress);
proxy.updateFeeRecipient(_feeRecipientAddress);
}

function run() public {
Expand Down
5 changes: 1 addition & 4 deletions evm/forge/scripts/DeployTokenRouterContracts.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,9 @@ contract DeployTokenRouterContracts is CheckWormholeContracts, Script {
TokenRouter proxy =
TokenRouter(address(new ERC1967Proxy(address(implementation), "")));

proxy.initialize();
proxy.initialize(abi.encodePacked(_ownerAssistantAddress));

console2.log("Deployed TokenRouter (chain=%s): %s", _chainId, address(proxy));

// Set the owner assistant.
proxy.updateOwnerAssistant(_ownerAssistantAddress);
}

function run() public {
Expand Down
97 changes: 84 additions & 13 deletions evm/forge/tests/MatchingEngine.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ contract MatchingEngineTest is Test {
MatchingEngine proxy =
MatchingEngine(address(new ERC1967Proxy(address(implementation), "")));

proxy.initialize();
proxy.initialize(abi.encodePacked(makeAddr("ownerAssistant"), FEE_RECIPIENT));

return IMatchingEngine(address(proxy));
}
Expand All @@ -142,10 +142,6 @@ contract MatchingEngineTest is Test {
ETH_CHAIN, RouterEndpoint({router: ETH_ROUTER, mintRecipient: ETH_ROUTER}), ETH_DOMAIN
);

// Change default state.
engine.updateOwnerAssistant(makeAddr("ownerAssistant"));
engine.updateFeeRecipient(FEE_RECIPIENT);

vm.stopPrank();

wormholeSimulator = new SigningWormholeSimulator(wormhole, TESTING_SIGNER);
Expand Down Expand Up @@ -182,11 +178,61 @@ contract MatchingEngineTest is Test {
vm.expectRevert(
abi.encodeWithSignature("ErrCallerNotDeployer(address,address)", owner, notDeployer)
);
proxy.initialize();
proxy.initialize(abi.encodePacked(makeAddr("ownerAssistant"), FEE_RECIPIENT));
}

function testCannotInitializeWithValue() public {
vm.startPrank(makeAddr("owner"));
function testCannotInitializeZeroInitData() public {
address owner = makeAddr("owner");

vm.startPrank(owner);
MatchingEngine implementation = new MatchingEngine(
USDC_ADDRESS,
address(wormhole),
CIRCLE_BRIDGE.fromUniversalAddress(),
USER_PENALTY_REWARD_BPS,
INITIAL_PENALTY_BPS,
AUCTION_DURATION,
AUCTION_GRACE_PERIOD,
AUCTION_PENALTY_BLOCKS
);

MatchingEngine proxy =
MatchingEngine(address(new ERC1967Proxy(address(implementation), "")));

vm.expectRevert(
abi.encodeWithSignature("InvalidInitDataLength(uint256,uint256)", 0, 40)
);
proxy.initialize(new bytes(0));
}

function testCannotInitializeInvalidInitDataLength() public {
address owner = makeAddr("owner");

vm.startPrank(owner);
MatchingEngine implementation = new MatchingEngine(
USDC_ADDRESS,
address(wormhole),
CIRCLE_BRIDGE.fromUniversalAddress(),
USER_PENALTY_REWARD_BPS,
INITIAL_PENALTY_BPS,
AUCTION_DURATION,
AUCTION_GRACE_PERIOD,
AUCTION_PENALTY_BLOCKS
);

MatchingEngine proxy =
MatchingEngine(address(new ERC1967Proxy(address(implementation), "")));

vm.expectRevert(
abi.encodeWithSignature("InvalidInitDataLength(uint256,uint256)", 41, 40)
);
proxy.initialize(abi.encodePacked(makeAddr("ownerAssistant"), FEE_RECIPIENT, uint8(69)));
}

function testCannotInitializeInvalidFeeRecipientAddress() public {
address owner = makeAddr("owner");

vm.startPrank(owner);
MatchingEngine implementation = new MatchingEngine(
USDC_ADDRESS,
address(wormhole),
Expand All @@ -201,9 +247,34 @@ contract MatchingEngineTest is Test {
MatchingEngine proxy =
MatchingEngine(address(new ERC1967Proxy(address(implementation), "")));

vm.expectRevert(abi.encodeWithSignature("ErrNonzeroMsgValue()"));
vm.deal(makeAddr("owner"), 42069);
proxy.initialize{value: 42069}();
vm.expectRevert(
abi.encodeWithSignature("InvalidAddress()")
);
proxy.initialize(abi.encodePacked(makeAddr("ownerAssistant"), address(0)));
}

function testCannotInitializeInvalidOwnerAssistantAddress() public {
address owner = makeAddr("owner");

vm.startPrank(owner);
MatchingEngine implementation = new MatchingEngine(
USDC_ADDRESS,
address(wormhole),
CIRCLE_BRIDGE.fromUniversalAddress(),
USER_PENALTY_REWARD_BPS,
INITIAL_PENALTY_BPS,
AUCTION_DURATION,
AUCTION_GRACE_PERIOD,
AUCTION_PENALTY_BLOCKS
);

MatchingEngine proxy =
MatchingEngine(address(new ERC1967Proxy(address(implementation), "")));

vm.expectRevert(
abi.encodeWithSignature("InvalidAddress()")
);
proxy.initialize(abi.encodePacked(address(0), FEE_RECIPIENT));
}

function testUpgradeContract() public {
Expand Down Expand Up @@ -1654,7 +1725,7 @@ contract MatchingEngineTest is Test {

TokenRouter proxy = TokenRouter(address(new ERC1967Proxy(address(implementation), "")));

proxy.initialize();
proxy.initialize(abi.encodePacked(makeAddr("ownerAssistant")));

vm.prank(makeAddr("owner"));
engine.addRouterEndpoint(
Expand Down Expand Up @@ -2042,7 +2113,7 @@ contract MatchingEngineTest is Test {
MatchingEngine proxy =
MatchingEngine(address(new ERC1967Proxy(address(implementation), "")));

proxy.initialize();
proxy.initialize(abi.encodePacked(makeAddr("ownerAssistant"), FEE_RECIPIENT));

engine = IMatchingEngine(address(proxy));
}
Expand Down
62 changes: 52 additions & 10 deletions evm/forge/tests/TokenRouter.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ contract TokenRouterTest is Test {

TokenRouter proxy = TokenRouter(address(new ERC1967Proxy(address(implementation), "")));

proxy.initialize();
proxy.initialize(abi.encodePacked(makeAddr("ownerAssistant")));

return ITokenRouter(address(proxy));
}
Expand All @@ -112,9 +112,6 @@ contract TokenRouterTest is Test {
ARB_CHAIN, Endpoint({router: ARB_ROUTER, mintRecipient: ARB_ROUTER}), ARB_DOMAIN
);

// Update the owner assistant, `owner` is the default.
router.updateOwnerAssistant(makeAddr("ownerAssistant"));

// Set the fast transfer parameters for Arbitrum.
router.updateFastTransferParameters(
FastTransferParameters({
Expand Down Expand Up @@ -157,11 +154,13 @@ contract TokenRouterTest is Test {
vm.expectRevert(
abi.encodeWithSignature("ErrCallerNotDeployer(address,address)", owner, notDeployer)
);
proxy.initialize();
proxy.initialize(abi.encodePacked(makeAddr("ownerAssistant")));
}

function testCannotInitializeWithValue() public {
vm.startPrank(makeAddr("owner"));
function testCannotInitializeZeroInitData() public {
address owner = makeAddr("owner");

vm.startPrank(owner);
TokenRouter implementation = new TokenRouter(
USDC_ADDRESS,
address(wormhole),
Expand All @@ -173,9 +172,52 @@ contract TokenRouterTest is Test {
);
TokenRouter proxy = TokenRouter(address(new ERC1967Proxy(address(implementation), "")));

vm.expectRevert(abi.encodeWithSignature("ErrNonzeroMsgValue()"));
vm.deal(makeAddr("owner"), 42069);
proxy.initialize{value: 42069}();
vm.expectRevert(
abi.encodeWithSignature("InvalidInitDataLength(uint256,uint256)", 0, 20)
);
proxy.initialize(new bytes(0));
}

function testCannotInitializeInvalidInitDataLength() public {
address owner = makeAddr("owner");

vm.startPrank(owner);
TokenRouter implementation = new TokenRouter(
USDC_ADDRESS,
address(wormhole),
CIRCLE_BRIDGE,
matchingEngineChain,
matchingEngineAddress,
matchingEngineMintRecipient,
matchingEngineDomain
);
TokenRouter proxy = TokenRouter(address(new ERC1967Proxy(address(implementation), "")));

vm.expectRevert(
abi.encodeWithSignature("InvalidInitDataLength(uint256,uint256)", 40, 20)
);
proxy.initialize(abi.encodePacked(makeAddr("ownerAssistant"), makeAddr("hole")));
}

function testCannotInitializeInvalidAddress() public {
address owner = makeAddr("owner");

vm.startPrank(owner);
TokenRouter implementation = new TokenRouter(
USDC_ADDRESS,
address(wormhole),
CIRCLE_BRIDGE,
matchingEngineChain,
matchingEngineAddress,
matchingEngineMintRecipient,
matchingEngineDomain
);
TokenRouter proxy = TokenRouter(address(new ERC1967Proxy(address(implementation), "")));

vm.expectRevert(
abi.encodeWithSignature("InvalidAddress()")
);
proxy.initialize(abi.encodePacked(address(0)));
}

function testUpgradeContract() public {
Expand Down
31 changes: 23 additions & 8 deletions evm/src/MatchingEngine/MatchingEngine.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {State} from "./assets/State.sol";
import "./assets/Errors.sol";

contract MatchingEngine is MatchingEngineFastOrders, MatchingEngineAdmin {
error AlreadyInitialized();
using BytesParsing for bytes;

constructor(
address cctpToken_,
Expand All @@ -37,21 +37,25 @@ contract MatchingEngine is MatchingEngineFastOrders, MatchingEngineAdmin {
)
{}

function __MatchingEngine_init() internal onlyInitializing {
function __MatchingEngine_init(bytes memory initData) internal onlyInitializing {
if (msg.sender != _deployer) {
revert ErrCallerNotDeployer(_deployer, msg.sender);
}
if (msg.value != 0) {
revert ErrNonzeroMsgValue();

// Decode the init data, verify that the addresses are not the zero address.
(address ownerAssistant, address feeRecipient) = _parseInitData(initData);

if (ownerAssistant == address(0) || feeRecipient == address(0)) {
revert InvalidAddress();
}

getOwnerState().owner = msg.sender;
getOwnerAssistantState().ownerAssistant = msg.sender;
getFeeRecipientState().recipient = msg.sender;
getOwnerAssistantState().ownerAssistant = ownerAssistant;
getFeeRecipientState().recipient = feeRecipient;
}

function _initialize() internal override {
__MatchingEngine_init();
function _initialize(bytes memory initData) internal override {
__MatchingEngine_init(initData);
}

function _checkImmutables() internal view override {
Expand All @@ -64,4 +68,15 @@ contract MatchingEngine is MatchingEngineFastOrders, MatchingEngineAdmin {
}

function _migrate() internal override {}

function _parseInitData(bytes memory initData) internal pure returns (address ownerAssistant, address feeRecipient) {
uint256 offset = 0;

(ownerAssistant, offset) = initData.asAddressUnchecked(offset);
(feeRecipient, offset) = initData.asAddressUnchecked(offset);

if (initData.length != offset) {
revert InvalidInitDataLength(initData.length, offset);
}
}
}
2 changes: 1 addition & 1 deletion evm/src/MatchingEngine/assets/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ error ErrDeadlineExceeded();

error ErrCallerNotDeployer(address deployer, address caller);

error ErrNonzeroMsgValue();
error InvalidInitDataLength(uint256 actual, uint256 expected);
28 changes: 21 additions & 7 deletions evm/src/TokenRouter/TokenRouter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {State} from "./assets/State.sol";
import "./assets/Errors.sol";

contract TokenRouter is TokenRouterAdmin, PlaceMarketOrder, RedeemFill {
error AlreadyInitialized();
using BytesParsing for bytes;

constructor(
address token_,
Expand All @@ -36,20 +36,24 @@ contract TokenRouter is TokenRouterAdmin, PlaceMarketOrder, RedeemFill {
)
{}

function __TokenRouter_init() internal onlyInitializing {
function __TokenRouter_init(bytes memory initData) internal onlyInitializing {
if (msg.sender != _deployer) {
revert ErrCallerNotDeployer(_deployer, msg.sender);
}
if (msg.value != 0) {
revert ErrNonzeroMsgValue();

// Decode the init data, verify that the address is not the zero address.
(address ownerAssistant) = _parseInitData(initData);

if (ownerAssistant == address(0)) {
revert InvalidAddress();
}

getOwnerState().owner = msg.sender;
getOwnerAssistantState().ownerAssistant = msg.sender;
getOwnerAssistantState().ownerAssistant = ownerAssistant;
}

function _initialize() internal override {
__TokenRouter_init();
function _initialize(bytes memory initData) internal override {
__TokenRouter_init(initData);
}

function _checkImmutables() internal view override {
Expand All @@ -61,4 +65,14 @@ contract TokenRouter is TokenRouterAdmin, PlaceMarketOrder, RedeemFill {
}

function _migrate() internal override {}

function _parseInitData(bytes memory initData) internal pure returns (address ownerAssistant) {
uint256 offset = 0;

(ownerAssistant, offset) = initData.asAddressUnchecked(offset);

if (initData.length != offset) {
revert InvalidInitDataLength(initData.length, offset);
}
}
}
2 changes: 1 addition & 1 deletion evm/src/TokenRouter/assets/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ error ErrInvalidMaxFee(uint64 maxFee, uint64 minimumReuiredFee);

error ErrCallerNotDeployer(address deployer, address caller);

error ErrNonzeroMsgValue();
error InvalidInitDataLength(uint256 actual, uint256 expected);
Loading

0 comments on commit ae39d6c

Please sign in to comment.