diff --git a/script/10_DeployExocoreGatewayOnly.s.sol b/script/10_DeployExocoreGatewayOnly.s.sol index f976f126..941af0fe 100644 --- a/script/10_DeployExocoreGatewayOnly.s.sol +++ b/script/10_DeployExocoreGatewayOnly.s.sol @@ -10,7 +10,6 @@ import "forge-std/Script.sol"; import {BaseScript} from "./BaseScript.sol"; contract DeployExocoreGatewayOnly is BaseScript { - function setUp() public virtual override { // load keys super.setUp(); @@ -48,14 +47,15 @@ contract DeployExocoreGatewayOnly is BaseScript { string memory exocoreContracts = "exocoreContracts"; vm.serializeAddress(exocoreContracts, "lzEndpoint", address(exocoreLzEndpoint)); vm.serializeAddress(exocoreContracts, "exocoreGatewayLogic", address(exocoreGatewayLogic)); - string memory exocoreContractsOutput = - vm.serializeAddress(exocoreContracts, "exocoreGateway", address(exocoreGateway)); + string memory exocoreContractsOutput = vm.serializeAddress( + exocoreContracts, + "exocoreGateway", + address(exocoreGateway) + ); string memory deployedContracts = "deployedContracts"; - string memory finalJson = - vm.serializeString(deployedContracts, "exocore", exocoreContractsOutput); + string memory finalJson = vm.serializeString(deployedContracts, "exocore", exocoreContractsOutput); vm.writeJson(finalJson, "script/deployedExocoreGatewayOnly.json"); - } -} \ No newline at end of file +} diff --git a/script/11_SetPeers.s.sol b/script/11_SetPeers.s.sol index c8dac6e5..41e914cf 100644 --- a/script/11_SetPeers.s.sol +++ b/script/11_SetPeers.s.sol @@ -50,8 +50,7 @@ contract SetPeersAndUpgrade is BaseScript { uint256 i = 0; uint256 tries = 5; bool success; - while(i < tries) { - + while (i < tries) { vm.selectFork(exocore); success = gateway.peers(clientChainId) == bootstrapAddr.toBytes32(); @@ -90,8 +89,8 @@ contract SetPeersAndUpgrade is BaseScript { console.log( "source .env && cast send --rpc-url $EXOCORE_TESETNET_RPC", exocoreGatewayAddr, - "\"markBootstrapOnAllChains()\"", + '"markBootstrapOnAllChains()"', "--private-key $TEST_ACCOUNT_THREE_PRIVATE_KEY" ); } -} \ No newline at end of file +} diff --git a/script/12_RedeployClientChainGateway.s.sol b/script/12_RedeployClientChainGateway.s.sol index fa04e4ec..e2d9fadb 100644 --- a/script/12_RedeployClientChainGateway.s.sol +++ b/script/12_RedeployClientChainGateway.s.sol @@ -28,25 +28,17 @@ contract RedeployClientChainGateway is BaseScript { stdJson.readAddress(prerequisiteContracts, ".clientChain.lzEndpoint") ); require(address(clientChainLzEndpoint) != address(0), "client chain l0 endpoint should not be empty"); - beaconOracle = EigenLayerBeaconOracle( - stdJson.readAddress(prerequisiteContracts, ".clientChain.beaconOracle") - ); + beaconOracle = EigenLayerBeaconOracle(stdJson.readAddress(prerequisiteContracts, ".clientChain.beaconOracle")); require(address(beaconOracle) != address(0), "beacon oracle should not be empty"); - vaultBeacon = UpgradeableBeacon( - stdJson.readAddress(prerequisiteContracts, ".clientChain.vaultBeacon") - ); + vaultBeacon = UpgradeableBeacon(stdJson.readAddress(prerequisiteContracts, ".clientChain.vaultBeacon")); require(address(vaultBeacon) != address(0), "vault beacon should not be empty"); - capsuleBeacon = UpgradeableBeacon( - stdJson.readAddress(prerequisiteContracts, ".clientChain.capsuleBeacon") - ); + capsuleBeacon = UpgradeableBeacon(stdJson.readAddress(prerequisiteContracts, ".clientChain.capsuleBeacon")); require(address(capsuleBeacon) != address(0), "capsule beacon should not be empty"); beaconProxyBytecode = BeaconProxyBytecode( stdJson.readAddress(prerequisiteContracts, ".clientChain.beaconProxyBytecode") ); require(address(beaconProxyBytecode) != address(0), "beacon proxy bytecode should not be empty"); - bootstrap = Bootstrap( - stdJson.readAddress(prerequisiteContracts, ".clientChain.bootstrap") - ); + bootstrap = Bootstrap(stdJson.readAddress(prerequisiteContracts, ".clientChain.bootstrap")); require(address(bootstrap) != address(0), "bootstrap should not be empty"); clientChain = vm.createSelectFork(clientChainRPCURL); } @@ -69,20 +61,19 @@ contract RedeployClientChainGateway is BaseScript { exocoreValidatorSet.addr, emptyList ); - bootstrap.setClientChainGatewayLogic( - address(clientGatewayLogic), - initialization - ); + bootstrap.setClientChainGatewayLogic(address(clientGatewayLogic), initialization); vm.stopBroadcast(); string memory clientChainContracts = "clientChainContracts"; - string memory clientChainContractsOutput = - vm.serializeAddress(clientChainContracts, "clientGatewayLogic", address(clientGatewayLogic)); + string memory clientChainContractsOutput = vm.serializeAddress( + clientChainContracts, + "clientGatewayLogic", + address(clientGatewayLogic) + ); string memory deployedContracts = "deployedContracts"; - string memory finalJson = - vm.serializeString(deployedContracts, "clientChain", clientChainContractsOutput); + string memory finalJson = vm.serializeString(deployedContracts, "clientChain", clientChainContractsOutput); vm.writeJson(finalJson, "script/redeployClientChainGateway.json"); } -} \ No newline at end of file +} diff --git a/script/1_Prerequisities.s.sol b/script/1_Prerequisities.s.sol index 3d340b59..3a088a03 100644 --- a/script/1_Prerequisities.s.sol +++ b/script/1_Prerequisities.s.sol @@ -56,8 +56,11 @@ contract PrerequisitiesScript is BaseScript { string memory exocoreContracts = "exocoreContracts"; vm.serializeAddress(clientChainContracts, "lzEndpoint", address(clientChainLzEndpoint)); vm.serializeAddress(clientChainContracts, "beaconOracle", address(beaconOracle)); - string memory clientChainContractsOutput = - vm.serializeAddress(clientChainContracts, "erc20Token", address(restakeToken)); + string memory clientChainContractsOutput = vm.serializeAddress( + clientChainContracts, + "erc20Token", + address(restakeToken) + ); if (useExocorePrecompileMock) { vm.serializeAddress(exocoreContracts, "depositPrecompileMock", depositMock); @@ -66,8 +69,11 @@ contract PrerequisitiesScript is BaseScript { vm.serializeAddress(exocoreContracts, "claimRewardPrecompileMock", claimRewardMock); } - string memory exocoreContractsOutput = - vm.serializeAddress(exocoreContracts, "lzEndpoint", address(exocoreLzEndpoint)); + string memory exocoreContractsOutput = vm.serializeAddress( + exocoreContracts, + "lzEndpoint", + address(exocoreLzEndpoint) + ); vm.serializeString(deployedContracts, "clientChain", clientChainContractsOutput); string memory finalJson = vm.serializeString(deployedContracts, "exocore", exocoreContractsOutput); diff --git a/script/2_DeployBoth.s.sol b/script/2_DeployBoth.s.sol index 8f7ff6de..e2c9819d 100644 --- a/script/2_DeployBoth.s.sol +++ b/script/2_DeployBoth.s.sol @@ -58,7 +58,7 @@ contract DeployScript is BaseScript { // deploy beacon chain oracle beaconOracle = _deployBeaconOracle(); - + /// deploy vault implementation contract and capsule implementation contract /// that has logics called by proxy vaultImplementation = new Vault(); @@ -113,7 +113,11 @@ contract DeployScript is BaseScript { if (useExocorePrecompileMock) { ExocoreGatewayMock exocoreGatewayLogic = new ExocoreGatewayMock( - address(exocoreLzEndpoint), depositMock, withdrawMock, delegationMock, claimRewardMock + address(exocoreLzEndpoint), + depositMock, + withdrawMock, + delegationMock, + claimRewardMock ); exocoreGateway = ExocoreGateway( payable( @@ -122,7 +126,8 @@ contract DeployScript is BaseScript { address(exocoreGatewayLogic), address(exocoreProxyAdmin), abi.encodeWithSelector( - exocoreGatewayLogic.initialize.selector, payable(exocoreValidatorSet.addr) + exocoreGatewayLogic.initialize.selector, + payable(exocoreValidatorSet.addr) ) ) ) @@ -137,7 +142,8 @@ contract DeployScript is BaseScript { address(exocoreGatewayLogic), address(exocoreProxyAdmin), abi.encodeWithSelector( - exocoreGatewayLogic.initialize.selector, payable(exocoreValidatorSet.addr) + exocoreGatewayLogic.initialize.selector, + payable(exocoreValidatorSet.addr) ) ) ) @@ -158,8 +164,11 @@ contract DeployScript is BaseScript { vm.serializeAddress(clientChainContracts, "vaultBeacon", address(vaultBeacon)); vm.serializeAddress(clientChainContracts, "capsuleBeacon", address(capsuleBeacon)); vm.serializeAddress(clientChainContracts, "beaconProxyBytecode", address(beaconProxyBytecode)); - string memory clientChainContractsOutput = - vm.serializeAddress(clientChainContracts, "proxyAdmin", address(clientChainProxyAdmin)); + string memory clientChainContractsOutput = vm.serializeAddress( + clientChainContracts, + "proxyAdmin", + address(clientChainProxyAdmin) + ); vm.serializeAddress(exocoreContracts, "lzEndpoint", address(exocoreLzEndpoint)); vm.serializeAddress(exocoreContracts, "exocoreGateway", address(exocoreGateway)); @@ -171,8 +180,11 @@ contract DeployScript is BaseScript { vm.serializeAddress(exocoreContracts, "claimRewardPrecompileMock", claimRewardMock); } - string memory exocoreContractsOutput = - vm.serializeAddress(exocoreContracts, "proxyAdmin", address(exocoreProxyAdmin)); + string memory exocoreContractsOutput = vm.serializeAddress( + exocoreContracts, + "proxyAdmin", + address(exocoreProxyAdmin) + ); vm.serializeString(deployedContracts, "clientChain", clientChainContractsOutput); string memory finalJson = vm.serializeString(deployedContracts, "exocore", exocoreContractsOutput); diff --git a/script/3_Setup.s.sol b/script/3_Setup.s.sol index a23420d9..c779da28 100644 --- a/script/3_Setup.s.sol +++ b/script/3_Setup.s.sol @@ -18,8 +18,9 @@ contract SetupScript is BaseScript { string memory deployedContracts = vm.readFile("script/deployedContracts.json"); - clientGateway = - IClientChainGateway(payable(stdJson.readAddress(deployedContracts, ".clientChain.clientChainGateway"))); + clientGateway = IClientChainGateway( + payable(stdJson.readAddress(deployedContracts, ".clientChain.clientChainGateway")) + ); require(address(clientGateway) != address(0), "clientGateway address should not be empty"); clientChainLzEndpoint = ILayerZeroEndpointV2(stdJson.readAddress(deployedContracts, ".clientChain.lzEndpoint")); @@ -53,7 +54,8 @@ contract SetupScript is BaseScript { // set the destination endpoint for corresponding destinations in endpoint mock if USE_ENDPOINT_MOCK is true if (useEndpointMock) { NonShortCircuitEndpointV2Mock(address(clientChainLzEndpoint)).setDestLzEndpoint( - address(exocoreGateway), address(exocoreLzEndpoint) + address(exocoreGateway), + address(exocoreLzEndpoint) ); } @@ -68,7 +70,8 @@ contract SetupScript is BaseScript { // set the destination endpoint for corresponding destinations in endpoint mock if USE_ENDPOINT_MOCK is true if (useEndpointMock) { NonShortCircuitEndpointV2Mock(address(exocoreLzEndpoint)).setDestLzEndpoint( - address(clientGateway), address(clientChainLzEndpoint) + address(clientGateway), + address(clientChainLzEndpoint) ); } exocoreGateway.setPeer(clientChainId, address(clientGateway).toBytes32()); diff --git a/script/4_Deposit.s.sol b/script/4_Deposit.s.sol index 2c7f0874..e233cd39 100644 --- a/script/4_Deposit.s.sol +++ b/script/4_Deposit.s.sol @@ -19,8 +19,9 @@ contract DepositScript is BaseScript { string memory deployedContracts = vm.readFile("script/deployedContracts.json"); - clientGateway = - IClientChainGateway(payable(stdJson.readAddress(deployedContracts, ".clientChain.clientChainGateway"))); + clientGateway = IClientChainGateway( + payable(stdJson.readAddress(deployedContracts, ".clientChain.clientChainGateway")) + ); require(address(clientGateway) != address(0), "clientGateway address should not be empty"); clientChainLzEndpoint = ILayerZeroEndpointV2(stdJson.readAddress(deployedContracts, ".clientChain.lzEndpoint")); @@ -80,7 +81,11 @@ contract DepositScript is BaseScript { Origin(clientChainId, address(clientGateway).toBytes32(), nonce), address(exocoreGateway), GUID.generate( - nonce, clientChainId, address(clientGateway), exocoreChainId, address(exocoreGateway).toBytes32() + nonce, + clientChainId, + address(clientGateway), + exocoreChainId, + address(exocoreGateway).toBytes32() ), msg_, bytes("") diff --git a/script/5_Withdraw.s.sol b/script/5_Withdraw.s.sol index 3b53dd71..ce44b25c 100644 --- a/script/5_Withdraw.s.sol +++ b/script/5_Withdraw.s.sol @@ -23,8 +23,9 @@ contract DepositScript is BaseScript { string memory deployedContracts = vm.readFile("script/deployedContracts.json"); - clientGateway = - IClientChainGateway(payable(stdJson.readAddress(deployedContracts, ".clientChain.clientChainGateway"))); + clientGateway = IClientChainGateway( + payable(stdJson.readAddress(deployedContracts, ".clientChain.clientChainGateway")) + ); require(address(clientGateway) != address(0), "clientGateway address should not be empty"); clientChainLzEndpoint = ILayerZeroEndpointV2(stdJson.readAddress(deployedContracts, ".clientChain.lzEndpoint")); @@ -79,7 +80,11 @@ contract DepositScript is BaseScript { Origin(clientChainId, address(clientGateway).toBytes32(), nonce), address(exocoreGateway), GUID.generate( - nonce, clientChainId, address(clientGateway), exocoreChainId, address(exocoreGateway).toBytes32() + nonce, + clientChainId, + address(clientGateway), + exocoreChainId, + address(exocoreGateway).toBytes32() ), msg_, bytes("") diff --git a/script/6_CreateExoCapsule.s.sol b/script/6_CreateExoCapsule.s.sol index 5fc5b08e..99562c7b 100644 --- a/script/6_CreateExoCapsule.s.sol +++ b/script/6_CreateExoCapsule.s.sol @@ -24,8 +24,9 @@ contract DepositScript is BaseScript { string memory deployedContracts = vm.readFile("script/deployedContracts.json"); - clientGateway = - IClientChainGateway(payable(stdJson.readAddress(deployedContracts, ".clientChain.clientChainGateway"))); + clientGateway = IClientChainGateway( + payable(stdJson.readAddress(deployedContracts, ".clientChain.clientChainGateway")) + ); require(address(clientGateway) != address(0), "clientGateway address should not be empty"); if (!useExocorePrecompileMock) { diff --git a/script/7_DeployBootstrap.s.sol b/script/7_DeployBootstrap.s.sol index 018c6701..5f0fe522 100644 --- a/script/7_DeployBootstrap.s.sol +++ b/script/7_DeployBootstrap.s.sol @@ -26,34 +26,18 @@ contract DeployBootstrapOnly is BaseScript { clientChainLzEndpoint = ILayerZeroEndpointV2( stdJson.readAddress(prerequisiteContracts, ".clientChain.lzEndpoint") ); - require( - address(clientChainLzEndpoint) != address(0), - "Client chain endpoint not found" - ); - restakeToken = ERC20PresetFixedSupply( - stdJson.readAddress(prerequisiteContracts, ".clientChain.erc20Token") - ); - require( - address(restakeToken) != address(0), - "Restake token not found" - ); + require(address(clientChainLzEndpoint) != address(0), "Client chain endpoint not found"); + restakeToken = ERC20PresetFixedSupply(stdJson.readAddress(prerequisiteContracts, ".clientChain.erc20Token")); + require(address(restakeToken) != address(0), "Restake token not found"); clientChain = vm.createSelectFork(clientChainRPCURL); // we should use the pre-requisite to save gas instead of deploying our own - beaconOracle = EigenLayerBeaconOracle( - stdJson.readAddress(prerequisiteContracts, ".clientChain.beaconOracle") - ); - require( - address(beaconOracle) != address(0), - "Beacon oracle not found" - ); + beaconOracle = EigenLayerBeaconOracle(stdJson.readAddress(prerequisiteContracts, ".clientChain.beaconOracle")); + require(address(beaconOracle) != address(0), "Beacon oracle not found"); // same for BeaconProxyBytecode beaconProxyBytecode = BeaconProxyBytecode( stdJson.readAddress(prerequisiteContracts, ".clientChain.beaconProxyBytecode") ); - require( - address(beaconProxyBytecode) != address(0), - "Beacon proxy bytecode not found" - ); + require(address(beaconProxyBytecode) != address(0), "Beacon proxy bytecode not found"); } function run() public { @@ -75,20 +59,24 @@ contract DeployBootstrapOnly is BaseScript { ); // bootstrap implementation Bootstrap bootstrap = Bootstrap( - payable(address( - new TransparentUpgradeableProxy( - address(bootstrapLogic), address(proxyAdmin), - abi.encodeCall(Bootstrap.initialize, - ( - exocoreValidatorSet.addr, - block.timestamp + 365 days + 24 hours, - 24 hours, - payable(exocoreValidatorSet.addr), - whitelistTokens, // vault is auto deployed - address(proxyAdmin) + payable( + address( + new TransparentUpgradeableProxy( + address(bootstrapLogic), + address(proxyAdmin), + abi.encodeCall( + Bootstrap.initialize, + ( + exocoreValidatorSet.addr, + block.timestamp + 365 days + 24 hours, + 24 hours, + payable(exocoreValidatorSet.addr), + whitelistTokens, // vault is auto deployed + address(proxyAdmin) + ) ) ) - )) + ) ) ); @@ -113,10 +101,7 @@ contract DeployBootstrapOnly is BaseScript { exocoreValidatorSet.addr, emptyList ); - bootstrap.setClientChainGatewayLogic( - address(clientGatewayLogic), - initialization - ); + bootstrap.setClientChainGatewayLogic(address(clientGatewayLogic), initialization); vm.stopBroadcast(); @@ -132,13 +117,15 @@ contract DeployBootstrapOnly is BaseScript { vm.serializeAddress(clientChainContracts, "beaconOracle", address(beaconOracle)); vm.serializeAddress(clientChainContracts, "capsuleImplementation", address(capsuleImplementation)); vm.serializeAddress(clientChainContracts, "capsuleBeacon", address(capsuleBeacon)); - string memory clientChainContractsOutput = - vm.serializeAddress(clientChainContracts, "clientGatewayLogic", address(clientGatewayLogic)); + string memory clientChainContractsOutput = vm.serializeAddress( + clientChainContracts, + "clientGatewayLogic", + address(clientGatewayLogic) + ); string memory deployedContracts = "deployedContracts"; - string memory finalJson = - vm.serializeString(deployedContracts, "clientChain", clientChainContractsOutput); + string memory finalJson = vm.serializeString(deployedContracts, "clientChain", clientChainContractsOutput); vm.writeJson(finalJson, "script/deployedBootstrapOnly.json"); } -} \ No newline at end of file +} diff --git a/script/8_DepositValidator.s.sol b/script/8_DepositValidator.s.sol index 9901ca9f..006c56dc 100644 --- a/script/8_DepositValidator.s.sol +++ b/script/8_DepositValidator.s.sol @@ -37,8 +37,9 @@ contract DepositScript is BaseScript { string memory deployedContracts = vm.readFile("script/deployedContracts.json"); - clientGateway = - IClientChainGateway(payable(stdJson.readAddress(deployedContracts, ".clientChain.clientChainGateway"))); + clientGateway = IClientChainGateway( + payable(stdJson.readAddress(deployedContracts, ".clientChain.clientChainGateway")) + ); require(address(clientGateway) != address(0), "clientGateway address should not be empty"); beaconOracle = EigenLayerBeaconOracle(stdJson.readAddress(deployedContracts, ".clientChain.beaconOracle")); @@ -70,7 +71,9 @@ contract DepositScript is BaseScript { vm.selectFork(clientChain); vm.startBroadcast(depositor.privateKey); - (bool success,) = address(beaconOracle).call(abi.encodeWithSelector(beaconOracle.addTimestamp.selector, validatorProof.beaconBlockTimestamp)); + (bool success, ) = address(beaconOracle).call( + abi.encodeWithSelector(beaconOracle.addTimestamp.selector, validatorProof.beaconBlockTimestamp) + ); vm.stopBroadcast(); vm.startBroadcast(depositor.privateKey); @@ -104,9 +107,15 @@ contract DepositScript is BaseScript { validatorProof.stateRoot = stdJson.readBytes32(validatorInfo, ".beaconStateRoot"); require(validatorProof.stateRoot != bytes32(0), "state root should not be empty"); - validatorProof.stateRootProof = stdJson.readBytes32Array(validatorInfo, ".StateRootAgainstLatestBlockHeaderProof"); + validatorProof.stateRootProof = stdJson.readBytes32Array( + validatorInfo, + ".StateRootAgainstLatestBlockHeaderProof" + ); require(validatorProof.stateRootProof.length == 3, "state root proof should have 3 nodes"); - validatorProof.validatorContainerRootProof = stdJson.readBytes32Array(validatorInfo, ".WithdrawalCredentialProof"); + validatorProof.validatorContainerRootProof = stdJson.readBytes32Array( + validatorInfo, + ".WithdrawalCredentialProof" + ); require(validatorProof.validatorContainerRootProof.length == 46, "validator root proof should have 46 nodes"); validatorProof.validatorIndex = stdJson.readUint(validatorInfo, ".validatorIndex"); require(validatorProof.validatorIndex != 0, "validator root index should not be 0"); diff --git a/script/8_RegisterOperatorsAndDelegate.s.sol b/script/8_RegisterOperatorsAndDelegate.s.sol index a20d313c..99818e73 100644 --- a/script/8_RegisterOperatorsAndDelegate.s.sol +++ b/script/8_RegisterOperatorsAndDelegate.s.sol @@ -25,12 +25,12 @@ contract RegisterOperatorsAndDelegate is Script { address tokenAddr; // each subarray sums to deposits, and each item is the delegation amount uint256[4][4] amounts = [ - [ 1500 * 1e18, 250 * 1e18, 250 * 1e18, 0 * 1e18 ], - [ 300 * 1e18, 1500 * 1e18, 0 * 1e18, 200 * 1e18 ], - [ 0 * 1e18, 0 * 1e18, 2500 * 1e18, 500 * 1e18 ], - [ 1000 * 1e18, 0 * 1e18, 0 * 1e18, 2000 * 1e18 ] + [1500 * 1e18, 250 * 1e18, 250 * 1e18, 0 * 1e18], + [300 * 1e18, 1500 * 1e18, 0 * 1e18, 200 * 1e18], + [0 * 1e18, 0 * 1e18, 2500 * 1e18, 500 * 1e18], + [1000 * 1e18, 0 * 1e18, 0 * 1e18, 2000 * 1e18] ]; - + function setUp() public { primaryKey = vm.envUint("TEST_ACCOUNT_THREE_PRIVATE_KEY"); operatorKeys = vm.envUint("OPERATOR_KEYS", ","); @@ -43,8 +43,8 @@ contract RegisterOperatorsAndDelegate is Script { require( operatorKeys.length == exoAddresses.length && - operatorKeys.length == names.length && - operatorKeys.length == consKeys.length, + operatorKeys.length == names.length && + operatorKeys.length == consKeys.length, "Operator registration data length mismatch" ); @@ -57,13 +57,11 @@ contract RegisterOperatorsAndDelegate is Script { function run() public { vm.selectFork(clientChain); - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0, 1e18, 1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0, 1e18, 1e18); Bootstrap bootstrap = Bootstrap(bootstrapAddr); ERC20PresetFixedSupply token = ERC20PresetFixedSupply(tokenAddr); address vaultAddr = address(bootstrap.tokenToVault(tokenAddr)); - for(uint256 i = 0; i < operatorKeys.length; i++) { + for (uint256 i = 0; i < operatorKeys.length; i++) { uint256 pk = operatorKeys[i]; address addr = vm.addr(pk); console.log(i, addr); @@ -72,14 +70,12 @@ contract RegisterOperatorsAndDelegate is Script { bytes32 consKey = consKeys[i]; vm.startBroadcast(pk); // register operator - bootstrap.registerOperator( - exoAddr, name, commission, consKey - ); + bootstrap.registerOperator(exoAddr, name, commission, consKey); vm.stopBroadcast(); // give them the balance vm.startBroadcast(primaryKey); uint256 depositAmount = 0; - for(uint256 j = 0; j < amounts[i].length; j++) { + for (uint256 j = 0; j < amounts[i].length; j++) { depositAmount += amounts[i][j]; } if (token.balanceOf(addr) < depositAmount) { @@ -93,10 +89,10 @@ contract RegisterOperatorsAndDelegate is Script { bootstrap.deposit(tokenAddr, depositAmount); vm.stopBroadcast(); } - for(uint256 i = 0; i < operatorKeys.length; i++) { + for (uint256 i = 0; i < operatorKeys.length; i++) { uint256 pk = operatorKeys[i]; vm.startBroadcast(pk); - for(uint256 j = 0; j < operatorKeys.length; j++) { + for (uint256 j = 0; j < operatorKeys.length; j++) { uint256 amount = amounts[i][j]; if (amount == 0) { continue; @@ -108,4 +104,4 @@ contract RegisterOperatorsAndDelegate is Script { vm.stopBroadcast(); } } -} \ No newline at end of file +} diff --git a/script/9_ExtendBootstrapTime.s.sol b/script/9_ExtendBootstrapTime.s.sol index 70b73827..b1a30b02 100644 --- a/script/9_ExtendBootstrapTime.s.sol +++ b/script/9_ExtendBootstrapTime.s.sol @@ -27,4 +27,4 @@ contract SetBootstrapTime is BaseScript { vm.stopBroadcast(); } -} \ No newline at end of file +} diff --git a/script/BaseScript.sol b/script/BaseScript.sol index 29c1c6fa..262282ab 100644 --- a/script/BaseScript.sol +++ b/script/BaseScript.sol @@ -127,13 +127,19 @@ contract BaseScript is Script { vm.etch(CLAIM_REWARD_PRECOMPILE_ADDRESS, WithdrawRewardMockCode); } - function _topUpPlayer(uint256 chain, address token, Player memory provider, address recipient, uint256 targetBalance) internal { + function _topUpPlayer( + uint256 chain, + address token, + Player memory provider, + address recipient, + uint256 targetBalance + ) internal { vm.selectFork(chain); vm.startBroadcast(provider.privateKey); - + if (token == address(0)) { if (recipient.balance < targetBalance) { - (bool sent,) = recipient.call{value: targetBalance - recipient.balance}(""); + (bool sent, ) = recipient.call{value: targetBalance - recipient.balance}(""); require(sent, "Failed to send Ether"); } } else { diff --git a/script/TestPrecompileErrorFixed.s.sol b/script/TestPrecompileErrorFixed.s.sol index ab3b93a9..3273102d 100644 --- a/script/TestPrecompileErrorFixed.s.sol +++ b/script/TestPrecompileErrorFixed.s.sol @@ -45,11 +45,11 @@ contract DepositScript is BaseScript { exocore = vm.createSelectFork(exocoreRPCURL); vm.startBroadcast(exocoreGenesis.privateKey); if (depositor.addr.balance < 1 ether) { - (bool sent,) = depositor.addr.call{value: 2 ether}(""); + (bool sent, ) = depositor.addr.call{value: 2 ether}(""); require(sent, "Failed to send Ether"); } if (address(exocoreGateway).balance < 1 ether) { - (bool sent,) = address(exocoreGateway).call{value: 2 ether}(""); + (bool sent, ) = address(exocoreGateway).call{value: 2 ether}(""); require(sent, "Failed to send Ether"); } vm.stopBroadcast(); @@ -83,7 +83,11 @@ contract DepositScript is BaseScript { Origin(clientChainId, address(clientGateway).toBytes32(), nonce), address(exocoreGateway), GUID.generate( - nonce, clientChainId, address(clientGateway), exocoreChainId, address(exocoreGateway).toBytes32() + nonce, + clientChainId, + address(clientGateway), + exocoreChainId, + address(exocoreGateway).toBytes32() ), depositMsg, bytes("") @@ -104,7 +108,11 @@ contract DepositScript is BaseScript { Origin(clientChainId, address(clientGateway).toBytes32(), nonce), address(exocoreGateway), GUID.generate( - nonce, clientChainId, address(clientGateway), exocoreChainId, address(exocoreGateway).toBytes32() + nonce, + clientChainId, + address(clientGateway), + exocoreChainId, + address(exocoreGateway).toBytes32() ), withdrawMsg, bytes("") diff --git a/script/TestPrecompileErrorFixed_Deploy.s.sol b/script/TestPrecompileErrorFixed_Deploy.s.sol index 5663a4d1..3044d25b 100644 --- a/script/TestPrecompileErrorFixed_Deploy.s.sol +++ b/script/TestPrecompileErrorFixed_Deploy.s.sol @@ -37,7 +37,7 @@ contract DepositScript is BaseScript { exocore = vm.createSelectFork(exocoreRPCURL); vm.startBroadcast(exocoreGenesis.privateKey); if (deployer.addr.balance < 1 ether) { - (bool sent,) = deployer.addr.call{value: 1 ether}(""); + (bool sent, ) = deployer.addr.call{value: 1 ether}(""); require(sent, "Failed to send Ether"); } vm.stopBroadcast(); @@ -50,8 +50,11 @@ contract DepositScript is BaseScript { string memory exocoreContracts = "exocoreContracts"; vm.serializeAddress(exocoreContracts, "lzEndpoint", address(exocoreLzEndpoint)); - string memory exocoreContractsOutput = - vm.serializeAddress(exocoreContracts, "exocoreGateway", address(exocoreGateway)); + string memory exocoreContractsOutput = vm.serializeAddress( + exocoreContracts, + "exocoreGateway", + address(exocoreGateway) + ); string memory finalJson = vm.serializeString(testContracts, "exocore", exocoreContractsOutput); @@ -77,8 +80,9 @@ contract DepositScript is BaseScript { vm.startBroadcast(exocoreValidatorSet.privateKey); exocoreGateway.setPeer(clientChainId, address(clientGateway).toBytes32()); NonShortCircuitEndpointV2Mock(address(exocoreLzEndpoint)).setDestLzEndpoint( - address(clientGateway), address(clientChainLzEndpoint) - ); + address(clientGateway), + address(clientChainLzEndpoint) + ); vm.stopBroadcast(); } } diff --git a/script/TokenTransfer.s.sol b/script/TokenTransfer.s.sol index 316ec05e..3b713abd 100644 --- a/script/TokenTransfer.s.sol +++ b/script/TokenTransfer.s.sol @@ -68,8 +68,9 @@ contract DeployScript is Script { string memory deployedContracts = vm.readFile("script/deployedContracts.json"); - clientGateway = - ClientChainGateway(payable(stdJson.readAddress(deployedContracts, ".clientChain.clientChainGateway"))); + clientGateway = ClientChainGateway( + payable(stdJson.readAddress(deployedContracts, ".clientChain.clientChainGateway")) + ); clientChainLzEndpoint = ILayerZeroEndpoint(stdJson.readAddress(deployedContracts, ".clientChain.lzEndpoint")); restakeToken = ERC20PresetFixedSupply(stdJson.readAddress(deployedContracts, ".clientChain.erc20Token")); vault = Vault(stdJson.readAddress(deployedContracts, ".clientChain.resVault")); @@ -96,11 +97,11 @@ contract DeployScript is Script { vm.startBroadcast(clientChainDeployer.privateKey); if (address(clientGateway).balance < 0.2 ether) { - (bool sent,) = address(clientGateway).call{value: 0.2 ether}(""); + (bool sent, ) = address(clientGateway).call{value: 0.2 ether}(""); require(sent, "Failed to send Ether"); } if (exocoreValidatorSet.addr.balance < 0.02 ether) { - (bool sent,) = exocoreValidatorSet.addr.call{value: 0.02 ether}(""); + (bool sent, ) = exocoreValidatorSet.addr.call{value: 0.02 ether}(""); require(sent, "Failed to send Ether"); } vm.stopBroadcast(); @@ -108,11 +109,11 @@ contract DeployScript is Script { exocore = vm.createSelectFork(exocoreRPCURL); vm.startBroadcast(exocoreDeployer.privateKey); if (relayer.addr.balance < 1 ether) { - (bool sent,) = relayer.addr.call{value: 0.1 ether}(""); + (bool sent, ) = relayer.addr.call{value: 0.1 ether}(""); require(sent, "Failed to send Ether"); } if (address(exocoreGateway).balance < 1 ether) { - (bool sent,) = address(exocoreGateway).call{value: 0.1 ether}(""); + (bool sent, ) = address(exocoreGateway).call{value: 0.1 ether}(""); require(sent, "Failed to send Ether"); } vm.stopBroadcast(); diff --git a/script/deployBeaconOracle.s.sol b/script/deployBeaconOracle.s.sol index dbf99850..56cf4fbe 100644 --- a/script/deployBeaconOracle.s.sol +++ b/script/deployBeaconOracle.s.sol @@ -20,7 +20,9 @@ contract PrerequisitiesScript is BaseScript { vm.startBroadcast(deployer.privateKey); beaconOracle = EigenLayerBeaconOracle(0xd3D285cd1516038dAED61B8BF7Ae2daD63662492); - (bool success,) = address(beaconOracle).call(abi.encodeWithSelector(beaconOracle.addTimestamp.selector, 1715918948)); + (bool success, ) = address(beaconOracle).call( + abi.encodeWithSelector(beaconOracle.addTimestamp.selector, 1715918948) + ); vm.stopPrank(); } } diff --git a/script/integration/1_DeployBootstrap.s.sol b/script/integration/1_DeployBootstrap.s.sol index d7725086..641510cd 100644 --- a/script/integration/1_DeployBootstrap.s.sol +++ b/script/integration/1_DeployBootstrap.s.sol @@ -83,21 +83,17 @@ contract DeployContracts is Script { function deployTokens() private { string[2] memory names = ["MyToken1", "MyToken2"]; string[2] memory symbols = ["MT1", "MT2"]; - uint256[2] memory initialBalances = [ - 2000 * 10 ** decimals[0], 5000 * 10 ** decimals[1] - ]; + uint256[2] memory initialBalances = [2000 * 10 ** decimals[0], 5000 * 10 ** decimals[1]]; address[] memory initialAddresses = new address[](operators.length + stakers.length); - for(uint256 i = 0; i < operators.length; i++) { + for (uint256 i = 0; i < operators.length; i++) { initialAddresses[i] = vm.addr(operators[i]); } - for(uint256 i = 0; i < stakers.length; i++) { + for (uint256 i = 0; i < stakers.length; i++) { initialAddresses[operators.length + i] = vm.addr(stakers[i]); } - for(uint256 i = 0; i < tokenDeployers.length; i++) { + for (uint256 i = 0; i < tokenDeployers.length; i++) { vm.startBroadcast(tokenDeployers[i]); - MyToken myToken = new MyToken( - names[i], symbols[i], decimals[i], initialAddresses, initialBalances[i] - ); + MyToken myToken = new MyToken(names[i], symbols[i], decimals[i], initialAddresses, initialBalances[i]); whitelistTokens.push(address(myToken)); vm.stopBroadcast(); } @@ -124,20 +120,24 @@ contract DeployContracts is Script { address(beaconProxyBytecode) ); bootstrap = Bootstrap( - payable(address( - new TransparentUpgradeableProxy( - address(bootstrapLogic), address(proxyAdmin), - abi.encodeCall(bootstrap.initialize, - ( - vm.addr(contractDeployer), - block.timestamp + 3 minutes, - 1 seconds, - payable(exocoreValidatorSet), - whitelistTokens, - address(proxyAdmin) + payable( + address( + new TransparentUpgradeableProxy( + address(bootstrapLogic), + address(proxyAdmin), + abi.encodeCall( + bootstrap.initialize, + ( + vm.addr(contractDeployer), + block.timestamp + 3 minutes, + 1 seconds, + payable(exocoreValidatorSet), + whitelistTokens, + address(proxyAdmin) + ) ) ) - )) + ) ) ); vm.stopBroadcast(); @@ -146,23 +146,19 @@ contract DeployContracts is Script { function approveAndDeposit() private { // amounts deposited by each operator, for the tokens 1 and 2. - uint256[2] memory operatorAmounts = [ - 1500 * 10 ** decimals[0], 2000 * 10 ** decimals[1] - ]; + uint256[2] memory operatorAmounts = [1500 * 10 ** decimals[0], 2000 * 10 ** decimals[1]]; // stakerAmounts - keep divisible by 3 for delegate - uint256[2] memory stakerAmounts = [ - 300 * 10 ** decimals[0], 600 * 10 ** decimals[1] - ]; - for(uint256 i = 0; i < whitelistTokens.length; i++) { - for(uint256 j = 0; j < operators.length; j++) { + uint256[2] memory stakerAmounts = [300 * 10 ** decimals[0], 600 * 10 ** decimals[1]]; + for (uint256 i = 0; i < whitelistTokens.length; i++) { + for (uint256 j = 0; j < operators.length; j++) { vm.startBroadcast(operators[j]); MyToken(whitelistTokens[i]).approve(address(vaults[i]), type(uint256).max); bootstrap.deposit(whitelistTokens[i], operatorAmounts[i]); vm.stopBroadcast(); } } - for(uint256 i = 0; i < whitelistTokens.length; i++) { - for(uint256 j = 0; j < stakers.length; j++) { + for (uint256 i = 0; i < whitelistTokens.length; i++) { + for (uint256 j = 0; j < stakers.length; j++) { vm.startBroadcast(stakers[j]); MyToken(whitelistTokens[i]).approve(address(vaults[i]), type(uint256).max); bootstrap.deposit(whitelistTokens[i], stakerAmounts[i]); @@ -195,14 +191,10 @@ contract DeployContracts is Script { // wise sister language work muscle parade dad angry across emerge trade bytes32(0x4C9DE94E1F3225906602AE812E30F1BE56427126D60F2F6CB661B7F4FDA638DC) ]; - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0, 1e18, 1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0, 1e18, 1e18); for (uint256 i = 0; i < operators.length; i++) { vm.startBroadcast(operators[i]); - bootstrap.registerOperator( - exos[i], names[i], commission, pubKeys[i] - ); + bootstrap.registerOperator(exos[i], names[i], commission, pubKeys[i]); vm.stopBroadcast(); } } @@ -233,9 +225,7 @@ contract DeployContracts is Script { string memory operatorExo = bootstrap.ethToExocoreAddress(operator); vm.startBroadcast(delegator); if (amount != 0) { - bootstrap.delegateTo( - operatorExo, whitelistTokens[i], amount - ); + bootstrap.delegateTo(operatorExo, whitelistTokens[i], amount); } vm.stopBroadcast(); } @@ -250,10 +240,8 @@ contract DeployContracts is Script { for (uint256 j = 0; j < stakers.length; j++) { uint256 delegator = stakers[j]; address delegatorAddress = vm.addr(delegator); - uint256 deposit = bootstrap.totalDepositAmounts( - delegatorAddress, whitelistTokens[i] - ); - uint256 stakerDelegationToDo = deposit * (i+1) / 3; + uint256 deposit = bootstrap.totalDepositAmounts(delegatorAddress, whitelistTokens[i]); + uint256 stakerDelegationToDo = (deposit * (i + 1)) / 3; for (uint256 k = 0; k < operators.length; k++) { uint256 amount; if (k == operators.length - 1) { @@ -264,9 +252,7 @@ contract DeployContracts is Script { address operator = vm.addr(operators[k]); string memory exo = bootstrap.ethToExocoreAddress(operator); vm.startBroadcast(delegator); - bootstrap.delegateTo( - exo, whitelistTokens[i], amount - ); + bootstrap.delegateTo(exo, whitelistTokens[i], amount); stakerDelegationToDo -= amount; vm.stopBroadcast(); } @@ -289,7 +275,7 @@ contract DeployContracts is Script { delegate(); console.log("[Delegated]; done!"); - for(uint256 i = 0; i < whitelistTokens.length; i++) { + for (uint256 i = 0; i < whitelistTokens.length; i++) { console.log("Token ", i, " address: ", whitelistTokens[i]); } } @@ -297,7 +283,6 @@ contract DeployContracts is Script { // Helper function to generate a random number within a range function random(uint256 _range) internal view returns (uint256) { // Basic random number generation; consider a more robust approach for production - return uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao))) % (_range - 1) + 1; + return (uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao))) % (_range - 1)) + 1; } - -} \ No newline at end of file +} diff --git a/src/core/BaseRestakingController.sol b/src/core/BaseRestakingController.sol index 96b144f8..dc04181c 100644 --- a/src/core/BaseRestakingController.sol +++ b/src/core/BaseRestakingController.sol @@ -9,7 +9,6 @@ import {IBaseRestakingController} from "../interfaces/IBaseRestakingController.s import {PausableUpgradeable} from "@openzeppelin-upgradeable/contracts/utils/PausableUpgradeable.sol"; import {OptionsBuilder} from "@layerzero-v2/oapp/contracts/oapp/libs/OptionsBuilder.sol"; - abstract contract BaseRestakingController is PausableUpgradeable, OAppSenderUpgradeable, @@ -20,11 +19,11 @@ abstract contract BaseRestakingController is receive() external payable {} - function claim(address token, uint256 amount, address recipient) - external - isTokenWhitelisted(token) - isValidAmount(amount) - whenNotPaused { + function claim( + address token, + uint256 amount, + address recipient + ) external isTokenWhitelisted(token) isValidAmount(amount) whenNotPaused { if (token == VIRTUAL_STAKED_ETH_ADDRESS) { IExoCapsule capsule = _getCapsule(msg.sender); capsule.withdraw(amount, recipient); @@ -38,21 +37,19 @@ abstract contract BaseRestakingController is } } - function delegateTo(string calldata operator, address token, uint256 amount) - external payable - isTokenWhitelisted(token) - isValidAmount(amount) - isValidBech32Address(operator) - whenNotPaused { + function delegateTo( + string calldata operator, + address token, + uint256 amount + ) external payable isTokenWhitelisted(token) isValidAmount(amount) isValidBech32Address(operator) whenNotPaused { _processRequest(token, msg.sender, amount, Action.REQUEST_DELEGATE_TO, operator); } - function undelegateFrom(string calldata operator, address token, uint256 amount) - external payable - isTokenWhitelisted(token) - isValidAmount(amount) - isValidBech32Address(operator) - whenNotPaused { + function undelegateFrom( + string calldata operator, + address token, + uint256 amount + ) external payable isTokenWhitelisted(token) isValidAmount(amount) isValidBech32Address(operator) whenNotPaused { _processRequest(token, msg.sender, amount, Action.REQUEST_UNDELEGATE_FROM, operator); } @@ -88,10 +85,20 @@ abstract contract BaseRestakingController is } function _sendMsgToExocore(Action action, bytes memory actionArgs) internal { bytes memory payload = abi.encodePacked(action, actionArgs); - bytes memory options = OptionsBuilder.newOptions().addExecutorLzReceiveOption(DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE).addExecutorOrderedExecutionOption(); + bytes memory options = OptionsBuilder + .newOptions() + .addExecutorLzReceiveOption(DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE) + .addExecutorOrderedExecutionOption(); MessagingFee memory fee = _quote(exocoreChainId, payload, options, false); - MessagingReceipt memory receipt = _lzSend(exocoreChainId, payload, options, MessagingFee(fee.nativeFee, 0), exocoreValidatorSetAddress, false); + MessagingReceipt memory receipt = _lzSend( + exocoreChainId, + payload, + options, + MessagingFee(fee.nativeFee, 0), + exocoreValidatorSetAddress, + false + ); emit MessageSent(action, receipt.guid, receipt.nonce, receipt.fee.nativeFee); } } diff --git a/src/core/Bootstrap.sol b/src/core/Bootstrap.sol index 814708f9..69306343 100644 --- a/src/core/Bootstrap.sol +++ b/src/core/Bootstrap.sol @@ -36,7 +36,7 @@ contract Bootstrap is { constructor( address endpoint_, - uint32 exocoreChainId_, + uint32 exocoreChainId_, address vaultBeacon_, address beaconProxyBytecode_ ) OAppCoreUpgradeable(endpoint_) BootstrapStorage(exocoreChainId_, vaultBeacon_, beaconProxyBytecode_) { @@ -54,19 +54,14 @@ contract Bootstrap is require(owner != address(0), "Bootstrap: owner should not be empty"); require(spawnTime_ > block.timestamp, "Bootstrap: spawn time should be in the future"); require(offsetDuration_ > 0, "Bootstrap: offset duration should be greater than 0"); - require( - spawnTime_ > offsetDuration_, - "Bootstrap: spawn time should be greater than offset duration" - ); + require(spawnTime_ > offsetDuration_, "Bootstrap: spawn time should be greater than offset duration"); uint256 lockTime = spawnTime_ - offsetDuration_; + require(lockTime > block.timestamp, "Bootstrap: lock time should be in the future"); require( - lockTime > block.timestamp, - "Bootstrap: lock time should be in the future" + exocoreValidatorSetAddress_ != address(0), + "Bootstrap: exocore validator set address should not be empty" ); - require(exocoreValidatorSetAddress_ != address(0), - "Bootstrap: exocore validator set address should not be empty"); - require(customProxyAdmin_ != address(0), - "Bootstrap: custom proxy admin should not be empty"); + require(customProxyAdmin_ != address(0), "Bootstrap: custom proxy admin should not be empty"); exocoreSpawnTime = spawnTime_; offsetDuration = offsetDuration_; @@ -81,8 +76,7 @@ contract Bootstrap is _deployVault(underlyingToken); } - _whiteListFunctionSelectors[Action.MARK_BOOTSTRAP] = - this.markBootstrapped.selector; + _whiteListFunctionSelectors[Action.MARK_BOOTSTRAP] = this.markBootstrapped.selector; customProxyAdmin = customProxyAdmin_; bootstrapped = false; @@ -117,21 +111,18 @@ contract Bootstrap is * to perform these operations during the lock period will result in a transaction * revert with an informative error message. */ - modifier beforeLocked { - require( - !isLocked(), - "Bootstrap: operation not allowed after lock time" - ); + modifier beforeLocked() { + require(!isLocked(), "Bootstrap: operation not allowed after lock time"); _; } // pausing and unpausing can happen at all times, including after locked time. - function pause() onlyOwner external { + function pause() external onlyOwner { _pause(); } // pausing and unpausing can happen at all times, including after locked time. - function unpause() onlyOwner external { + function unpause() external onlyOwner { _unpause(); } @@ -143,19 +134,10 @@ contract Bootstrap is * @param _spawnTime The new spawn time in seconds. */ function setSpawnTime(uint256 _spawnTime) external onlyOwner beforeLocked { - require( - _spawnTime > block.timestamp, - "Bootstrap: spawn time should be in the future" - ); - require( - _spawnTime > offsetDuration, - "Bootstrap: spawn time should be greater than offset duration" - ); + require(_spawnTime > block.timestamp, "Bootstrap: spawn time should be in the future"); + require(_spawnTime > offsetDuration, "Bootstrap: spawn time should be greater than offset duration"); uint256 lockTime = _spawnTime - offsetDuration; - require( - lockTime > block.timestamp, - "Bootstrap: lock time should be in the future" - ); + require(lockTime > block.timestamp, "Bootstrap: lock time should be in the future"); // technically the spawn time can be moved backwards in time as well. exocoreSpawnTime = _spawnTime; emit SpawnTimeUpdated(_spawnTime); @@ -170,32 +152,21 @@ contract Bootstrap is * @param _offsetDuration The new offset duration in seconds. */ function setOffsetDuration(uint256 _offsetDuration) external onlyOwner beforeLocked { - require( - exocoreSpawnTime > _offsetDuration, - "Bootstrap: spawn time should be greater than offset duration" - ); + require(exocoreSpawnTime > _offsetDuration, "Bootstrap: spawn time should be greater than offset duration"); uint256 lockTime = exocoreSpawnTime - _offsetDuration; - require( - lockTime > block.timestamp, - "Bootstrap: lock time should be in the future" - ); + require(lockTime > block.timestamp, "Bootstrap: lock time should be in the future"); offsetDuration = _offsetDuration; emit OffsetDurationUpdated(_offsetDuration); } // implementation of ITokenWhitelister - function addWhitelistToken( - address _token - ) external beforeLocked onlyOwner whenNotPaused { + function addWhitelistToken(address _token) external beforeLocked onlyOwner whenNotPaused { // modifiers: onlyOwner and whenNotPaused copied from client chain gateway. // i added beforeLocked to ensure that new tokens may not be added after // the offset duration before the spawn time begins. // anyway it would be pointless to add such tokens since other operations // cannot be performed. - require( - !isWhitelistedToken[_token], - "Bootstrap: token should be not whitelisted before" - ); + require(!isWhitelistedToken[_token], "Bootstrap: token should be not whitelisted before"); whitelistTokens.push(_token); isWhitelistedToken[_token] = true; @@ -208,17 +179,12 @@ contract Bootstrap is } // implementation of ITokenWhitelister - function removeWhitelistToken( - address _token - ) external beforeLocked onlyOwner whenNotPaused { - require( - isWhitelistedToken[_token], - "Bootstrap: token should be already whitelisted" - ); + function removeWhitelistToken(address _token) external beforeLocked onlyOwner whenNotPaused { + require(isWhitelistedToken[_token], "Bootstrap: token should be already whitelisted"); isWhitelistedToken[_token] = false; // the implicit assumption here is that the _token must be included in whitelistTokens // if isWhitelistedToken[_token] is true - for(uint i = 0; i < whitelistTokens.length; i++) { + for (uint i = 0; i < whitelistTokens.length; i++) { if (whitelistTokens[i] == _token) { whitelistTokens[i] = whitelistTokens[whitelistTokens.length - 1]; whitelistTokens.pop(); @@ -237,35 +203,20 @@ contract Bootstrap is bytes32 consensusPublicKey ) external beforeLocked whenNotPaused { // ensure the address format is valid. - require( - isValidExocoreAddress(operatorExocoreAddress), - "Bootstrap: invalid bech32 address" - ); + require(isValidExocoreAddress(operatorExocoreAddress), "Bootstrap: invalid bech32 address"); // ensure that there is only one operator per ethereum address - require( - bytes(ethToExocoreAddress[msg.sender]).length == 0, - "Ethereum address already linked to an operator" - ); + require(bytes(ethToExocoreAddress[msg.sender]).length == 0, "Ethereum address already linked to an operator"); // check if operator with the same exocore address already exists require( bytes(operators[operatorExocoreAddress].name).length == 0, "Operator with this Exocore address is already registered" ); // check that the consensus key is unique. - require( - !consensusPublicKeyInUse(consensusPublicKey), - "Consensus public key already in use" - ); + require(!consensusPublicKeyInUse(consensusPublicKey), "Consensus public key already in use"); // and that the name (meta info) is unique. - require( - !nameInUse(name), - "Name already in use" - ); + require(!nameInUse(name), "Name already in use"); // check that the commission is valid. - require( - isCommissionValid(commission), - "invalid commission" - ); + require(isCommissionValid(commission), "invalid commission"); ethToExocoreAddress[msg.sender] = operatorExocoreAddress; operators[operatorExocoreAddress] = IOperatorRegistry.Operator({ name: name, @@ -273,13 +224,7 @@ contract Bootstrap is consensusPublicKey: consensusPublicKey }); registeredOperators.push(msg.sender); - emit OperatorRegistered( - msg.sender, - operatorExocoreAddress, - name, - commission, - consensusPublicKey - ); + emit OperatorRegistered(msg.sender, operatorExocoreAddress, name, commission, consensusPublicKey); } /** @@ -299,7 +244,7 @@ contract Bootstrap is * existing operator, indicating that the key is not unique. Returns `false` if the * public key is not found among the registered operators, indicating that the key * is unique and can be safely used for a new or updating operator. - */ + */ function consensusPublicKeyInUse(bytes32 newKey) public view returns (bool) { require(newKey != bytes32(0), "Consensus public key cannot be zero"); for (uint256 i = 0; i < registeredOperators.length; i++) { @@ -346,13 +291,12 @@ contract Bootstrap is * indicating that the name is not unique. Returns `false` if the name is not found * among the registered operators, indicating that the name is unique and can be * safely used for a new operator. - */ + */ function nameInUse(string memory newName) public view returns (bool) { for (uint256 i = 0; i < registeredOperators.length; i++) { address ethAddress = registeredOperators[i]; string memory exoAddress = ethToExocoreAddress[ethAddress]; - if (keccak256(abi.encodePacked(operators[exoAddress].name)) == - keccak256(abi.encodePacked(newName))) { + if (keccak256(abi.encodePacked(operators[exoAddress].name)) == keccak256(abi.encodePacked(newName))) { return true; } } @@ -360,30 +304,17 @@ contract Bootstrap is } // implementation of IOperatorRegistry - function replaceKey( - bytes32 newKey - ) external beforeLocked whenNotPaused { - require( - bytes(ethToExocoreAddress[msg.sender]).length != 0, - "no such operator exists" - ); - require( - !consensusPublicKeyInUse(newKey), - "Consensus public key already in use" - ); + function replaceKey(bytes32 newKey) external beforeLocked whenNotPaused { + require(bytes(ethToExocoreAddress[msg.sender]).length != 0, "no such operator exists"); + require(!consensusPublicKeyInUse(newKey), "Consensus public key already in use"); operators[ethToExocoreAddress[msg.sender]].consensusPublicKey = newKey; emit OperatorKeyReplaced(ethToExocoreAddress[msg.sender], newKey); } // implementation of IOperatorRegistry - function updateRate( - uint256 newRate - ) external beforeLocked whenNotPaused { + function updateRate(uint256 newRate) external beforeLocked whenNotPaused { string memory operatorAddress = ethToExocoreAddress[msg.sender]; - require( - bytes(operatorAddress).length != 0, - "no such operator exists" - ); + require(bytes(operatorAddress).length != 0, "no such operator exists"); // across the lifetime of this contract before network bootstrap, // allow the editing of commission only once. require(!commissionEdited[operatorAddress], "Commission already edited once"); @@ -396,10 +327,7 @@ contract Bootstrap is // to prevent operators from blindsiding users by first registering at low rate and // subsequently increasing it, we should also check that the change is within the // allowed rate change. - require( - newRate <= rate + maxChangeRate, - "Rate change exceeds max change rate" - ); + require(newRate <= rate + maxChangeRate, "Rate change exceeds max change rate"); operators[operatorAddress].commission.rate = newRate; commissionEdited[operatorAddress] = true; emit OperatorCommissionUpdated(newRate); @@ -412,9 +340,7 @@ contract Bootstrap is * @dev This function checks if the token is whitelisted, the amount is greater than zero * and that a vault for the token exists. */ - function _validateAndGetVault( - address token, uint256 amount - ) view internal returns (IVault) { + function _validateAndGetVault(address token, uint256 amount) internal view returns (IVault) { require(isWhitelistedToken[token], "Bootstrap: token is not whitelisted"); require(amount > 0, "Bootstrap: amount should be greater than zero"); @@ -422,9 +348,7 @@ contract Bootstrap is } // implementation of IController - function deposit( - address token, uint256 amount - ) override external payable beforeLocked whenNotPaused { + function deposit(address token, uint256 amount) external payable override beforeLocked whenNotPaused { IVault vault = _validateAndGetVault(token, amount); vault.deposit(msg.sender, amount); @@ -449,20 +373,15 @@ contract Bootstrap is // implementation of IController // This will allow release of undelegated (free) funds to the user for claiming separately. function withdrawPrincipleFromExocore( - address token, uint256 amount - ) override external payable beforeLocked whenNotPaused { + address token, + uint256 amount + ) external payable override beforeLocked whenNotPaused { IVault vault = _validateAndGetVault(token, amount); uint256 deposited = totalDepositAmounts[msg.sender][token]; - require( - deposited >= amount, - "Bootstrap: insufficient deposited balance" - ); + require(deposited >= amount, "Bootstrap: insufficient deposited balance"); uint256 withdrawable = withdrawableAmounts[msg.sender][token]; - require( - withdrawable >= amount, - "Bootstrap: insufficient withdrawable balance" - ); + require(withdrawable >= amount, "Bootstrap: insufficient withdrawable balance"); // when the withdraw precompile is called, it does these things. totalDepositAmounts[msg.sender][token] -= amount; @@ -478,38 +397,30 @@ contract Bootstrap is // implementation of IController // there are no rewards before the network bootstrap, so this function is not supported. - function withdrawRewardFromExocore( - address, uint256 - ) override external payable beforeLocked whenNotPaused { + function withdrawRewardFromExocore(address, uint256) external payable override beforeLocked whenNotPaused { revert NotYetSupported(); } // implementation of IController - function claim( - address token, uint256 amount, address recipient - ) override external beforeLocked whenNotPaused { + function claim(address token, uint256 amount, address recipient) external override beforeLocked whenNotPaused { IVault vault = _validateAndGetVault(token, amount); vault.withdraw(msg.sender, recipient, amount); } // implementation of IController function delegateTo( - string calldata operator, address token, uint256 amount - ) override external payable beforeLocked whenNotPaused { - _validateAndGetVault(token, amount); + string calldata operator, + address token, + uint256 amount + ) external payable override beforeLocked whenNotPaused { + _validateAndGetVault(token, amount); // check that operator is registered - require( - bytes(operators[operator].name).length != 0, - "Operator does not exist" - ); + require(bytes(operators[operator].name).length != 0, "Operator does not exist"); // operator can't be frozen and amount can't be negative // asset validity has been checked. // now check amounts. uint256 withdrawable = withdrawableAmounts[msg.sender][token]; - require( - withdrawable >= amount, - "Bootstrap: insufficient withdrawable balance" - ); + require(withdrawable >= amount, "Bootstrap: insufficient withdrawable balance"); delegations[msg.sender][operator][token] += amount; delegationsByOperator[operator][token] += amount; withdrawableAmounts[msg.sender][token] -= amount; @@ -519,22 +430,18 @@ contract Bootstrap is // implementation of IController function undelegateFrom( - string calldata operator, address token, uint256 amount - ) override external payable beforeLocked whenNotPaused { + string calldata operator, + address token, + uint256 amount + ) external payable override beforeLocked whenNotPaused { _validateAndGetVault(token, amount); // check that operator is registered - require( - bytes(operators[operator].name).length != 0, - "Operator does not exist" - ); + require(bytes(operators[operator].name).length != 0, "Operator does not exist"); // operator can't be frozen and amount can't be negative // asset validity has been checked. // now check amounts. uint256 delegated = delegations[msg.sender][operator][token]; - require( - delegated >= amount, - "Bootstrap: insufficient delegated balance" - ); + require(delegated >= amount, "Bootstrap: insufficient delegated balance"); // the undelegation is released immediately since it is not at stake yet. delegations[msg.sender][operator][token] -= amount; delegationsByOperator[operator][token] -= amount; @@ -563,22 +470,14 @@ contract Bootstrap is // nonce match, which requires that inbound nonce is uint64(1). // TSS checks are not super clear since they can be set by anyone // but at this point that does not matter since it is not fully implemented anyway. - require( - block.timestamp >= exocoreSpawnTime, - "Bootstrap: not yet in the bootstrap time" - ); - require( - !bootstrapped, - "Bootstrap: already bootstrapped" - ); - require( - clientChainGatewayLogic != address(0), - "Bootstrap: client chain gateway logic not set" - ); + require(block.timestamp >= exocoreSpawnTime, "Bootstrap: not yet in the bootstrap time"); + require(!bootstrapped, "Bootstrap: already bootstrapped"); + require(clientChainGatewayLogic != address(0), "Bootstrap: client chain gateway logic not set"); ICustomProxyAdmin(customProxyAdmin).changeImplementation( // address(this) is storage address and not logic address. so it is a proxy. ITransparentUpgradeableProxy(address(this)), - clientChainGatewayLogic, clientChainInitializationData + clientChainGatewayLogic, + clientChainInitializationData ); emit Bootstrapped(); } @@ -599,10 +498,7 @@ contract Bootstrap is ) public onlyOwner { clientChainGatewayLogic = _clientChainGatewayLogic; clientChainInitializationData = _clientChainInitializationData; - emit ClientChainGatewayLogicUpdated( - _clientChainGatewayLogic, - _clientChainInitializationData - ); + emit ClientChainGatewayLogicUpdated(_clientChainGatewayLogic, _clientChainInitializationData); } /** @@ -610,8 +506,7 @@ contract Bootstrap is * @return The number of registered operators. * @notice This function returns the total number of registered operators in the contract. */ - function getOperatorsCount( - ) external view returns (uint256) { + function getOperatorsCount() external view returns (uint256) { return registeredOperators.length; } @@ -620,8 +515,7 @@ contract Bootstrap is * @return The number of depositors. * @notice This function returns the total number of depositors in the contract. */ - function getDepositorsCount( - ) external view returns (uint256) { + function getDepositorsCount() external view returns (uint256) { return depositors.length; } @@ -630,8 +524,7 @@ contract Bootstrap is * @return The number of whitelisted tokens. * @notice This function returns the total number of whitelisted tokens in the contract. */ - function getWhitelistedTokensCount( - ) external view returns (uint256) { + function getWhitelistedTokensCount() external view returns (uint256) { return whitelistTokens.length; } @@ -645,13 +538,14 @@ contract Bootstrap is require(index < whitelistTokens.length, "Index out of bounds"); address tokenAddress = whitelistTokens[index]; ERC20 token = ERC20(tokenAddress); - return TokenInfo({ - name: token.name(), - symbol: token.symbol(), - tokenAddress: tokenAddress, - decimals: token.decimals(), - totalSupply: token.totalSupply(), - depositAmount: depositsByToken[tokenAddress] - }); + return + TokenInfo({ + name: token.name(), + symbol: token.symbol(), + tokenAddress: tokenAddress, + decimals: token.decimals(), + totalSupply: token.totalSupply(), + depositAmount: depositsByToken[tokenAddress] + }); } -} \ No newline at end of file +} diff --git a/src/core/BootstrapLzReceiver.sol b/src/core/BootstrapLzReceiver.sol index ce6e1fbc..ea0f87ac 100644 --- a/src/core/BootstrapLzReceiver.sol +++ b/src/core/BootstrapLzReceiver.sol @@ -6,11 +6,7 @@ import {OwnableUpgradeable} from "@openzeppelin-upgradeable/contracts/access/Own import {OAppReceiverUpgradeable, Origin} from "../lzApp/OAppReceiverUpgradeable.sol"; import {PausableUpgradeable} from "@openzeppelin-upgradeable/contracts/utils/PausableUpgradeable.sol"; -abstract contract BootstrapLzReceiver is - PausableUpgradeable, - OAppReceiverUpgradeable, - BootstrapStorage -{ +abstract contract BootstrapLzReceiver is PausableUpgradeable, OAppReceiverUpgradeable, BootstrapStorage { modifier onlyCalledFromThis() { require( msg.sender == address(this), @@ -19,9 +15,7 @@ abstract contract BootstrapLzReceiver is _; } - function _lzReceive( - Origin calldata _origin, bytes calldata payload - ) internal virtual override { + function _lzReceive(Origin calldata _origin, bytes calldata payload) internal virtual override { if (_origin.srcEid != exocoreChainId) { revert UnexpectedSourceChain(_origin.srcEid); } @@ -32,20 +26,16 @@ abstract contract BootstrapLzReceiver is if (selector_ == bytes4(0)) { revert UnsupportedRequest(act); } - (bool success, bytes memory reason) = - address(this).call(abi.encodePacked(selector_, abi.encode(payload[1:]))); + (bool success, bytes memory reason) = address(this).call(abi.encodePacked(selector_, abi.encode(payload[1:]))); if (!success) { revert RequestOrResponseExecuteFailed(act, _origin.nonce, reason); } } - function nextNonce(uint32 srcEid, bytes32 sender) - public - view - virtual - override(OAppReceiverUpgradeable) - returns (uint64) - { + function nextNonce( + uint32 srcEid, + bytes32 sender + ) public view virtual override(OAppReceiverUpgradeable) returns (uint64) { return inboundNonce[srcEid][sender] + 1; } diff --git a/src/core/ClientChainGateway.sol b/src/core/ClientChainGateway.sol index 1630d04d..4cceb2d6 100644 --- a/src/core/ClientChainGateway.sol +++ b/src/core/ClientChainGateway.sol @@ -46,7 +46,13 @@ contract ClientChainGateway is address beaconProxyBytecode_ ) OAppCoreUpgradeable(endpoint_) - ClientChainGatewayStorage(exocoreChainId_, beaconOracleAddress_, vaultBeacon_, exoCapsuleBeacon_, beaconProxyBytecode_) + ClientChainGatewayStorage( + exocoreChainId_, + beaconOracleAddress_, + vaultBeacon_, + exoCapsuleBeacon_, + beaconProxyBytecode_ + ) { _disableInitializers(); } @@ -59,7 +65,10 @@ contract ClientChainGateway is ) external reinitializer(2) { _clearBootstrapData(); - require(exocoreValidatorSetAddress_ != address(0), "ClientChainGateway: exocore validator set address should not be empty"); + require( + exocoreValidatorSetAddress_ != address(0), + "ClientChainGateway: exocore validator set address should not be empty" + ); exocoreValidatorSetAddress = exocoreValidatorSetAddress_; @@ -78,12 +87,14 @@ contract ClientChainGateway is } _registeredResponseHooks[Action.REQUEST_DEPOSIT] = this.afterReceiveDepositResponse.selector; - _registeredResponseHooks[Action.REQUEST_WITHDRAW_PRINCIPLE_FROM_EXOCORE] = - this.afterReceiveWithdrawPrincipleResponse.selector; + _registeredResponseHooks[Action.REQUEST_WITHDRAW_PRINCIPLE_FROM_EXOCORE] = this + .afterReceiveWithdrawPrincipleResponse + .selector; _registeredResponseHooks[Action.REQUEST_DELEGATE_TO] = this.afterReceiveDelegateResponse.selector; _registeredResponseHooks[Action.REQUEST_UNDELEGATE_FROM] = this.afterReceiveUndelegateResponse.selector; - _registeredResponseHooks[Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE] = - this.afterReceiveWithdrawRewardResponse.selector; + _registeredResponseHooks[Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE] = this + .afterReceiveWithdrawRewardResponse + .selector; bootstrapped = true; @@ -144,14 +155,16 @@ contract ClientChainGateway is function pause() external { require( - msg.sender == exocoreValidatorSetAddress, "ClientChainGateway: caller is not Exocore validator set aggregated address" + msg.sender == exocoreValidatorSetAddress, + "ClientChainGateway: caller is not Exocore validator set aggregated address" ); _pause(); } function unpause() external { require( - msg.sender == exocoreValidatorSetAddress, "ClientChainGateway: caller is not Exocore validator set aggregated address" + msg.sender == exocoreValidatorSetAddress, + "ClientChainGateway: caller is not Exocore validator set aggregated address" ); _unpause(); } @@ -170,7 +183,7 @@ contract ClientChainGateway is function removeWhitelistToken(address _token) external isTokenWhitelisted(_token) onlyOwner whenNotPaused { isWhitelistedToken[_token] = false; - for(uint i = 0; i < whitelistTokens.length; i++) { + for (uint i = 0; i < whitelistTokens.length; i++) { if (whitelistTokens[i] == _token) { whitelistTokens[i] = whitelistTokens[whitelistTokens.length - 1]; whitelistTokens.pop(); @@ -182,9 +195,10 @@ contract ClientChainGateway is } function quote(bytes memory _message) public view returns (uint256 nativeFee) { - bytes memory options = OptionsBuilder.newOptions().addExecutorLzReceiveOption( - DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE - ).addExecutorOrderedExecutionOption(); + bytes memory options = OptionsBuilder + .newOptions() + .addExecutorLzReceiveOption(DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE) + .addExecutorOrderedExecutionOption(); MessagingFee memory fee = _quote(exocoreChainId, _message, options, false); return fee.nativeFee; } diff --git a/src/core/ClientGatewayLzReceiver.sol b/src/core/ClientGatewayLzReceiver.sol index f25c4343..90cdaa91 100644 --- a/src/core/ClientGatewayLzReceiver.sol +++ b/src/core/ClientGatewayLzReceiver.sol @@ -13,7 +13,10 @@ abstract contract ClientGatewayLzReceiver is PausableUpgradeable, OAppReceiverUp error DepositShouldNotFailOnExocore(address token, address depositor); modifier onlyCalledFromThis() { - require(msg.sender == address(this), "ClientChainLzReceiver: could only be called from this contract itself with low level call"); + require( + msg.sender == address(this), + "ClientChainLzReceiver: could only be called from this contract itself with low level call" + ); _; } @@ -39,8 +42,9 @@ abstract contract ClientGatewayLzReceiver is PausableUpgradeable, OAppReceiverUp revert UnexpectedResponse(requestId); } - (bool success, bytes memory reason) = - address(this).call(abi.encodePacked(hookSelector, abi.encode(requestPayload, payload[9:]))); + (bool success, bytes memory reason) = address(this).call( + abi.encodePacked(hookSelector, abi.encode(requestPayload, payload[9:])) + ); if (!success) { revert RequestOrResponseExecuteFailed(act, _origin.nonce, reason); } @@ -53,21 +57,19 @@ abstract contract ClientGatewayLzReceiver is PausableUpgradeable, OAppReceiverUp revert UnsupportedRequest(act); } - (bool success, bytes memory reason) = - address(this).call(abi.encodePacked(selector_, abi.encode(payload[1:]))); + (bool success, bytes memory reason) = address(this).call( + abi.encodePacked(selector_, abi.encode(payload[1:])) + ); if (!success) { revert RequestOrResponseExecuteFailed(act, _origin.nonce, reason); } } } - function nextNonce(uint32 srcEid, bytes32 sender) - public - view - virtual - override(OAppReceiverUpgradeable) - returns (uint64) - { + function nextNonce( + uint32 srcEid, + bytes32 sender + ) public view virtual override(OAppReceiverUpgradeable) returns (uint64) { return inboundNonce[srcEid][sender] + 1; } @@ -78,10 +80,10 @@ abstract contract ClientGatewayLzReceiver is PausableUpgradeable, OAppReceiverUp } } - function afterReceiveDepositResponse(bytes memory requestPayload, bytes calldata responsePayload) - public - onlyCalledFromThis - { + function afterReceiveDepositResponse( + bytes memory requestPayload, + bytes calldata responsePayload + ) public onlyCalledFromThis { (address token, address depositor, uint256 amount) = abi.decode(requestPayload, (address, address, uint256)); bool success = (uint8(bytes1(responsePayload[0])) == 1); @@ -102,12 +104,14 @@ abstract contract ClientGatewayLzReceiver is PausableUpgradeable, OAppReceiverUp emit DepositResult(success, token, depositor, amount); } - function afterReceiveWithdrawPrincipleResponse(bytes memory requestPayload, bytes calldata responsePayload) - public - onlyCalledFromThis - { - (address token, address withdrawer, uint256 unlockPrincipleAmount) = - abi.decode(requestPayload, (address, address, uint256)); + function afterReceiveWithdrawPrincipleResponse( + bytes memory requestPayload, + bytes calldata responsePayload + ) public onlyCalledFromThis { + (address token, address withdrawer, uint256 unlockPrincipleAmount) = abi.decode( + requestPayload, + (address, address, uint256) + ); bool success = (uint8(bytes1(responsePayload[0])) == 1); uint256 lastlyUpdatedPrincipleBalance = uint256(bytes32(responsePayload[1:33])); @@ -121,12 +125,14 @@ abstract contract ClientGatewayLzReceiver is PausableUpgradeable, OAppReceiverUp emit WithdrawPrincipleResult(success, token, withdrawer, unlockPrincipleAmount); } - function afterReceiveWithdrawRewardResponse(bytes memory requestPayload, bytes calldata responsePayload) - public - onlyCalledFromThis - { - (address token, address withdrawer, uint256 unlockRewardAmount) = - abi.decode(requestPayload, (address, address, uint256)); + function afterReceiveWithdrawRewardResponse( + bytes memory requestPayload, + bytes calldata responsePayload + ) public onlyCalledFromThis { + (address token, address withdrawer, uint256 unlockRewardAmount) = abi.decode( + requestPayload, + (address, address, uint256) + ); bool success = (uint8(bytes1(responsePayload[0])) == 1); uint256 lastlyUpdatedRewardBalance = uint256(bytes32(responsePayload[1:33])); @@ -140,24 +146,28 @@ abstract contract ClientGatewayLzReceiver is PausableUpgradeable, OAppReceiverUp emit WithdrawRewardResult(success, token, withdrawer, unlockRewardAmount); } - function afterReceiveDelegateResponse(bytes memory requestPayload, bytes calldata responsePayload) - public - onlyCalledFromThis - { - (address token, string memory operator, address delegator, uint256 amount) = - abi.decode(requestPayload, (address, string, address, uint256)); + function afterReceiveDelegateResponse( + bytes memory requestPayload, + bytes calldata responsePayload + ) public onlyCalledFromThis { + (address token, string memory operator, address delegator, uint256 amount) = abi.decode( + requestPayload, + (address, string, address, uint256) + ); bool success = (uint8(bytes1(responsePayload[0])) == 1); emit DelegateResult(success, delegator, operator, token, amount); } - function afterReceiveUndelegateResponse(bytes memory requestPayload, bytes calldata responsePayload) - public - onlyCalledFromThis - { - (address token, string memory operator, address undelegator, uint256 amount) = - abi.decode(requestPayload, (address, string, address, uint256)); + function afterReceiveUndelegateResponse( + bytes memory requestPayload, + bytes calldata responsePayload + ) public onlyCalledFromThis { + (address token, string memory operator, address undelegator, uint256 amount) = abi.decode( + requestPayload, + (address, string, address, uint256) + ); bool success = (uint8(bytes1(responsePayload[0])) == 1); diff --git a/src/core/CustomProxyAdmin.sol b/src/core/CustomProxyAdmin.sol index 74b5f2ea..0e2c5b80 100644 --- a/src/core/CustomProxyAdmin.sol +++ b/src/core/CustomProxyAdmin.sol @@ -16,19 +16,10 @@ contract CustomProxyAdmin is Initializable, ProxyAdmin { bootstrapper = newBootstrapper; } - function changeImplementation( - address proxy, - address implementation, - bytes memory data - ) public virtual { - require( - msg.sender == bootstrapper, "CustomProxyAdmin: sender must be bootstrapper" - ); - require( - msg.sender == proxy, - "CustomProxyAdmin: sender must be the proxy itself" - ); + function changeImplementation(address proxy, address implementation, bytes memory data) public virtual { + require(msg.sender == bootstrapper, "CustomProxyAdmin: sender must be bootstrapper"); + require(msg.sender == proxy, "CustomProxyAdmin: sender must be the proxy itself"); ITransparentUpgradeableProxy(proxy).upgradeToAndCall(implementation, data); bootstrapper = address(0); } -} \ No newline at end of file +} diff --git a/src/core/ExoCapsule.sol b/src/core/ExoCapsule.sol index 8c749a00..d04de15b 100644 --- a/src/core/ExoCapsule.sol +++ b/src/core/ExoCapsule.sol @@ -11,11 +11,7 @@ import {WithdrawalContainer} from "../libraries/WithdrawalContainer.sol"; import {IBeaconChainOracle} from "@beacon-oracle/contracts/src/IBeaconChainOracle.sol"; import {Initializable} from "@openzeppelin-upgradeable/contracts/proxy/utils/Initializable.sol"; -contract ExoCapsule is - Initializable, - ExoCapsuleStorage, - IExoCapsule -{ +contract ExoCapsule is Initializable, ExoCapsuleStorage, IExoCapsule { using BeaconChainProofs for bytes32; using ValidatorContainer for bytes32[]; using WithdrawalContainer for bytes32[]; @@ -140,7 +136,7 @@ contract ExoCapsule is if (!validatorContainer.verifyValidatorContainerBasic()) { revert InvalidValidatorContainer(validatorPubkey); } - + if (!fullyWithdrawal) { revert NotPartialWithdrawal(validatorPubkey); } @@ -201,7 +197,7 @@ contract ExoCapsule is return root; } - function getRegisteredValidatorByPubkey(bytes32 pubkey) public view returns(Validator memory) { + function getRegisteredValidatorByPubkey(bytes32 pubkey) public view returns (Validator memory) { Validator memory validator = _capsuleValidators[pubkey]; if (validator.status == VALIDATOR_STATUS.UNREGISTERED) { revert UnregisteredValidator(pubkey); @@ -210,7 +206,7 @@ contract ExoCapsule is return validator; } - function getRegisteredValidatorByIndex(uint256 index) public view returns(Validator memory) { + function getRegisteredValidatorByIndex(uint256 index) public view returns (Validator memory) { Validator memory validator = _capsuleValidators[_capsuleValidatorsByIndex[index]]; if (validator.status == VALIDATOR_STATUS.UNREGISTERED) { revert UnregisteredValidator(_capsuleValidatorsByIndex[index]); @@ -219,7 +215,10 @@ contract ExoCapsule is return validator; } - function _verifyValidatorContainer(bytes32[] calldata validatorContainer, ValidatorContainerProof calldata proof) internal view { + function _verifyValidatorContainer( + bytes32[] calldata validatorContainer, + ValidatorContainerProof calldata proof + ) internal view { bytes32 beaconBlockRoot = getBeaconBlockRoot(proof.beaconBlockTimestamp); bytes32 validatorContainerRoot = validatorContainer.merklelizeValidatorContainer(); bool valid = validatorContainerRoot.isValidValidatorContainerRoot( @@ -234,7 +233,10 @@ contract ExoCapsule is } } - function _verifyWithdrawalContainer(bytes32[] calldata withdrawalContainer, WithdrawalContainerProof calldata proof) internal view { + function _verifyWithdrawalContainer( + bytes32[] calldata withdrawalContainer, + WithdrawalContainerProof calldata proof + ) internal view { bytes32 beaconBlockRoot = getBeaconBlockRoot(proof.beaconBlockTimestamp); bytes32 withdrawalContainerRoot = withdrawalContainer.merklelizeWithdrawalContainer(); bool valid = withdrawalContainerRoot.isValidWithdrawalContainerRoot( @@ -249,7 +251,10 @@ contract ExoCapsule is } } - function _isActivatedAtEpoch(bytes32[] calldata validatorContainer, uint256 atTimestamp) internal pure returns (bool) { + function _isActivatedAtEpoch( + bytes32[] calldata validatorContainer, + uint256 atTimestamp + ) internal pure returns (bool) { uint64 atEpoch = _timestampToEpoch(atTimestamp); uint64 activationEpoch = validatorContainer.getActivationEpoch(); uint64 exitEpoch = validatorContainer.getExitEpoch(); @@ -258,11 +263,15 @@ contract ExoCapsule is } function _isStaleProof(Validator storage validator, uint256 proofTimestamp) internal view returns (bool) { - return proofTimestamp + VERIFY_BALANCE_UPDATE_WINDOW_SECONDS < block.timestamp || proofTimestamp <= validator.mostRecentBalanceUpdateTimestamp; + return + proofTimestamp + VERIFY_BALANCE_UPDATE_WINDOW_SECONDS < block.timestamp || + proofTimestamp <= validator.mostRecentBalanceUpdateTimestamp; } function _hasFullyWithdrawn(bytes32[] calldata validatorContainer) internal view returns (bool) { - return validatorContainer.getWithdrawableEpoch() <= _timestampToEpoch(block.timestamp) && validatorContainer.getEffectiveBalance() == 0; + return + validatorContainer.getWithdrawableEpoch() <= _timestampToEpoch(block.timestamp) && + validatorContainer.getEffectiveBalance() == 0; } /** @@ -271,7 +280,10 @@ contract ExoCapsule is * reference: https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md */ function _timestampToEpoch(uint256 timestamp) internal pure returns (uint64) { - require(timestamp >= BEACON_CHAIN_GENESIS_TIME, "timestamp should be greater than beacon chain genesis timestamp"); + require( + timestamp >= BEACON_CHAIN_GENESIS_TIME, + "timestamp should be greater than beacon chain genesis timestamp" + ); return uint64((timestamp - BEACON_CHAIN_GENESIS_TIME) / BeaconChainProofs.SECONDS_PER_EPOCH); } } diff --git a/src/core/ExocoreGateway.sol b/src/core/ExocoreGateway.sol index 40e45094..1b3d7b12 100644 --- a/src/core/ExocoreGateway.sol +++ b/src/core/ExocoreGateway.sol @@ -7,13 +7,7 @@ import {WITHDRAW_CONTRACT, WITHDRAW_PRECOMPILE_ADDRESS} from "../interfaces/prec import {CLAIM_REWARD_CONTRACT, CLAIM_REWARD_PRECOMPILE_ADDRESS} from "../interfaces/precompiles/IClaimReward.sol"; import {DELEGATION_CONTRACT, DELEGATION_PRECOMPILE_ADDRESS} from "../interfaces/precompiles/IDelegation.sol"; import {CLIENT_CHAINS_CONTRACT, CLIENT_CHAINS_PRECOMPILE_ADDRESS} from "../interfaces/precompiles/IClientChains.sol"; -import { - OAppReceiverUpgradeable, - OAppUpgradeable, - Origin, - MessagingFee, - MessagingReceipt -} from "../lzApp/OAppUpgradeable.sol"; +import {OAppReceiverUpgradeable, OAppUpgradeable, Origin, MessagingFee, MessagingReceipt} from "../lzApp/OAppUpgradeable.sol"; import {Initializable} from "@openzeppelin-upgradeable/contracts/proxy/utils/Initializable.sol"; import {PausableUpgradeable} from "@openzeppelin-upgradeable/contracts/utils/PausableUpgradeable.sol"; @@ -33,7 +27,10 @@ contract ExocoreGateway is using OptionsBuilder for bytes; modifier onlyCalledFromThis() { - require(msg.sender == address(this), "ExocoreGateway: can only be called from this contract itself with low level call"); + require( + msg.sender == address(this), + "ExocoreGateway: can only be called from this contract itself with low level call" + ); _; } @@ -58,7 +55,9 @@ contract ExocoreGateway is _whiteListFunctionSelectors[Action.REQUEST_DEPOSIT] = this.requestDeposit.selector; _whiteListFunctionSelectors[Action.REQUEST_DELEGATE_TO] = this.requestDelegateTo.selector; _whiteListFunctionSelectors[Action.REQUEST_UNDELEGATE_FROM] = this.requestUndelegateFrom.selector; - _whiteListFunctionSelectors[Action.REQUEST_WITHDRAW_PRINCIPLE_FROM_EXOCORE] = this.requestWithdrawPrinciple.selector; + _whiteListFunctionSelectors[Action.REQUEST_WITHDRAW_PRINCIPLE_FROM_EXOCORE] = this + .requestWithdrawPrinciple + .selector; _whiteListFunctionSelectors[Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE] = this.requestWithdrawReward.selector; } @@ -67,8 +66,9 @@ contract ExocoreGateway is // For manual calls, this function should be called immediately after deployment and // then never needs to be called again. function markBootstrapOnAllChains() public { - (bool success, bytes memory result) = CLIENT_CHAINS_PRECOMPILE_ADDRESS. - staticcall(abi.encodeWithSelector(IClientChains.getClientChains.selector)); + (bool success, bytes memory result) = CLIENT_CHAINS_PRECOMPILE_ADDRESS.staticcall( + abi.encodeWithSelector(IClientChains.getClientChains.selector) + ); require(success, "ExocoreGateway: failed to get client chain ids"); // TODO: change to uint32[] when the precompile is upgraded (bool ok, uint16[] memory clientChainIds) = abi.decode(result, (bool, uint16[])); @@ -85,14 +85,16 @@ contract ExocoreGateway is function pause() external { require( - msg.sender == exocoreValidatorSetAddress, "ExocoreGateway: caller is not Exocore validator set aggregated address" + msg.sender == exocoreValidatorSetAddress, + "ExocoreGateway: caller is not Exocore validator set aggregated address" ); _pause(); } function unpause() external { require( - msg.sender == exocoreValidatorSetAddress, "ExocoreGateway: caller is not Exocore validator set aggregated address" + msg.sender == exocoreValidatorSetAddress, + "ExocoreGateway: caller is not Exocore validator set aggregated address" ); _unpause(); } @@ -106,8 +108,9 @@ contract ExocoreGateway is revert UnsupportedRequest(act); } - (bool success, bytes memory responseOrReason) = - address(this).call(abi.encodePacked(selector_, abi.encode(_origin.srcEid, _origin.nonce, payload[1:]))); + (bool success, bytes memory responseOrReason) = address(this).call( + abi.encodePacked(selector_, abi.encode(_origin.srcEid, _origin.nonce, payload[1:])) + ); if (!success) { revert RequestExecuteFailed(act, _origin.nonce, responseOrReason); } @@ -128,49 +131,53 @@ contract ExocoreGateway is _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success, updatedBalance)); } - function requestWithdrawPrinciple(uint32 srcChainId, uint64 lzNonce, bytes calldata payload) - public - onlyCalledFromThis - { - _validatePayloadLength(payload, WITHDRAW_PRINCIPLE_REQUEST_LENGTH, Action.REQUEST_WITHDRAW_PRINCIPLE_FROM_EXOCORE); + function requestWithdrawPrinciple( + uint32 srcChainId, + uint64 lzNonce, + bytes calldata payload + ) public onlyCalledFromThis { + _validatePayloadLength( + payload, + WITHDRAW_PRINCIPLE_REQUEST_LENGTH, + Action.REQUEST_WITHDRAW_PRINCIPLE_FROM_EXOCORE + ); bytes calldata token = payload[:32]; bytes calldata withdrawer = payload[32:64]; uint256 amount = uint256(bytes32(payload[64:96])); - try WITHDRAW_CONTRACT.withdrawPrinciple(srcChainId, token, withdrawer, amount) returns (bool success, uint256 updatedBalance) { - _sendInterchainMsg( - srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success, updatedBalance) - ); + try WITHDRAW_CONTRACT.withdrawPrinciple(srcChainId, token, withdrawer, amount) returns ( + bool success, + uint256 updatedBalance + ) { + _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success, updatedBalance)); } catch { emit ExocorePrecompileError(WITHDRAW_PRECOMPILE_ADDRESS, lzNonce); - _sendInterchainMsg( - srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false, uint256(0)) - ); + _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false, uint256(0))); } } - function requestWithdrawReward(uint32 srcChainId, uint64 lzNonce, bytes calldata payload) - public - onlyCalledFromThis - { + function requestWithdrawReward( + uint32 srcChainId, + uint64 lzNonce, + bytes calldata payload + ) public onlyCalledFromThis { _validatePayloadLength(payload, CLAIM_REWARD_REQUEST_LENGTH, Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE); bytes calldata token = payload[:32]; bytes calldata withdrawer = payload[32:64]; uint256 amount = uint256(bytes32(payload[64:96])); - try CLAIM_REWARD_CONTRACT.claimReward(srcChainId, token, withdrawer, amount) returns (bool success, uint256 updatedBalance) { - _sendInterchainMsg( - srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success, updatedBalance) - ); + try CLAIM_REWARD_CONTRACT.claimReward(srcChainId, token, withdrawer, amount) returns ( + bool success, + uint256 updatedBalance + ) { + _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success, updatedBalance)); } catch { emit ExocorePrecompileError(CLAIM_REWARD_PRECOMPILE_ADDRESS, lzNonce); - _sendInterchainMsg( - srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false, uint256(0)) - ); + _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false, uint256(0))); } } @@ -182,23 +189,22 @@ contract ExocoreGateway is bytes calldata operator = payload[64:106]; uint256 amount = uint256(bytes32(payload[106:138])); - try DELEGATION_CONTRACT.delegateToThroughClientChain(srcChainId, lzNonce, token, delegator, operator, amount) returns (bool success) { - _sendInterchainMsg( - srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success) - ); + try + DELEGATION_CONTRACT.delegateToThroughClientChain(srcChainId, lzNonce, token, delegator, operator, amount) + returns (bool success) { + _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success)); } catch { emit ExocorePrecompileError(DELEGATION_PRECOMPILE_ADDRESS, lzNonce); - _sendInterchainMsg( - srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false) - ); + _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false)); } } - function requestUndelegateFrom(uint32 srcChainId, uint64 lzNonce, bytes calldata payload) - public - onlyCalledFromThis - { + function requestUndelegateFrom( + uint32 srcChainId, + uint64 lzNonce, + bytes calldata payload + ) public onlyCalledFromThis { _validatePayloadLength(payload, UNDELEGATE_REQUEST_LENGTH, Action.REQUEST_UNDELEGATE_FROM); bytes memory token = payload[:32]; @@ -206,16 +212,21 @@ contract ExocoreGateway is bytes memory operator = payload[64:106]; uint256 amount = uint256(bytes32(payload[106:138])); - try DELEGATION_CONTRACT.undelegateFromThroughClientChain(srcChainId, lzNonce, token, delegator, operator, amount) returns (bool success) { - _sendInterchainMsg( - srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success) - ); + try + DELEGATION_CONTRACT.undelegateFromThroughClientChain( + srcChainId, + lzNonce, + token, + delegator, + operator, + amount + ) + returns (bool success) { + _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success)); } catch { emit ExocorePrecompileError(DELEGATION_PRECOMPILE_ADDRESS, lzNonce); - _sendInterchainMsg( - srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false) - ); + _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false)); } } @@ -227,31 +238,36 @@ contract ExocoreGateway is function _sendInterchainMsg(uint32 srcChainId, Action act, bytes memory actionArgs) internal whenNotPaused { bytes memory payload = abi.encodePacked(act, actionArgs); - bytes memory options = OptionsBuilder.newOptions().addExecutorLzReceiveOption( - DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE - ).addExecutorOrderedExecutionOption(); + bytes memory options = OptionsBuilder + .newOptions() + .addExecutorLzReceiveOption(DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE) + .addExecutorOrderedExecutionOption(); MessagingFee memory fee = _quote(srcChainId, payload, options, false); - MessagingReceipt memory receipt = - _lzSend(srcChainId, payload, options, MessagingFee(fee.nativeFee, 0), exocoreValidatorSetAddress, true); + MessagingReceipt memory receipt = _lzSend( + srcChainId, + payload, + options, + MessagingFee(fee.nativeFee, 0), + exocoreValidatorSetAddress, + true + ); emit MessageSent(act, receipt.guid, receipt.nonce, receipt.fee.nativeFee); } function quote(uint32 srcChainid, bytes memory _message) public view returns (uint256 nativeFee) { - bytes memory options = OptionsBuilder.newOptions().addExecutorLzReceiveOption( - DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE - ).addExecutorOrderedExecutionOption(); + bytes memory options = OptionsBuilder + .newOptions() + .addExecutorLzReceiveOption(DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE) + .addExecutorOrderedExecutionOption(); MessagingFee memory fee = _quote(srcChainid, _message, options, false); return fee.nativeFee; } - function nextNonce(uint32 srcEid, bytes32 sender) - public - view - virtual - override(ILayerZeroReceiver, OAppReceiverUpgradeable) - returns (uint64) - { + function nextNonce( + uint32 srcEid, + bytes32 sender + ) public view virtual override(ILayerZeroReceiver, OAppReceiverUpgradeable) returns (uint64) { return inboundNonce[srcEid][sender] + 1; } @@ -261,4 +277,4 @@ contract ExocoreGateway is revert UnexpectedInboundNonce(inboundNonce[srcEid][sender], nonce); } } -} \ No newline at end of file +} diff --git a/src/core/LSTRestakingController.sol b/src/core/LSTRestakingController.sol index 3d5f39ed..1e801ef1 100644 --- a/src/core/LSTRestakingController.sol +++ b/src/core/LSTRestakingController.sol @@ -7,20 +7,25 @@ import {BaseRestakingController} from "./BaseRestakingController.sol"; import {PausableUpgradeable} from "@openzeppelin-upgradeable/contracts/utils/PausableUpgradeable.sol"; -abstract contract LSTRestakingController is - PausableUpgradeable, - ILSTRestakingController, - BaseRestakingController -{ - function deposit(address token, uint256 amount) external payable isTokenWhitelisted(token) isValidAmount(amount) whenNotPaused { - _processRequest(token, msg.sender, amount, Action.REQUEST_DEPOSIT,""); +abstract contract LSTRestakingController is PausableUpgradeable, ILSTRestakingController, BaseRestakingController { + function deposit( + address token, + uint256 amount + ) external payable isTokenWhitelisted(token) isValidAmount(amount) whenNotPaused { + _processRequest(token, msg.sender, amount, Action.REQUEST_DEPOSIT, ""); } - function withdrawPrincipleFromExocore(address token, uint256 principleAmount) external payable isTokenWhitelisted(token) isValidAmount(principleAmount) whenNotPaused { - _processRequest(token, msg.sender, principleAmount, Action.REQUEST_WITHDRAW_PRINCIPLE_FROM_EXOCORE,""); + function withdrawPrincipleFromExocore( + address token, + uint256 principleAmount + ) external payable isTokenWhitelisted(token) isValidAmount(principleAmount) whenNotPaused { + _processRequest(token, msg.sender, principleAmount, Action.REQUEST_WITHDRAW_PRINCIPLE_FROM_EXOCORE, ""); } - function withdrawRewardFromExocore(address token, uint256 rewardAmount) external payable isTokenWhitelisted(token) isValidAmount(rewardAmount) whenNotPaused { - _processRequest(token, msg.sender, rewardAmount, Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE,""); + function withdrawRewardFromExocore( + address token, + uint256 rewardAmount + ) external payable isTokenWhitelisted(token) isValidAmount(rewardAmount) whenNotPaused { + _processRequest(token, msg.sender, rewardAmount, Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE, ""); } } diff --git a/src/core/NativeRestakingController.sol b/src/core/NativeRestakingController.sol index 245d709d..b4f6a085 100644 --- a/src/core/NativeRestakingController.sol +++ b/src/core/NativeRestakingController.sol @@ -16,7 +16,11 @@ abstract contract NativeRestakingController is { using ValidatorContainer for bytes32[]; - function stake(bytes calldata pubkey, bytes calldata signature, bytes32 depositDataRoot) external payable whenNotPaused { + function stake( + bytes calldata pubkey, + bytes calldata signature, + bytes32 depositDataRoot + ) external payable whenNotPaused { require(msg.value == 32 ether, "NativeRestakingController: stake value must be exactly 32 ether"); IExoCapsule capsule = ownerToCapsule[msg.sender]; @@ -29,7 +33,10 @@ abstract contract NativeRestakingController is } function createExoCapsule() public whenNotPaused returns (address) { - require(address(ownerToCapsule[msg.sender]) == address(0), "NativeRestakingController: message sender has already created the capsule"); + require( + address(ownerToCapsule[msg.sender]) == address(0), + "NativeRestakingController: message sender has already created the capsule" + ); ExoCapsule capsule = ExoCapsule( Create2.deploy( 0, @@ -55,8 +62,6 @@ abstract contract NativeRestakingController is uint256 depositValue = uint256(validatorContainer.getEffectiveBalance()) * GWEI_TO_WEI; _processRequest(VIRTUAL_STAKED_ETH_ADDRESS, msg.sender, depositValue, Action.REQUEST_DEPOSIT, ""); - - } function processBeaconChainPartialWithdrawal( @@ -64,16 +69,12 @@ abstract contract NativeRestakingController is IExoCapsule.ValidatorContainerProof calldata validatorProof, bytes32[] calldata withdrawalContainer, IExoCapsule.WithdrawalContainerProof calldata withdrawalProof - ) external payable whenNotPaused { - - } + ) external payable whenNotPaused {} function processBeaconChainFullWithdrawal( bytes32[] calldata validatorContainer, IExoCapsule.ValidatorContainerProof calldata validatorProof, bytes32[] calldata withdrawalContainer, IExoCapsule.WithdrawalContainerProof calldata withdrawalProof - ) external payable whenNotPaused { - - } + ) external payable whenNotPaused {} } diff --git a/src/core/Vault.sol b/src/core/Vault.sol index 067ede9f..df5fcac8 100644 --- a/src/core/Vault.sol +++ b/src/core/Vault.sol @@ -22,7 +22,7 @@ contract Vault is Initializable, VaultStorage, IVault { function initialize(address underlyingToken_, address gateway_) external initializer { require(underlyingToken_ != address(0), "Vault: underlying token can not be empty"); - require(gateway_!= address(0), "VaultStorage: the gateway address should not be empty"); + require(gateway_ != address(0), "VaultStorage: the gateway address should not be empty"); underlyingToken = IERC20(underlyingToken_); gateway = ILSTRestakingController(gateway_); @@ -65,10 +65,11 @@ contract Vault is Initializable, VaultStorage, IVault { emit RewardBalanceUpdated(user, lastlyUpdatedRewardBalance); } - function updateWithdrawableBalance(address user, uint256 unlockPrincipleAmount, uint256 unlockRewardAmount) - external - onlyGateway - { + function updateWithdrawableBalance( + address user, + uint256 unlockPrincipleAmount, + uint256 unlockRewardAmount + ) external onlyGateway { uint256 totalDeposited = totalDepositedPrincipleAmount[user]; require( unlockPrincipleAmount <= totalDeposited, diff --git a/src/interfaces/IClientChainGateway.sol b/src/interfaces/IClientChainGateway.sol index 65af359f..9547f828 100644 --- a/src/interfaces/IClientChainGateway.sol +++ b/src/interfaces/IClientChainGateway.sol @@ -6,6 +6,12 @@ import {ILSTRestakingController} from "./ILSTRestakingController.sol"; import {INativeRestakingController} from "../interfaces/INativeRestakingController.sol"; import {ITokenWhitelister} from "../interfaces/ITokenWhitelister.sol"; -interface IClientChainGateway is ITokenWhitelister, IOAppReceiver, IOAppCore, ILSTRestakingController, INativeRestakingController { +interface IClientChainGateway is + ITokenWhitelister, + IOAppReceiver, + IOAppCore, + ILSTRestakingController, + INativeRestakingController +{ function quote(bytes memory _message) external view returns (uint256 nativeFee); } diff --git a/src/interfaces/ICustomProxyAdmin.sol b/src/interfaces/ICustomProxyAdmin.sol index b8b1109d..701f64ca 100644 --- a/src/interfaces/ICustomProxyAdmin.sol +++ b/src/interfaces/ICustomProxyAdmin.sol @@ -8,4 +8,4 @@ interface ICustomProxyAdmin { address implementation, bytes memory data ) external payable; -} \ No newline at end of file +} diff --git a/src/interfaces/IExoCapsule.sol b/src/interfaces/IExoCapsule.sol index 608b08b1..7c058e29 100644 --- a/src/interfaces/IExoCapsule.sol +++ b/src/interfaces/IExoCapsule.sol @@ -18,10 +18,7 @@ interface IExoCapsule { uint256 withdrawalIndex; } - function verifyDepositProof( - bytes32[] calldata validatorContainer, - ValidatorContainerProof calldata proof - ) external; + function verifyDepositProof(bytes32[] calldata validatorContainer, ValidatorContainerProof calldata proof) external; function verifyPartialWithdrawalProof( bytes32[] calldata validatorContainer, @@ -44,4 +41,4 @@ interface IExoCapsule { function updateWithdrawableBalance(uint256 unlockPrincipleAmount) external; function capsuleWithdrawalCredentials() external view returns (bytes memory); -} \ No newline at end of file +} diff --git a/src/interfaces/INativeRestakingController.sol b/src/interfaces/INativeRestakingController.sol index 709d585a..6197061d 100644 --- a/src/interfaces/INativeRestakingController.sol +++ b/src/interfaces/INativeRestakingController.sol @@ -7,11 +7,11 @@ interface INativeRestakingController is IBaseRestakingController { /// *** function signatures for staker operations *** /** - * @notice Stakers call this function to deposit to beacon chain validator, and point withdrawal_credentials of + * @notice Stakers call this function to deposit to beacon chain validator, and point withdrawal_credentials of * beacon chain validator to staker's ExoCapsule contract address. An ExoCapsule contract owned by staker would * be created if it does not exist. * @param pubkey the BLS pubkey of beacon chain validator - * @param signature the BLS signature + * @param signature the BLS signature * @param depositDataRoot The SHA-256 hash of the SSZ-encoded DepositData object. * Used as a protection against malformed input. */ @@ -26,13 +26,16 @@ interface INativeRestakingController is IBaseRestakingController { * @notice This is called to deposit ETH that is staked on Ethereum beacon chain to Exocore network to be restaked in future * @dev Before deposit, staker should have created the ExoCapsule that it owns and point the validator's withdrawal crendentials * to the ExoCapsule owned by staker. The effective balance of `validatorContainer` would be credited as deposited value by Exocore network. - * @ param + * @ param */ - function depositBeaconChainValidator(bytes32[] calldata validatorContainer, IExoCapsule.ValidatorContainerProof calldata proof) payable external; + function depositBeaconChainValidator( + bytes32[] calldata validatorContainer, + IExoCapsule.ValidatorContainerProof calldata proof + ) external payable; /** - * @notice When a beacon chain partial withdrawal to an ExoCapsule contract happens(the withdrawal time is less than validator's withdrawable_epoch), - * this function could be called with `validatorContainer`, `withdrawalContainer` and corresponding proofs to prove this partial withdrawal + * @notice When a beacon chain partial withdrawal to an ExoCapsule contract happens(the withdrawal time is less than validator's withdrawable_epoch), + * this function could be called with `validatorContainer`, `withdrawalContainer` and corresponding proofs to prove this partial withdrawal * from beacon chain is done and unlock withdrawn ETH to be claimable for ExoCapsule owner. * @param validatorContainer is the data structure included in `BeaconState` of `BeaconBlock` that contains beacon chain validator information, * refer to: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator @@ -47,11 +50,11 @@ interface INativeRestakingController is IBaseRestakingController { IExoCapsule.ValidatorContainerProof calldata validatorProof, bytes32[] calldata withdrawalContainer, IExoCapsule.WithdrawalContainerProof calldata withdrawalProof - ) payable external; + ) external payable; /** - * @notice When a beacon chain full withdrawal to this capsule contract happens(the withdrawal time is euqal to or greater than - * validator's withdrawable_epoch), this function could be called with `validatorContainer`, `withdrawalContainer` and corresponding + * @notice When a beacon chain full withdrawal to this capsule contract happens(the withdrawal time is euqal to or greater than + * validator's withdrawable_epoch), this function could be called with `validatorContainer`, `withdrawalContainer` and corresponding * proofs to prove this full withdrawal from beacon chain is done, send withdrawal request to Exocore network to be processed. * After Exocore network finishs dealing with withdrawal request and sending back the response, ExoCapsule would unlock corresponding ETH * in response to be cliamable for ExoCapsule owner. @@ -68,5 +71,5 @@ interface INativeRestakingController is IBaseRestakingController { IExoCapsule.ValidatorContainerProof calldata validatorProof, bytes32[] calldata withdrawalContainer, IExoCapsule.WithdrawalContainerProof calldata withdrawalProof - ) payable external; + ) external payable; } diff --git a/src/interfaces/IOperatorRegistry.sol b/src/interfaces/IOperatorRegistry.sol index a241ddf2..8ea76301 100644 --- a/src/interfaces/IOperatorRegistry.sol +++ b/src/interfaces/IOperatorRegistry.sol @@ -9,7 +9,7 @@ interface IOperatorRegistry { * All rates must be less than or equal to 1e18. * For example, a 10% commission rate would be represented as 1e17. * rate must not exceed maxRate, and maxChangeRate must not exceed maxRate. - */ + */ struct Commission { uint256 rate; uint256 maxRate; @@ -50,9 +50,7 @@ interface IOperatorRegistry { * @dev Updates the consensus public key for the operator corresponding to `msg.sender`. * @param newKey The new public key to use for consensus operations. */ - function replaceKey( - bytes32 newKey - ) external; + function replaceKey(bytes32 newKey) external; /** * @notice Updates the commission rate for the calling operator. @@ -62,9 +60,7 @@ interface IOperatorRegistry { * @param newRate The new commission rate to be set for the calling operator. * Must not exceed the operator's maximum rate. */ - function updateRate( - uint256 newRate - ) external; + function updateRate(uint256 newRate) external; /** * @dev Emitted when a new operator is registered in the contract. @@ -87,14 +83,11 @@ interface IOperatorRegistry { * @param operatorExocoreAddress The Exocore address of the operator. * @param newConsensusPublicKey The new consensus key for the operator. */ - event OperatorKeyReplaced( - string operatorExocoreAddress, - bytes32 newConsensusPublicKey - ); + event OperatorKeyReplaced(string operatorExocoreAddress, bytes32 newConsensusPublicKey); /** * @dev Emitted when an operator's commission rate is updated. * @param newRate The new commission rate for the operator. */ event OperatorCommissionUpdated(uint256 newRate); -} \ No newline at end of file +} diff --git a/src/interfaces/ITokenWhitelister.sol b/src/interfaces/ITokenWhitelister.sol index 576faa4d..fa3c2880 100644 --- a/src/interfaces/ITokenWhitelister.sol +++ b/src/interfaces/ITokenWhitelister.sol @@ -20,4 +20,4 @@ interface ITokenWhitelister { * @dev Indicates an operation was attempted with a token that is not authorized. */ error UnauthorizedToken(); -} \ No newline at end of file +} diff --git a/src/interfaces/IVault.sol b/src/interfaces/IVault.sol index 4f2a9f59..1ccb3bec 100644 --- a/src/interfaces/IVault.sol +++ b/src/interfaces/IVault.sol @@ -9,8 +9,11 @@ interface IVault { function updateRewardBalance(address user, uint256 lastlyUpdatedRewardBalance) external; - function updateWithdrawableBalance(address user, uint256 unlockPrincipleAmount, uint256 unlockRewardAmount) - external; + function updateWithdrawableBalance( + address user, + uint256 unlockPrincipleAmount, + uint256 unlockRewardAmount + ) external; function getUnderlyingToken() external returns (address); } diff --git a/src/interfaces/precompiles/IClientChains.sol b/src/interfaces/precompiles/IClientChains.sol index e687ff06..03ff0da1 100644 --- a/src/interfaces/precompiles/IClientChains.sol +++ b/src/interfaces/precompiles/IClientChains.sol @@ -4,9 +4,7 @@ pragma solidity >=0.8.17; address constant CLIENT_CHAINS_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000801; /// @dev The CLIENT_CHAINS contract's instance. -IClientChains constant CLIENT_CHAINS_CONTRACT = IClientChains( - CLIENT_CHAINS_PRECOMPILE_ADDRESS -); +IClientChains constant CLIENT_CHAINS_CONTRACT = IClientChains(CLIENT_CHAINS_PRECOMPILE_ADDRESS); /// @author Exocore Team /// @title Client Chains Precompile Contract @@ -16,4 +14,3 @@ interface IClientChains { /// @dev Returns the chain indices of the client chains. function getClientChains() external view returns (bool, uint16[] memory); } - diff --git a/src/interfaces/precompiles/IDeposit.sol b/src/interfaces/precompiles/IDeposit.sol index cb52648b..b8e8ac15 100644 --- a/src/interfaces/precompiles/IDeposit.sol +++ b/src/interfaces/precompiles/IDeposit.sol @@ -19,7 +19,10 @@ interface IDeposit { /// @param AssetsAddress The client chain asset Address /// @param StakerAddress The staker address /// @param OpAmount The deposit amount - function depositTo(uint32 ClientChainLzId, bytes memory AssetsAddress, bytes memory StakerAddress, uint256 OpAmount) - external - returns (bool success, uint256 latestAssetState); + function depositTo( + uint32 ClientChainLzId, + bytes memory AssetsAddress, + bytes memory StakerAddress, + uint256 OpAmount + ) external returns (bool success, uint256 latestAssetState); } diff --git a/src/libraries/BeaconChainProofs.sol b/src/libraries/BeaconChainProofs.sol index 8f570165..43506b09 100644 --- a/src/libraries/BeaconChainProofs.sol +++ b/src/libraries/BeaconChainProofs.sol @@ -103,7 +103,7 @@ library BeaconChainProofs { /// @notice The number of seconds in a slot in the beacon chain uint64 internal constant SECONDS_PER_SLOT = 12; - /// @notice Number of seconds per epoch: 384 == 32 slots/epoch * 12 seconds/slot + /// @notice Number of seconds per epoch: 384 == 32 slots/epoch * 12 seconds/slot uint64 internal constant SECONDS_PER_EPOCH = SLOTS_PER_EPOCH * SECONDS_PER_SLOT; bytes8 internal constant UINT64_MASK = 0xffffffffffffffff; @@ -139,7 +139,12 @@ library BeaconChainProofs { bytes32[] calldata stateRootProof ) internal view returns (bool valid) { bool validStateRoot = isValidStateRoot(stateRoot, beaconBlockRoot, stateRootProof); - bool validVCRootAgainstStateRoot = isValidVCRootAgainstStateRoot(validatorContainerRoot, stateRoot, validatorContainerRootProof, validatorIndex); + bool validVCRootAgainstStateRoot = isValidVCRootAgainstStateRoot( + validatorContainerRoot, + stateRoot, + validatorContainerRootProof, + validatorIndex + ); if (validStateRoot && validVCRootAgainstStateRoot) { valid = true; } @@ -150,17 +155,15 @@ library BeaconChainProofs { bytes32 beaconBlockRoot, bytes32[] calldata stateRootProof ) internal view returns (bool) { - require( - stateRootProof.length == BEACON_BLOCK_HEADER_FIELD_TREE_HEIGHT, - "state root proof should have 3 nodes" - ); - - return Merkle.verifyInclusionSha256({ - proof: stateRootProof, - root: beaconBlockRoot, - leaf: stateRoot, - index: STATE_ROOT_INDEX - }); + require(stateRootProof.length == BEACON_BLOCK_HEADER_FIELD_TREE_HEIGHT, "state root proof should have 3 nodes"); + + return + Merkle.verifyInclusionSha256({ + proof: stateRootProof, + root: beaconBlockRoot, + leaf: stateRoot, + index: STATE_ROOT_INDEX + }); } function isValidVCRootAgainstStateRoot( @@ -176,12 +179,13 @@ library BeaconChainProofs { uint256 leafIndex = (VALIDATOR_TREE_ROOT_INDEX << (VALIDATOR_TREE_HEIGHT + 1)) | uint256(validatorIndex); - return Merkle.verifyInclusionSha256({ - proof: validatorContainerRootProof, - root: stateRoot, - leaf: validatorContainerRoot, - index: leafIndex - }); + return + Merkle.verifyInclusionSha256({ + proof: validatorContainerRootProof, + root: stateRoot, + leaf: validatorContainerRoot, + index: leafIndex + }); } function isValidWithdrawalContainerRoot( @@ -192,11 +196,15 @@ library BeaconChainProofs { bytes32 executionPayloadRoot, bytes32[] calldata executionPayloadRootProof ) internal view returns (bool valid) { - bool validExecutionPayloadRoot = isValidExecutionPayloadRoot(executionPayloadRoot, beaconBlockRoot, executionPayloadRootProof); + bool validExecutionPayloadRoot = isValidExecutionPayloadRoot( + executionPayloadRoot, + beaconBlockRoot, + executionPayloadRootProof + ); bool validWCRootAgainstExecutionPayloadRoot = isValidWCRootAgainstExecutionPayloadRoot( - withdrawalContainerRoot, - executionPayloadRoot, - withdrawalContainerRootProof, + withdrawalContainerRoot, + executionPayloadRoot, + withdrawalContainerRootProof, withdrawalIndex ); if (validExecutionPayloadRoot && validWCRootAgainstExecutionPayloadRoot) { @@ -210,19 +218,20 @@ library BeaconChainProofs { bytes32[] calldata executionPayloadRootProof ) internal view returns (bool) { require( - executionPayloadRootProof.length == BEACON_BLOCK_HEADER_FIELD_TREE_HEIGHT + BEACON_BLOCK_BODY_FIELD_TREE_HEIGHT, + executionPayloadRootProof.length == + BEACON_BLOCK_HEADER_FIELD_TREE_HEIGHT + BEACON_BLOCK_BODY_FIELD_TREE_HEIGHT, "state root proof should have 3 nodes" ); - uint256 leafIndex = (BODY_ROOT_INDEX << (BEACON_BLOCK_BODY_FIELD_TREE_HEIGHT)) | - EXECUTION_PAYLOAD_INDEX; + uint256 leafIndex = (BODY_ROOT_INDEX << (BEACON_BLOCK_BODY_FIELD_TREE_HEIGHT)) | EXECUTION_PAYLOAD_INDEX; - return Merkle.verifyInclusionSha256({ - proof: executionPayloadRootProof, - root: beaconBlockRoot, - leaf: executionPayloadRoot, - index: leafIndex - }); + return + Merkle.verifyInclusionSha256({ + proof: executionPayloadRootProof, + root: beaconBlockRoot, + leaf: executionPayloadRoot, + index: leafIndex + }); } function isValidWCRootAgainstExecutionPayloadRoot( @@ -236,14 +245,14 @@ library BeaconChainProofs { "validator container root proof should have 46 nodes" ); - uint256 leafIndex = (WITHDRAWALS_INDEX << (WITHDRAWALS_TREE_HEIGHT + 1)) | - uint256(withdrawalIndex); + uint256 leafIndex = (WITHDRAWALS_INDEX << (WITHDRAWALS_TREE_HEIGHT + 1)) | uint256(withdrawalIndex); - return Merkle.verifyInclusionSha256({ - proof: withdrawalContainerRootProof, - root: executionPayloadRoot, - leaf: withdrawalContainerRoot, - index: leafIndex - }); + return + Merkle.verifyInclusionSha256({ + proof: withdrawalContainerRootProof, + root: executionPayloadRoot, + leaf: withdrawalContainerRoot, + index: leafIndex + }); } } diff --git a/src/libraries/ValidatorContainer.sol b/src/libraries/ValidatorContainer.sol index 7cf0750d..68efb398 100644 --- a/src/libraries/ValidatorContainer.sol +++ b/src/libraries/ValidatorContainer.sol @@ -19,7 +19,7 @@ library ValidatorContainer { uint256 internal constant VALID_LENGTH = 8; uint256 internal constant MERKLE_TREE_HEIGHT = 3; - + function verifyValidatorContainerBasic(bytes32[] calldata validatorContainer) internal pure returns (bool) { return validatorContainer.length == VALID_LENGTH; } @@ -64,4 +64,4 @@ library ValidatorContainer { return leaves[0]; } -} \ No newline at end of file +} diff --git a/src/libraries/WithdrawalContainer.sol b/src/libraries/WithdrawalContainer.sol index a5254671..e5f019a2 100644 --- a/src/libraries/WithdrawalContainer.sol +++ b/src/libraries/WithdrawalContainer.sol @@ -14,7 +14,7 @@ library WithdrawalContainer { uint256 internal constant VALID_LENGTH = 4; uint256 internal constant MERKLE_TREE_HEIGHT = 2; - + function verifyWithdrawalContainerBasic(bytes32[] calldata withdrawalContainer) internal pure returns (bool) { return withdrawalContainer.length == VALID_LENGTH; } @@ -47,4 +47,4 @@ library WithdrawalContainer { return leaves[0]; } -} \ No newline at end of file +} diff --git a/src/lzApp/OAppReceiverUpgradeable.sol b/src/lzApp/OAppReceiverUpgradeable.sol index 5eb4ef72..817964db 100644 --- a/src/lzApp/OAppReceiverUpgradeable.sol +++ b/src/lzApp/OAppReceiverUpgradeable.sol @@ -65,7 +65,7 @@ abstract contract OAppReceiverUpgradeable is IOAppReceiver, OAppCoreUpgradeable * @dev This is also enforced by the OApp. * @dev By default this is NOT enabled. ie. nextNonce is hardcoded to return 0. */ - function nextNonce(uint32, /*_srcEid*/ bytes32 /*_sender*/ ) public view virtual returns (uint64 nonce) { + function nextNonce(uint32, /*_srcEid*/ bytes32 /*_sender*/) public view virtual returns (uint64 nonce) { return 0; } diff --git a/src/lzApp/OAppSenderUpgradeable.sol b/src/lzApp/OAppSenderUpgradeable.sol index 54b9f12e..3bbfa44f 100644 --- a/src/lzApp/OAppSenderUpgradeable.sol +++ b/src/lzApp/OAppSenderUpgradeable.sol @@ -3,11 +3,7 @@ pragma solidity ^0.8.20; import {SafeERC20, IERC20} from "@openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; -import { - MessagingParams, - MessagingFee, - MessagingReceipt -} from "@layerzero-v2/protocol/contracts/interfaces/ILayerZeroEndpointV2.sol"; +import {MessagingParams, MessagingFee, MessagingReceipt} from "@layerzero-v2/protocol/contracts/interfaces/ILayerZeroEndpointV2.sol"; import {OAppCoreUpgradeable} from "./OAppCoreUpgradeable.sol"; /** @@ -48,15 +44,17 @@ abstract contract OAppSenderUpgradeable is OAppCoreUpgradeable { * - nativeFee: The native fee for the message. * - lzTokenFee: The LZ token fee for the message. */ - function _quote(uint32 _dstEid, bytes memory _message, bytes memory _options, bool _payInLzToken) - internal - view - virtual - returns (MessagingFee memory fee) - { - return endpoint.quote( - MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _payInLzToken), address(this) - ); + function _quote( + uint32 _dstEid, + bytes memory _message, + bytes memory _options, + bool _payInLzToken + ) internal view virtual returns (MessagingFee memory fee) { + return + endpoint.quote( + MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _payInLzToken), + address(this) + ); } /** @@ -87,11 +85,12 @@ abstract contract OAppSenderUpgradeable is OAppCoreUpgradeable { uint256 messageValue = _payNative(_fee.nativeFee, byApp); if (_fee.lzTokenFee > 0) _payLzToken(_fee.lzTokenFee); - return endpoint + return + endpoint.send{value: messageValue}( // solhint-disable-next-line check-send-result - .send{value: messageValue}( - MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _fee.lzTokenFee > 0), _refundAddress - ); + MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _fee.lzTokenFee > 0), + _refundAddress + ); } /** diff --git a/src/storage/BootstrapStorage.sol b/src/storage/BootstrapStorage.sol index fb1328f4..8c967817 100644 --- a/src/storage/BootstrapStorage.sol +++ b/src/storage/BootstrapStorage.sol @@ -58,7 +58,7 @@ contract BootstrapStorage is GatewayStorage { * The system used is a delegated POS system, where the vote power of each operator * is determined by the total amount of tokens delegated to them across all supported * tokens. - */ + */ address[] public registeredOperators; /** @@ -70,7 +70,7 @@ contract BootstrapStorage is GatewayStorage { mapping(address ethAddress => string exoAddress) public ethToExocoreAddress; /** - * @dev Maps Exocore addresses to their corresponding operator details stored in an + * @dev Maps Exocore addresses to their corresponding operator details stored in an * Operator` struct. * @notice Use this mapping to access or modify operator details associated with a specific * Exocore address. @@ -95,8 +95,7 @@ contract BootstrapStorage is GatewayStorage { */ // delegationsByOperator means it is indexed by operator address and not that is is // a delegation made by the operator. - mapping(string exoAddress => mapping(address tokenAddress => uint256 amount)) public - delegationsByOperator; + mapping(string exoAddress => mapping(address tokenAddress => uint256 amount)) public delegationsByOperator; // depositor and delegation information /** @@ -119,8 +118,7 @@ contract BootstrapStorage is GatewayStorage { * @notice This mapping is used to keep track of the total deposits made by each account * for each token. */ - mapping(address depositor => mapping(address tokenAddress => uint256 amount)) public - totalDepositAmounts; + mapping(address depositor => mapping(address tokenAddress => uint256 amount)) public totalDepositAmounts; /** * @dev Maps depositor addresses to another mapping, where the key is an token address and @@ -129,8 +127,7 @@ contract BootstrapStorage is GatewayStorage { * token. The amount available for withdrawal is the total deposited amount minus the * amount already delegated. */ - mapping(address depositor => mapping(address tokenAddress => uint256 amount)) public - withdrawableAmounts; + mapping(address depositor => mapping(address tokenAddress => uint256 amount)) public withdrawableAmounts; /** * @dev Maps a delegator address to a nested mapping, where the first key the operator @@ -139,13 +136,8 @@ contract BootstrapStorage is GatewayStorage { * @notice This allows tracking of how much each delegator has delegated to each operator * for all of the whitelisted tokens. */ - mapping( - address delegator => mapping( - string exoAddress => mapping( - address tokenAddress => uint256 - ) - ) - ) public delegations; + mapping(address delegator => mapping(string exoAddress => mapping(address tokenAddress => uint256))) + public delegations; // bootstrapping information - including status, address of proxy, implementation, and // initialization @@ -230,7 +222,7 @@ contract BootstrapStorage is GatewayStorage { // the beacon that stores the Vault implementation contract address for proxy /** - * @notice this stores the Vault implementation contract address for proxy, and it is + * @notice this stores the Vault implementation contract address for proxy, and it is * shsared among all beacon proxies as an immutable. */ IBeacon public immutable vaultBeacon; @@ -282,9 +274,7 @@ contract BootstrapStorage is GatewayStorage { * @param depositor The address of the depositor, on this chain. * @param amount The amount of the token accepted as deposit. */ - event DepositResult( - bool indexed success, address indexed token, address indexed depositor, uint256 amount - ); + event DepositResult(bool indexed success, address indexed token, address indexed depositor, uint256 amount); /** * @notice Emitted when a withdrawal is made from the contract. @@ -295,7 +285,10 @@ contract BootstrapStorage is GatewayStorage { * @param amount The amount of the token available to claim. */ event WithdrawPrincipleResult( - bool indexed success, address indexed token, address indexed withdrawer, uint256 amount + bool indexed success, + address indexed token, + address indexed withdrawer, + uint256 amount ); /** @@ -308,8 +301,11 @@ contract BootstrapStorage is GatewayStorage { * @param amount The amount of the token delegated. */ event DelegateResult( - bool indexed success, address indexed delegator, string indexed delegatee, - address token, uint256 amount + bool indexed success, + address indexed delegator, + string indexed delegatee, + address token, + uint256 amount ); /** @@ -322,8 +318,11 @@ contract BootstrapStorage is GatewayStorage { * @param amount The amount of the token undelegated. */ event UndelegateResult( - bool indexed success, address indexed undelegator, string indexed undelegatee, - address token, uint256 amount + bool indexed success, + address indexed undelegator, + string indexed undelegatee, + address token, + uint256 amount ); /** @@ -399,14 +398,16 @@ contract BootstrapStorage is GatewayStorage { uint256[40] private __gap; - constructor( - uint32 exocoreChainId_, - address vaultBeacon_, - address beaconProxyBytecode_ - ) { + constructor(uint32 exocoreChainId_, address vaultBeacon_, address beaconProxyBytecode_) { require(exocoreChainId_ != 0, "BootstrapStorage: exocore chain id should not be empty"); - require(vaultBeacon_ != address(0), "BootstrapStorage: the vaultBeacon address for beacon proxy should not be empty"); - require(beaconProxyBytecode_ != address(0), "BootstrapStorage: the beaconProxyBytecode address should not be empty"); + require( + vaultBeacon_ != address(0), + "BootstrapStorage: the vaultBeacon address for beacon proxy should not be empty" + ); + require( + beaconProxyBytecode_ != address(0), + "BootstrapStorage: the beaconProxyBytecode address should not be empty" + ); exocoreChainId = exocoreChainId_; vaultBeacon = IBeacon(vaultBeacon_); @@ -421,9 +422,7 @@ contract BootstrapStorage is GatewayStorage { return vault; } - function isValidExocoreAddress( - string calldata operatorExocoreAddress - ) public pure returns (bool) { + function isValidExocoreAddress(string calldata operatorExocoreAddress) public pure returns (bool) { bytes memory stringBytes = bytes(operatorExocoreAddress); if (stringBytes.length != 42) { return false; @@ -452,4 +451,4 @@ contract BootstrapStorage is GatewayStorage { tokenToVault[underlyingToken] = vault; return vault; } -} \ No newline at end of file +} diff --git a/src/storage/ClientChainGatewayStorage.sol b/src/storage/ClientChainGatewayStorage.sol index 5c945c3b..bef05aa1 100644 --- a/src/storage/ClientChainGatewayStorage.sol +++ b/src/storage/ClientChainGatewayStorage.sol @@ -66,19 +66,28 @@ contract ClientChainGatewayStorage is BootstrapStorage { } modifier isValidBech32Address(string calldata exocoreAddress) { - require(isValidExocoreAddress(exocoreAddress), "BaseRestakingController: invalid bech32 encoded Exocore address"); + require( + isValidExocoreAddress(exocoreAddress), + "BaseRestakingController: invalid bech32 encoded Exocore address" + ); _; } constructor( - uint32 exocoreChainId_, - address beaconOracleAddress_, + uint32 exocoreChainId_, + address beaconOracleAddress_, address vaultBeacon_, address exoCapsuleBeacon_, address beaconProxyBytecode_ ) BootstrapStorage(exocoreChainId_, vaultBeacon_, beaconProxyBytecode_) { - require(beaconOracleAddress_ != address(0), "ClientChainGatewayStorage: beacon chain oracle address should not be empty"); - require(exoCapsuleBeacon_ != address(0), "ClientChainGatewayStorage: the exoCapsuleBeacon address for beacon proxy should not be empty"); + require( + beaconOracleAddress_ != address(0), + "ClientChainGatewayStorage: beacon chain oracle address should not be empty" + ); + require( + exoCapsuleBeacon_ != address(0), + "ClientChainGatewayStorage: the exoCapsuleBeacon address for beacon proxy should not be empty" + ); beaconOracleAddress = beaconOracleAddress_; exoCapsuleBeacon = IBeacon(exoCapsuleBeacon_); diff --git a/src/storage/ExoCapsuleStorage.sol b/src/storage/ExoCapsuleStorage.sol index 1dc7a243..10f26dd9 100644 --- a/src/storage/ExoCapsuleStorage.sol +++ b/src/storage/ExoCapsuleStorage.sol @@ -38,4 +38,4 @@ contract ExoCapsuleStorage { mapping(uint256 index => bytes32 pubkey) _capsuleValidatorsByIndex; uint256[40] private __gap; -} \ No newline at end of file +} diff --git a/test/foundry/Bootstrap.t.sol b/test/foundry/Bootstrap.t.sol index 347d7571..d3a81618 100644 --- a/test/foundry/Bootstrap.t.sol +++ b/test/foundry/Bootstrap.t.sol @@ -30,12 +30,12 @@ contract BootstrapTest is Test { Bootstrap bootstrap; address[] addrs = new address[](6); uint256[] amounts = [ - 35 * 10 ** 18, // self - 25 * 10 ** 18, // self - 10 * 10 ** 18, // self - 17 * 10 ** 18, // 8 + 9 + 0 - 15 * 10 ** 18, // 0 + 7 + 8 - 8 * 10 ** 18 // 2 + 0 + 6 + 35 * 10 ** 18, // self + 25 * 10 ** 18, // self + 10 * 10 ** 18, // self + 17 * 10 ** 18, // 8 + 9 + 0 + 15 * 10 ** 18, // 0 + 7 + 8 + 8 * 10 ** 18 // 2 + 0 + 6 ]; address deployer = address(0xdeadbeef); uint256 spawnTime; @@ -85,9 +85,7 @@ contract BootstrapTest is Test { // then the ProxyAdmin proxyAdmin = new CustomProxyAdmin(); // then the logic - clientChainLzEndpoint = new NonShortCircuitEndpointV2Mock( - clientChainId, exocoreValidatorSet - ); + clientChainLzEndpoint = new NonShortCircuitEndpointV2Mock(clientChainId, exocoreValidatorSet); Bootstrap bootstrapLogic = new Bootstrap( address(clientChainLzEndpoint), exocoreChainId, @@ -98,16 +96,25 @@ contract BootstrapTest is Test { spawnTime = block.timestamp + 1 hours; offsetDuration = 30 minutes; bootstrap = Bootstrap( - payable(address( - new TransparentUpgradeableProxy( - address(bootstrapLogic), address(proxyAdmin), - abi.encodeCall(bootstrap.initialize, - (deployer, spawnTime, offsetDuration, - payable(exocoreValidatorSet), whitelistTokens, - address(proxyAdmin)) + payable( + address( + new TransparentUpgradeableProxy( + address(bootstrapLogic), + address(proxyAdmin), + abi.encodeCall( + bootstrap.initialize, + ( + deployer, + spawnTime, + offsetDuration, + payable(exocoreValidatorSet), + whitelistTokens, + address(proxyAdmin) + ) + ) ) ) - )) + ) ); // validate the initialization assertTrue(bootstrap.isWhitelistedToken(address(myToken))); @@ -123,9 +130,7 @@ contract BootstrapTest is Test { ); assertTrue(address(bootstrap.tokenToVault(address(myToken))) == expectedVaultAddress); // now set the gateway address for Exocore. - clientChainLzEndpoint.setDestLzEndpoint( - undeployedExocoreGateway, undeployedExocoreLzEndpoint - ); + clientChainLzEndpoint.setDestLzEndpoint(undeployedExocoreGateway, undeployedExocoreLzEndpoint); bootstrap.setPeer(exocoreChainId, bytes32(bytes20(undeployedExocoreGateway))); // lastly set up the upgrade params @@ -158,10 +163,7 @@ contract BootstrapTest is Test { appendedWhitelistTokensForUpgrade ) ); - bootstrap.setClientChainGatewayLogic( - address(clientGatewayLogic), - initialization - ); + bootstrap.setClientChainGatewayLogic(address(clientGatewayLogic), initialization); vm.stopPrank(); } @@ -203,9 +205,7 @@ contract BootstrapTest is Test { bool prevIsDepositor = bootstrap.isDepositor(addrs[i]); uint256 prevBalance = myToken.balanceOf(addrs[i]); uint256 prevDeposit = bootstrap.totalDepositAmounts(addrs[i], address(myToken)); - uint256 prevWithdrawable = bootstrap.withdrawableAmounts( - addrs[i], address(myToken) - ); + uint256 prevWithdrawable = bootstrap.withdrawableAmounts(addrs[i], address(myToken)); uint256 prevTokenDeposit = bootstrap.depositsByToken(address(myToken)); bootstrap.deposit(address(myToken), amounts[i]); uint256 newBalance = myToken.balanceOf(addrs[i]); @@ -220,8 +220,7 @@ contract BootstrapTest is Test { } else { assertTrue(bootstrap.getDepositorsCount() == prevDepositorsCount); } - assertTrue(bootstrap.depositsByToken(address(myToken)) == - prevTokenDeposit + amounts[i]); + assertTrue(bootstrap.depositsByToken(address(myToken)) == prevTokenDeposit + amounts[i]); vm.stopPrank(); } } @@ -311,31 +310,19 @@ contract BootstrapTest is Test { bytes32(0xe2f00b6510e16fd8cc5802a4011d6f093acbbbca7c284cad6aa2c2e474bb50f9), bytes32(0xa29429a3ca352334fbe75df9485544bd517e3718df73725f33c6d06f3c1caade) ]; - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0, 1e18, 1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0, 1e18, 1e18); for (uint256 i = 0; i < 3; i++) { vm.startPrank(addrs[i]); - bootstrap.registerOperator( - operators[i], names[i], commission, pubKeys[i] - ); + bootstrap.registerOperator(operators[i], names[i], commission, pubKeys[i]); // check count assertTrue(bootstrap.getOperatorsCount() == i + 1); // check ethToExocoreAddress mapping string memory exoAddress = bootstrap.ethToExocoreAddress(addrs[i]); - assertTrue( - keccak256(abi.encodePacked(exoAddress)) == - keccak256(abi.encodePacked(operators[i])) - ); - ( - string memory name, - IOperatorRegistry.Commission memory thisCommision, - bytes32 key - ) = bootstrap.operators(exoAddress); - assertTrue( - keccak256(abi.encodePacked(name)) == - keccak256(abi.encodePacked(names[i])) + assertTrue(keccak256(abi.encodePacked(exoAddress)) == keccak256(abi.encodePacked(operators[i]))); + (string memory name, IOperatorRegistry.Commission memory thisCommision, bytes32 key) = bootstrap.operators( + exoAddress ); + assertTrue(keccak256(abi.encodePacked(name)) == keccak256(abi.encodePacked(names[i]))); assertTrue(key == pubKeys[i]); assertTrue(thisCommision.rate == commission.rate); vm.stopPrank(); @@ -343,69 +330,48 @@ contract BootstrapTest is Test { } function test03_RegisterOperator_EthAlreadyRegistered() public { - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0, 1e18, 1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0, 1e18, 1e18); // Register operator string memory exo = "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac"; string memory name = "operator1"; - bytes32 pubKey = - bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); + bytes32 pubKey = bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); vm.startPrank(addrs[0]); - bootstrap.registerOperator( - exo, name, commission, pubKey - ); + bootstrap.registerOperator(exo, name, commission, pubKey); // change all identifying params except eth address of operator exo = "exo1wnw7zcl9fy04ax69uffumwkdxftfqsjyj37wt2"; name = "operator1_re"; - pubKey = - bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540783); + pubKey = bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540783); vm.expectRevert("Ethereum address already linked to an operator"); - bootstrap.registerOperator( - exo, name, commission, pubKey - ); + bootstrap.registerOperator(exo, name, commission, pubKey); vm.stopPrank(); } function test03_RegisterOperator_ExoAlreadyRegistered() public { - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0, 1e18, 1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0, 1e18, 1e18); // Register operator string memory exo = "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac"; string memory name = "operator1"; - bytes32 pubKey = - bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); + bytes32 pubKey = bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); vm.startPrank(addrs[0]); - bootstrap.registerOperator( - exo, name, commission, pubKey - ); + bootstrap.registerOperator(exo, name, commission, pubKey); // change all identifying params except exo address of operator vm.stopPrank(); vm.startPrank(addrs[1]); name = "operator1_re"; - pubKey = - bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540783); + pubKey = bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540783); vm.expectRevert("Operator with this Exocore address is already registered"); - bootstrap.registerOperator( - exo, name, commission, pubKey - ); + bootstrap.registerOperator(exo, name, commission, pubKey); vm.stopPrank(); } function test03_RegisterOperator_ConsensusKeyInUse() public { - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0, 1e18, 1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0, 1e18, 1e18); // Register operator string memory exo = "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac"; string memory name = "operator1"; - bytes32 pubKey = - bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); + bytes32 pubKey = bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); vm.startPrank(addrs[0]); - bootstrap.registerOperator( - exo, name, commission, pubKey - ); + bootstrap.registerOperator(exo, name, commission, pubKey); // change all identifying params except consensus key of operator vm.stopPrank(); @@ -413,60 +379,44 @@ contract BootstrapTest is Test { exo = "exo1wnw7zcl9fy04ax69uffumwkdxftfqsjyj37wt2"; name = "operator1_re"; vm.expectRevert("Consensus public key already in use"); - bootstrap.registerOperator( - exo, name, commission, pubKey - ); + bootstrap.registerOperator(exo, name, commission, pubKey); vm.stopPrank(); } function test03_RegisterOperator_NameInUse() public { - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0, 1e18, 1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0, 1e18, 1e18); // Register operator string memory exo = "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac"; string memory name = "operator1"; - bytes32 pubKey = - bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); + bytes32 pubKey = bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); vm.startPrank(addrs[0]); - bootstrap.registerOperator( - exo, name, commission, pubKey - ); + bootstrap.registerOperator(exo, name, commission, pubKey); // change all identifying params except name of operator vm.stopPrank(); vm.startPrank(addrs[1]); exo = "exo1wnw7zcl9fy04ax69uffumwkdxftfqsjyj37wt2"; - pubKey = - bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540783); + pubKey = bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540783); vm.expectRevert("Name already in use"); - bootstrap.registerOperator( - exo, name, commission, pubKey - ); + bootstrap.registerOperator(exo, name, commission, pubKey); vm.stopPrank(); } function test05_ReplaceKey() public { - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0, 1e18, 1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0, 1e18, 1e18); // Register operator string memory exo = "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac"; string memory name = "operator1"; - bytes32 pubKey = - bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); + bytes32 pubKey = bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); vm.startPrank(addrs[0]); - bootstrap.registerOperator( - exo, name, commission, pubKey - ); + bootstrap.registerOperator(exo, name, commission, pubKey); assertTrue(bootstrap.getOperatorsCount() == 1); - (, , bytes32 consensusPublicKey ) = bootstrap.operators(exo); + (, , bytes32 consensusPublicKey) = bootstrap.operators(exo); assertTrue(consensusPublicKey == pubKey); // Then change the key - bytes32 newKey = - bytes32(0xd995b7f4b2178b0466cfa512955ce2299a4487ebcd86f817d686880dd2b7c4b0); + bytes32 newKey = bytes32(0xd995b7f4b2178b0466cfa512955ce2299a4487ebcd86f817d686880dd2b7c4b0); bootstrap.replaceKey(newKey); - (, , consensusPublicKey ) = bootstrap.operators(exo); + (, , consensusPublicKey) = bootstrap.operators(exo); assertTrue(consensusPublicKey == newKey); vm.stopPrank(); } @@ -475,8 +425,7 @@ contract BootstrapTest is Test { test03_RegisterOperator(); // Then change the key vm.startPrank(addrs[0]); - bytes32 newKey = - bytes32(0xe2f00b6510e16fd8cc5802a4011d6f093acbbbca7c284cad6aa2c2e474bb50f9); + bytes32 newKey = bytes32(0xe2f00b6510e16fd8cc5802a4011d6f093acbbbca7c284cad6aa2c2e474bb50f9); vm.expectRevert("Consensus public key already in use"); bootstrap.replaceKey(newKey); vm.stopPrank(); @@ -486,8 +435,7 @@ contract BootstrapTest is Test { test03_RegisterOperator(); // Then change the key for the same address vm.startPrank(addrs[1]); - bytes32 newKey = - bytes32(0xe2f00b6510e16fd8cc5802a4011d6f093acbbbca7c284cad6aa2c2e474bb50f9); + bytes32 newKey = bytes32(0xe2f00b6510e16fd8cc5802a4011d6f093acbbbca7c284cad6aa2c2e474bb50f9); vm.expectRevert("Consensus public key already in use"); bootstrap.replaceKey(newKey); vm.stopPrank(); @@ -495,26 +443,20 @@ contract BootstrapTest is Test { function test05_ReplaceKey_Unregistered() public { vm.startPrank(addrs[1]); - bytes32 newKey = - bytes32(0xe2f00b6510e16fd8cc5802a4011d6f093acbbbca7c284cad6aa2c2e474bb50f9); + bytes32 newKey = bytes32(0xe2f00b6510e16fd8cc5802a4011d6f093acbbbca7c284cad6aa2c2e474bb50f9); vm.expectRevert("no such operator exists"); bootstrap.replaceKey(newKey); vm.stopPrank(); } function test06_UpdateRate() public { - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0, 1e18, 1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0, 1e18, 1e18); // Register one operator string memory exo = "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac"; string memory name = "operator1"; - bytes32 pubKey = - bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); + bytes32 pubKey = bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); vm.startPrank(addrs[0]); - bootstrap.registerOperator( - exo, name, commission, pubKey - ); + bootstrap.registerOperator(exo, name, commission, pubKey); bootstrap.updateRate(1e17); (, IOperatorRegistry.Commission memory newCommission, ) = bootstrap.operators(exo); assertTrue(newCommission.rate == 1e17); @@ -522,18 +464,13 @@ contract BootstrapTest is Test { } function test06_UpdateRate_Twice() public { - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0, 1e18, 1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0, 1e18, 1e18); // Register one operator string memory exo = "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac"; string memory name = "operator1"; - bytes32 pubKey = - bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); + bytes32 pubKey = bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); vm.startPrank(addrs[0]); - bootstrap.registerOperator( - exo, name, commission, pubKey - ); + bootstrap.registerOperator(exo, name, commission, pubKey); bootstrap.updateRate(1e17); (, IOperatorRegistry.Commission memory newCommission, ) = bootstrap.operators(exo); assertTrue(newCommission.rate == 1e17); @@ -543,18 +480,13 @@ contract BootstrapTest is Test { } function test06_UpdateRate_MoreThanMaxRate() public { - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0, 1e17, 1e17 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0, 1e17, 1e17); // Register one operator string memory exo = "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac"; string memory name = "operator1"; - bytes32 pubKey = - bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); + bytes32 pubKey = bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); vm.startPrank(addrs[0]); - bootstrap.registerOperator( - exo, name, commission, pubKey - ); + bootstrap.registerOperator(exo, name, commission, pubKey); vm.expectRevert("Rate exceeds max rate"); bootstrap.updateRate(2e17); vm.stopPrank(); @@ -562,18 +494,13 @@ contract BootstrapTest is Test { function test06_UpdateRate_MoreThanMaxChangeRate() public { // 0, 0.1, 0.01 - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0, 1e17, 1e16 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0, 1e17, 1e16); // Register one operator string memory exo = "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac"; string memory name = "operator1"; - bytes32 pubKey = - bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); + bytes32 pubKey = bytes32(0x27165ec2f29a4815b7c29e47d8700845b5ae267f2d61ad29fb3939aec5540782); vm.startPrank(addrs[0]); - bootstrap.registerOperator( - exo, name, commission, pubKey - ); + bootstrap.registerOperator(exo, name, commission, pubKey); vm.expectRevert("Rate change exceeds max change rate"); bootstrap.updateRate(2e16); vm.stopPrank(); @@ -611,27 +538,15 @@ contract BootstrapTest is Test { } function test08_ExocoreAddressIsValid() public { - assertTrue( - bootstrap.isValidExocoreAddress( - "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac" - ) - ); + assertTrue(bootstrap.isValidExocoreAddress("exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac")); } function test08_ExocoreAddressIsValid_Length() public { - assertFalse( - bootstrap.isValidExocoreAddress( - "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7acaa" - ) - ); + assertFalse(bootstrap.isValidExocoreAddress("exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7acaa")); } function test08_ExocoreAddressIsValid_Prefix() public { - assertFalse( - bootstrap.isValidExocoreAddress( - "asd" - ) - ); + assertFalse(bootstrap.isValidExocoreAddress("asd")); } function test09_DelegateTo() public { @@ -643,70 +558,36 @@ contract BootstrapTest is Test { for (uint256 i = 0; i < 3; i++) { vm.startPrank(addrs[i]); string memory exo = bootstrap.ethToExocoreAddress(addrs[i]); - uint256 prevDelegation = bootstrap.delegations( - addrs[i], exo, address(myToken) - ); - uint256 prevDelegationByOperator = bootstrap.delegationsByOperator( - exo, address(myToken) - ); - uint256 prevWithdrawableAmount = bootstrap.withdrawableAmounts( - addrs[i], address(myToken) - ); - bootstrap.delegateTo( - exo, address(myToken), amounts[i] - ); - uint256 postDelegation = bootstrap.delegations( - addrs[i], exo, address(myToken) - ); - uint256 postDelegationByOperator = bootstrap.delegationsByOperator( - exo, address(myToken) - ); - uint256 postWithdrawableAmount = bootstrap.withdrawableAmounts( - addrs[i], address(myToken) - ); + uint256 prevDelegation = bootstrap.delegations(addrs[i], exo, address(myToken)); + uint256 prevDelegationByOperator = bootstrap.delegationsByOperator(exo, address(myToken)); + uint256 prevWithdrawableAmount = bootstrap.withdrawableAmounts(addrs[i], address(myToken)); + bootstrap.delegateTo(exo, address(myToken), amounts[i]); + uint256 postDelegation = bootstrap.delegations(addrs[i], exo, address(myToken)); + uint256 postDelegationByOperator = bootstrap.delegationsByOperator(exo, address(myToken)); + uint256 postWithdrawableAmount = bootstrap.withdrawableAmounts(addrs[i], address(myToken)); assertTrue(postDelegation == prevDelegation + amounts[i]); assertTrue(postDelegationByOperator == prevDelegationByOperator + amounts[i]); assertTrue(postWithdrawableAmount == prevWithdrawableAmount - amounts[i]); vm.stopPrank(); } // finally, delegate from stakers to the operators - uint8[3][3] memory delegations = [ - [8, 9, 0], - [0, 7, 8], - [2, 0, 6] - ]; + uint8[3][3] memory delegations = [[8, 9, 0], [0, 7, 8], [2, 0, 6]]; for (uint256 i = 0; i < 3; i++) { address delegator = addrs[i + 3]; vm.startPrank(delegator); - for(uint256 j = 0; j < 3; j++) { + for (uint256 j = 0; j < 3; j++) { uint256 amount = delegations[i][j] * 10 ** 18; if (amount != 0) { string memory exo = bootstrap.ethToExocoreAddress(addrs[j]); - uint256 prevDelegation = bootstrap.delegations( - delegator, exo, address(myToken) - ); - uint256 prevDelegationByOperator = bootstrap.delegationsByOperator( - exo, address(myToken) - ); - uint256 prevWithdrawableAmount = bootstrap.withdrawableAmounts( - delegator, address(myToken) - ); - bootstrap.delegateTo( - exo, address(myToken), uint256(amount) - ); - uint256 postDelegation = bootstrap.delegations( - delegator, exo, address(myToken) - ); - uint256 postDelegationByOperator = bootstrap.delegationsByOperator( - exo, address(myToken) - ); - uint256 postWithdrawableAmount = bootstrap.withdrawableAmounts( - delegator, address(myToken) - ); + uint256 prevDelegation = bootstrap.delegations(delegator, exo, address(myToken)); + uint256 prevDelegationByOperator = bootstrap.delegationsByOperator(exo, address(myToken)); + uint256 prevWithdrawableAmount = bootstrap.withdrawableAmounts(delegator, address(myToken)); + bootstrap.delegateTo(exo, address(myToken), uint256(amount)); + uint256 postDelegation = bootstrap.delegations(delegator, exo, address(myToken)); + uint256 postDelegationByOperator = bootstrap.delegationsByOperator(exo, address(myToken)); + uint256 postWithdrawableAmount = bootstrap.withdrawableAmounts(delegator, address(myToken)); assertTrue(postDelegation == prevDelegation + amount); - assertTrue( - postDelegationByOperator == prevDelegationByOperator + amount - ); + assertTrue(postDelegationByOperator == prevDelegationByOperator + amount); assertTrue(postWithdrawableAmount == prevWithdrawableAmount - amount); } } @@ -718,9 +599,7 @@ contract BootstrapTest is Test { test02_Deposit(); vm.startPrank(addrs[0]); vm.expectRevert("Operator does not exist"); - bootstrap.delegateTo( - "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(myToken), amounts[0] - ); + bootstrap.delegateTo("exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(myToken), amounts[0]); } function test09_DelegateTo_TokenNotWhitelisted() public { @@ -728,9 +607,7 @@ contract BootstrapTest is Test { test02_Deposit(); vm.startPrank(addrs[0]); vm.expectRevert("Bootstrap: token is not whitelisted"); - bootstrap.delegateTo( - "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(0xa), amounts[0] - ); + bootstrap.delegateTo("exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(0xa), amounts[0]); } function test09_DelegateTo_NotEnoughBlance() public { @@ -740,9 +617,7 @@ contract BootstrapTest is Test { vm.stopPrank(); vm.startPrank(addrs[0]); vm.expectRevert(bytes("Bootstrap: insufficient withdrawable balance")); - bootstrap.delegateTo( - "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(0xa), amounts[0] - ); + bootstrap.delegateTo("exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(0xa), amounts[0]); } function test09_DelegateTo_ZeroAmount() public { @@ -750,18 +625,14 @@ contract BootstrapTest is Test { test02_Deposit(); vm.startPrank(addrs[0]); vm.expectRevert("Bootstrap: amount should be greater than zero"); - bootstrap.delegateTo( - "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(myToken), 0 - ); + bootstrap.delegateTo("exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(myToken), 0); } function test09_DelegateTo_NoDeposits() public { test03_RegisterOperator(); vm.startPrank(addrs[0]); vm.expectRevert("Bootstrap: insufficient withdrawable balance"); - bootstrap.delegateTo( - "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(myToken), amounts[0] - ); + bootstrap.delegateTo("exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(myToken), amounts[0]); } function test09_DelegateTo_Excess() public { @@ -769,9 +640,7 @@ contract BootstrapTest is Test { test02_Deposit(); vm.startPrank(addrs[0]); vm.expectRevert("Bootstrap: insufficient withdrawable balance"); - bootstrap.delegateTo( - "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(myToken), amounts[0] + 1 - ); + bootstrap.delegateTo("exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(myToken), amounts[0] + 1); } function test10_UndelegateFrom() public { @@ -780,70 +649,36 @@ contract BootstrapTest is Test { for (uint256 i = 0; i < 3; i++) { vm.startPrank(addrs[i]); string memory exo = bootstrap.ethToExocoreAddress(addrs[i]); - uint256 prevDelegation = bootstrap.delegations( - addrs[i], exo, address(myToken) - ); - uint256 prevDelegationByOperator = bootstrap.delegationsByOperator( - exo, address(myToken) - ); - uint256 prevWithdrawableAmount = bootstrap.withdrawableAmounts( - addrs[i], address(myToken) - ); - bootstrap.undelegateFrom( - exo, address(myToken), amounts[i] - ); - uint256 postDelegation = bootstrap.delegations( - addrs[i], exo, address(myToken) - ); - uint256 postDelegationByOperator = bootstrap.delegationsByOperator( - exo, address(myToken) - ); - uint256 postWithdrawableAmount = bootstrap.withdrawableAmounts( - addrs[i], address(myToken) - ); + uint256 prevDelegation = bootstrap.delegations(addrs[i], exo, address(myToken)); + uint256 prevDelegationByOperator = bootstrap.delegationsByOperator(exo, address(myToken)); + uint256 prevWithdrawableAmount = bootstrap.withdrawableAmounts(addrs[i], address(myToken)); + bootstrap.undelegateFrom(exo, address(myToken), amounts[i]); + uint256 postDelegation = bootstrap.delegations(addrs[i], exo, address(myToken)); + uint256 postDelegationByOperator = bootstrap.delegationsByOperator(exo, address(myToken)); + uint256 postWithdrawableAmount = bootstrap.withdrawableAmounts(addrs[i], address(myToken)); assertTrue(postDelegation == prevDelegation - amounts[i]); assertTrue(postDelegationByOperator == prevDelegationByOperator - amounts[i]); assertTrue(postWithdrawableAmount == prevWithdrawableAmount + amounts[i]); vm.stopPrank(); } // finally, undelegate from stakers to the operators - uint8[3][3] memory delegations = [ - [8, 9, 0], - [0, 7, 8], - [2, 0, 6] - ]; + uint8[3][3] memory delegations = [[8, 9, 0], [0, 7, 8], [2, 0, 6]]; for (uint256 i = 0; i < 3; i++) { address delegator = addrs[i + 3]; vm.startPrank(delegator); - for(uint256 j = 0; j < 3; j++) { + for (uint256 j = 0; j < 3; j++) { uint256 amount = delegations[i][j] * 10 ** 18; if (amount != 0) { string memory exo = bootstrap.ethToExocoreAddress(addrs[j]); - uint256 prevDelegation = bootstrap.delegations( - delegator, exo, address(myToken) - ); - uint256 prevDelegationByOperator = bootstrap.delegationsByOperator( - exo, address(myToken) - ); - uint256 prevWithdrawableAmount = bootstrap.withdrawableAmounts( - delegator, address(myToken) - ); - bootstrap.undelegateFrom( - exo, address(myToken), uint256(amount) - ); - uint256 postDelegation = bootstrap.delegations( - delegator, exo, address(myToken) - ); - uint256 postDelegationByOperator = bootstrap.delegationsByOperator( - exo, address(myToken) - ); - uint256 postWithdrawableAmount = bootstrap.withdrawableAmounts( - delegator, address(myToken) - ); + uint256 prevDelegation = bootstrap.delegations(delegator, exo, address(myToken)); + uint256 prevDelegationByOperator = bootstrap.delegationsByOperator(exo, address(myToken)); + uint256 prevWithdrawableAmount = bootstrap.withdrawableAmounts(delegator, address(myToken)); + bootstrap.undelegateFrom(exo, address(myToken), uint256(amount)); + uint256 postDelegation = bootstrap.delegations(delegator, exo, address(myToken)); + uint256 postDelegationByOperator = bootstrap.delegationsByOperator(exo, address(myToken)); + uint256 postWithdrawableAmount = bootstrap.withdrawableAmounts(delegator, address(myToken)); assertTrue(postDelegation == prevDelegation - amount); - assertTrue( - postDelegationByOperator == prevDelegationByOperator - amount - ); + assertTrue(postDelegationByOperator == prevDelegationByOperator - amount); assertTrue(postWithdrawableAmount == prevWithdrawableAmount + amount); } } @@ -855,18 +690,14 @@ contract BootstrapTest is Test { test09_DelegateTo(); vm.startPrank(addrs[0]); vm.expectRevert("Operator does not exist"); - bootstrap.undelegateFrom( - "exo1awm72f4sc5yhedurdunx9afcshfq6ymqva8an4", address(myToken), amounts[0] - ); + bootstrap.undelegateFrom("exo1awm72f4sc5yhedurdunx9afcshfq6ymqva8an4", address(myToken), amounts[0]); } function test10_UndelegateFrom_TokenNotWhitelisted() public { test03_RegisterOperator(); vm.startPrank(addrs[0]); vm.expectRevert("Bootstrap: token is not whitelisted"); - bootstrap.undelegateFrom( - "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(0xa), amounts[0] - ); + bootstrap.undelegateFrom("exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(0xa), amounts[0]); } function test10_UndelegateFrom_NotEnoughBalance() public { @@ -876,9 +707,7 @@ contract BootstrapTest is Test { vm.stopPrank(); vm.startPrank(addrs[0]); vm.expectRevert(bytes("Bootstrap: insufficient delegated balance")); - bootstrap.undelegateFrom( - "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(0xa), amounts[0] - ); + bootstrap.undelegateFrom("exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(0xa), amounts[0]); } function test10_UndelegateFrom_ZeroAmount() public { @@ -886,27 +715,21 @@ contract BootstrapTest is Test { test02_Deposit(); vm.startPrank(addrs[0]); vm.expectRevert("Bootstrap: amount should be greater than zero"); - bootstrap.undelegateFrom( - "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(myToken), 0 - ); + bootstrap.undelegateFrom("exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(myToken), 0); } function test10_UndelegateFromOperator_Excess() public { test09_DelegateTo(); vm.startPrank(addrs[0]); vm.expectRevert("Bootstrap: insufficient delegated balance"); - bootstrap.undelegateFrom( - "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(myToken), amounts[0] + 1 - ); + bootstrap.undelegateFrom("exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(myToken), amounts[0] + 1); } function test10_UndelegateFrom_NoDelegation() public { test03_RegisterOperator(); vm.startPrank(addrs[0]); vm.expectRevert("Bootstrap: insufficient delegated balance"); - bootstrap.undelegateFrom( - "exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(myToken), amounts[0] - ); + bootstrap.undelegateFrom("exo13hasr43vvq8v44xpzh0l6yuym4kca98f87j7ac", address(myToken), amounts[0]); } function test11_WithdrawPrincipleFromExocore() public { @@ -916,22 +739,16 @@ contract BootstrapTest is Test { for (uint256 i = 0; i < 6; i++) { vm.startPrank(addrs[i]); uint256 prevDeposit = bootstrap.totalDepositAmounts(addrs[i], address(myToken)); - uint256 prevWithdrawable = bootstrap.withdrawableAmounts( - addrs[i], address(myToken) - ); + uint256 prevWithdrawable = bootstrap.withdrawableAmounts(addrs[i], address(myToken)); uint256 prevTokenDeposit = bootstrap.depositsByToken(address(myToken)); - uint256 prevVaultWithdrawable = Vault( - address(bootstrap.tokenToVault(address(myToken))) - ).withdrawableBalances(addrs[i]); + uint256 prevVaultWithdrawable = Vault(address(bootstrap.tokenToVault(address(myToken)))) + .withdrawableBalances(addrs[i]); bootstrap.withdrawPrincipleFromExocore(address(myToken), amounts[i]); uint256 postDeposit = bootstrap.totalDepositAmounts(addrs[i], address(myToken)); - uint256 postWithdrawable = bootstrap.withdrawableAmounts( - addrs[i], address(myToken) - ); + uint256 postWithdrawable = bootstrap.withdrawableAmounts(addrs[i], address(myToken)); uint256 postTokenDeposit = bootstrap.depositsByToken(address(myToken)); - uint256 postVaultWithdrawable = Vault( - address(bootstrap.tokenToVault(address(myToken))) - ).withdrawableBalances(addrs[i]); + uint256 postVaultWithdrawable = Vault(address(bootstrap.tokenToVault(address(myToken)))) + .withdrawableBalances(addrs[i]); assertTrue(postDeposit == prevDeposit - amounts[i]); assertTrue(postWithdrawable == prevWithdrawable - amounts[i]); assertTrue(postTokenDeposit == prevTokenDeposit - amounts[i]); @@ -1014,7 +831,9 @@ contract BootstrapTest is Test { function test12_MarkBootstrapped_AlreadyBootstrapped() public { test12_MarkBootstrapped(); vm.startPrank(address(clientChainLzEndpoint)); - vm.expectRevert(abi.encodeWithSelector(GatewayStorage.UnsupportedRequest.selector, GatewayStorage.Action.MARK_BOOTSTRAP)); + vm.expectRevert( + abi.encodeWithSelector(GatewayStorage.UnsupportedRequest.selector, GatewayStorage.Action.MARK_BOOTSTRAP) + ); bootstrap.lzReceive( Origin(exocoreChainId, bytes32(bytes20(undeployedExocoreGateway)), uint64(2)), generateUID(1), @@ -1028,9 +847,7 @@ contract BootstrapTest is Test { function test12_MarkBootstrapped_DirectCall() public { vm.startPrank(address(0x20)); vm.warp(spawnTime + 2); - vm.expectRevert( - "BootstrapLzReceiver: could only be called from this contract itself with low level call" - ); + vm.expectRevert("BootstrapLzReceiver: could only be called from this contract itself with low level call"); bootstrap.markBootstrapped(); vm.stopPrank(); } @@ -1044,54 +861,42 @@ contract BootstrapTest is Test { } function test14_IsCommissionValid() public { - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0, 1e18, 1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0, 1e18, 1e18); assertTrue(bootstrap.isCommissionValid(commission)); } function test14_IsCommissionValidRateLarge() public { - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 1.1e18, 1e18, 1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(1.1e18, 1e18, 1e18); assertFalse(bootstrap.isCommissionValid(commission)); } function test14_IsCommissionValidMaxRateLarge() public { - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0, 1.1e18, 1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0, 1.1e18, 1e18); assertFalse(bootstrap.isCommissionValid(commission)); } function test14_IsCommissionValidMaxChangeRateLarge() public { - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0, 1e18, 1.1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0, 1e18, 1.1e18); assertFalse(bootstrap.isCommissionValid(commission)); } function test14_IsCommissionValidRateExceedsMaxRate() public { - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0.5e18, 0.2e18, 1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0.5e18, 0.2e18, 1e18); assertFalse(bootstrap.isCommissionValid(commission)); } function test14_IsCommissionValidMaxChangeRateExceedsMaxRate() public { - IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission( - 0.1e18, 0.2e18, 1e18 - ); + IOperatorRegistry.Commission memory commission = IOperatorRegistry.Commission(0.1e18, 0.2e18, 1e18); assertFalse(bootstrap.isCommissionValid(commission)); } - function generateUID( - uint64 nonce - ) internal view returns (bytes32 uid) { + function generateUID(uint64 nonce) internal view returns (bytes32 uid) { uid = GUID.generate( - nonce, exocoreChainId, + nonce, + exocoreChainId, address(undeployedExocoreGateway), - clientChainId, bytes32(bytes20(address(bootstrap))) + clientChainId, + bytes32(bytes20(address(bootstrap))) ); } @@ -1105,16 +910,25 @@ contract BootstrapTest is Test { ); vm.expectRevert("Bootstrap: owner should not be empty"); Bootstrap( - payable(address( - new TransparentUpgradeableProxy( - address(bootstrapLogic), address(proxyAdmin), - abi.encodeCall(bootstrap.initialize, - (address(0x0), spawnTime, offsetDuration, - payable(exocoreValidatorSet), whitelistTokens, - address(proxyAdmin)) + payable( + address( + new TransparentUpgradeableProxy( + address(bootstrapLogic), + address(proxyAdmin), + abi.encodeCall( + bootstrap.initialize, + ( + address(0x0), + spawnTime, + offsetDuration, + payable(exocoreValidatorSet), + whitelistTokens, + address(proxyAdmin) + ) + ) ) ) - )) + ) ); } @@ -1129,16 +943,25 @@ contract BootstrapTest is Test { vm.warp(20); vm.expectRevert("Bootstrap: spawn time should be in the future"); Bootstrap( - payable(address( - new TransparentUpgradeableProxy( - address(bootstrapLogic), address(proxyAdmin), - abi.encodeCall(bootstrap.initialize, - (deployer, block.timestamp - 10, offsetDuration, - payable(exocoreValidatorSet), whitelistTokens, - address(proxyAdmin)) + payable( + address( + new TransparentUpgradeableProxy( + address(bootstrapLogic), + address(proxyAdmin), + abi.encodeCall( + bootstrap.initialize, + ( + deployer, + block.timestamp - 10, + offsetDuration, + payable(exocoreValidatorSet), + whitelistTokens, + address(proxyAdmin) + ) + ) ) ) - )) + ) ); } @@ -1152,16 +975,18 @@ contract BootstrapTest is Test { ); vm.expectRevert("Bootstrap: offset duration should be greater than 0"); Bootstrap( - payable(address( - new TransparentUpgradeableProxy( - address(bootstrapLogic), address(proxyAdmin), - abi.encodeCall(bootstrap.initialize, - (deployer, spawnTime, 0, - payable(exocoreValidatorSet), whitelistTokens, - address(proxyAdmin)) + payable( + address( + new TransparentUpgradeableProxy( + address(bootstrapLogic), + address(proxyAdmin), + abi.encodeCall( + bootstrap.initialize, + (deployer, spawnTime, 0, payable(exocoreValidatorSet), whitelistTokens, address(proxyAdmin)) + ) ) ) - )) + ) ); } @@ -1176,16 +1001,18 @@ contract BootstrapTest is Test { vm.expectRevert("Bootstrap: spawn time should be greater than offset duration"); vm.warp(20); Bootstrap( - payable(address( - new TransparentUpgradeableProxy( - address(bootstrapLogic), address(proxyAdmin), - abi.encodeCall(bootstrap.initialize, - (deployer, 21, 22, - payable(exocoreValidatorSet), whitelistTokens, - address(proxyAdmin)) + payable( + address( + new TransparentUpgradeableProxy( + address(bootstrapLogic), + address(proxyAdmin), + abi.encodeCall( + bootstrap.initialize, + (deployer, 21, 22, payable(exocoreValidatorSet), whitelistTokens, address(proxyAdmin)) + ) ) ) - )) + ) ); } @@ -1200,16 +1027,18 @@ contract BootstrapTest is Test { vm.expectRevert("Bootstrap: lock time should be in the future"); vm.warp(20); Bootstrap( - payable(address( - new TransparentUpgradeableProxy( - address(bootstrapLogic), address(proxyAdmin), - abi.encodeCall(bootstrap.initialize, - (deployer, 21, 9, - payable(exocoreValidatorSet), whitelistTokens, - address(proxyAdmin)) + payable( + address( + new TransparentUpgradeableProxy( + address(bootstrapLogic), + address(proxyAdmin), + abi.encodeCall( + bootstrap.initialize, + (deployer, 21, 9, payable(exocoreValidatorSet), whitelistTokens, address(proxyAdmin)) + ) ) ) - )) + ) ); } @@ -1223,16 +1052,25 @@ contract BootstrapTest is Test { ); vm.expectRevert("Bootstrap: exocore validator set address should not be empty"); Bootstrap( - payable(address( - new TransparentUpgradeableProxy( - address(bootstrapLogic), address(proxyAdmin), - abi.encodeCall(bootstrap.initialize, - (deployer, spawnTime, offsetDuration, - payable(address(0)), whitelistTokens, - address(proxyAdmin)) + payable( + address( + new TransparentUpgradeableProxy( + address(bootstrapLogic), + address(proxyAdmin), + abi.encodeCall( + bootstrap.initialize, + ( + deployer, + spawnTime, + offsetDuration, + payable(address(0)), + whitelistTokens, + address(proxyAdmin) + ) + ) ) ) - )) + ) ); } @@ -1246,16 +1084,25 @@ contract BootstrapTest is Test { ); vm.expectRevert("Bootstrap: custom proxy admin should not be empty"); Bootstrap( - payable(address( - new TransparentUpgradeableProxy( - address(bootstrapLogic), address(proxyAdmin), - abi.encodeCall(bootstrap.initialize, - (deployer, spawnTime, offsetDuration, - payable(exocoreValidatorSet), whitelistTokens, - address(0x0)) + payable( + address( + new TransparentUpgradeableProxy( + address(bootstrapLogic), + address(proxyAdmin), + abi.encodeCall( + bootstrap.initialize, + ( + deployer, + spawnTime, + offsetDuration, + payable(exocoreValidatorSet), + whitelistTokens, + address(0x0) + ) + ) ) ) - )) + ) ); } @@ -1328,7 +1175,7 @@ contract BootstrapTest is Test { function test22_Claim() public { test11_WithdrawPrincipleFromExocore(); - for(uint256 i = 0; i < 6; i++) { + for (uint256 i = 0; i < 6; i++) { vm.startPrank(addrs[i]); uint256 prevBalance = myToken.balanceOf(addrs[i]); bootstrap.claim(address(myToken), amounts[i], addrs[i]); @@ -1353,9 +1200,7 @@ contract BootstrapTest is Test { function test22_Claim_Excess() public { test11_WithdrawPrincipleFromExocore(); vm.startPrank(addrs[0]); - vm.expectRevert( - "Vault: withdrawal amount is larger than depositor's withdrawable balance" - ); + vm.expectRevert("Vault: withdrawal amount is larger than depositor's withdrawable balance"); bootstrap.claim(address(myToken), amounts[0] + 5, addrs[0]); } } diff --git a/test/foundry/ClientChainGateway.t.sol b/test/foundry/ClientChainGateway.t.sol index 713fd4e1..e9437aec 100644 --- a/test/foundry/ClientChainGateway.t.sol +++ b/test/foundry/ClientChainGateway.t.sol @@ -79,7 +79,7 @@ contract SetUp is Test { // deploy BeaconProxyBytecode to store BeaconProxyBytecode beaconProxyBytecode = new BeaconProxyBytecode(); - + restakeToken = new ERC20PresetFixedSupply("rest", "rest", 1e16, exocoreValidatorSet.addr); whitelistTokens.push(address(restakeToken)); @@ -97,10 +97,7 @@ contract SetUp is Test { payable(address(new TransparentUpgradeableProxy(address(clientGatewayLogic), address(proxyAdmin), ""))) ); - clientGateway.initialize( - payable(exocoreValidatorSet.addr), - whitelistTokens - ); + clientGateway.initialize(payable(exocoreValidatorSet.addr), whitelistTokens); vm.stopPrank(); } @@ -111,13 +108,13 @@ contract SetUp is Test { // mainnet if (block.chainid == 1) { GENESIS_BLOCK_TIMESTAMP = 1606824023; - // goerli + // goerli } else if (block.chainid == 5) { GENESIS_BLOCK_TIMESTAMP = 1616508000; - // sepolia + // sepolia } else if (block.chainid == 11155111) { GENESIS_BLOCK_TIMESTAMP = 1655733600; - // holesky + // holesky } else if (block.chainid == 17000) { GENESIS_BLOCK_TIMESTAMP = 1695902400; } else { diff --git a/test/foundry/CustomProxyAdmin.t.sol b/test/foundry/CustomProxyAdmin.t.sol index 6053b470..573cdc4c 100644 --- a/test/foundry/CustomProxyAdmin.t.sol +++ b/test/foundry/CustomProxyAdmin.t.sol @@ -27,15 +27,11 @@ contract ImplementationChanger is Initializable, StorageOld { implementationChanged = false; } - function changeImplementation( - address customProxyAdmin, - address newImplementation - ) public { + function changeImplementation(address customProxyAdmin, address newImplementation) public { ICustomProxyAdmin(customProxyAdmin).changeImplementation( ITransparentUpgradeableProxy(address(this)), - newImplementation, abi.encodeCall( - NewImplementation.initialize, () - ) + newImplementation, + abi.encodeCall(NewImplementation.initialize, ()) ); } } @@ -81,17 +77,12 @@ contract CustomProxyAdminTest is Test { // validate that the implementation has not changed already assertFalse(implementationChanger.implementationChanged()); // check that it does not have a `hi` function in there. - NewImplementation newImplementation = NewImplementation( - address(implementationChanger) - ); - vm.expectRevert(); // EVM error + NewImplementation newImplementation = NewImplementation(address(implementationChanger)); + vm.expectRevert(); // EVM error assertFalse(newImplementation.hi()); // now change the implementation proxyAdmin.initialize(address(implementationChanger)); - implementationChanger.changeImplementation( - address(proxyAdmin), - address(new NewImplementation()) - ); + implementationChanger.changeImplementation(address(proxyAdmin), address(new NewImplementation())); // validate that it has changed assertTrue(implementationChanger.implementationChanged()); assertTrue(newImplementation.hi()); @@ -114,10 +105,7 @@ contract CustomProxyAdminTest is Test { // for some reason, i could not get `vm.expectRevert` to work here. // if i had that line, it would not revert. // if i didn't have that line, it would not revert. - try implementationChanger.changeImplementation( - address(proxyAdmin), - address(new NewImplementation()) - ) { + try implementationChanger.changeImplementation(address(proxyAdmin), address(new NewImplementation())) { // should never happen assertTrue(false); } catch {} @@ -141,16 +129,18 @@ contract CustomProxyAdminTest is Test { proxyAdmin.initialize(address(0x1)); vm.startPrank(address(0x1)); // same logic as above for using a try/catch. - try proxyAdmin.changeImplementation( - // the call is made to the ProxyAdmin from address(0x1) - // when instead it should have been made from the TransparentUpgradeableProxy - address(implementationChanger), - address(new NewImplementation()), - abi.encodeCall(NewImplementation.initialize, ()) - ) { + try + proxyAdmin.changeImplementation( + // the call is made to the ProxyAdmin from address(0x1) + // when instead it should have been made from the TransparentUpgradeableProxy + address(implementationChanger), + address(new NewImplementation()), + abi.encodeCall(NewImplementation.initialize, ()) + ) + { // should never happen assertTrue(false); } catch {} assertFalse(implementationChanger.implementationChanged()); } -} \ No newline at end of file +} diff --git a/test/foundry/Delegation.t.sol b/test/foundry/Delegation.t.sol index 4537615f..c62ca978 100644 --- a/test/foundry/Delegation.t.sol +++ b/test/foundry/Delegation.t.sol @@ -20,10 +20,18 @@ contract DelegateTest is ExocoreDeployer { event MessageSent(GatewayStorage.Action indexed act, bytes32 packetId, uint64 nonce, uint256 nativeFee); event DelegateResult( - bool indexed success, address indexed delegator, string indexed delegatee, address token, uint256 amount + bool indexed success, + address indexed delegator, + string indexed delegatee, + address token, + uint256 amount ); - event UndelegateResult( - bool indexed success, address indexed undelegator, string indexed undelegatee, address token, uint256 amount + event UndelegateResult( + bool indexed success, + address indexed undelegator, + string indexed undelegatee, + address token, + uint256 amount ); event DelegateRequestProcessed( uint32 clientChainLzId, @@ -68,7 +76,12 @@ contract DelegateTest is ExocoreDeployer { _testUndelegate(delegator.addr, relayer.addr, operatorAddress, undelegateAmount); } - function _testDelegate(address delegator, address relayer, string memory operator, uint256 delegateAmount) internal { + function _testDelegate( + address delegator, + address relayer, + string memory operator, + uint256 delegateAmount + ) internal { /* ------------------------- delegate workflow test ------------------------- */ // 1. first user call client chain gateway to delegate @@ -146,7 +159,12 @@ contract DelegateTest is ExocoreDeployer { vm.stopPrank(); /// assert that DelegationMock contract should have recorded the delegate - uint256 actualDelegateAmount = DelegationMock(DELEGATION_PRECOMPILE_ADDRESS).getDelegateAmount(delegator, operator, clientChainId, address(restakeToken)); + uint256 actualDelegateAmount = DelegationMock(DELEGATION_PRECOMPILE_ADDRESS).getDelegateAmount( + delegator, + operator, + clientChainId, + address(restakeToken) + ); assertEq(actualDelegateAmount, delegateAmount); // 3. third layerzero relayers should watch the response message packet and relay the message to source chain endpoint @@ -167,9 +185,19 @@ contract DelegateTest is ExocoreDeployer { vm.stopPrank(); } - function _testUndelegate(address delegator, address relayer, string memory operator, uint256 undelegateAmount) internal { + function _testUndelegate( + address delegator, + address relayer, + string memory operator, + uint256 undelegateAmount + ) internal { /* ------------------------- undelegate workflow test ------------------------- */ - uint256 totalDelegate = DelegationMock(DELEGATION_PRECOMPILE_ADDRESS).getDelegateAmount(delegator, operator, clientChainId, address(restakeToken)); + uint256 totalDelegate = DelegationMock(DELEGATION_PRECOMPILE_ADDRESS).getDelegateAmount( + delegator, + operator, + clientChainId, + address(restakeToken) + ); require(undelegateAmount <= totalDelegate, "undelegate amount overflow"); // 1. first user call client chain gateway to undelegate @@ -247,7 +275,12 @@ contract DelegateTest is ExocoreDeployer { vm.stopPrank(); /// assert that DelegationMock contract should have recorded the undelegation - uint256 actualDelegateAmount = DelegationMock(DELEGATION_PRECOMPILE_ADDRESS).getDelegateAmount(delegator, operator, clientChainId, address(restakeToken)); + uint256 actualDelegateAmount = DelegationMock(DELEGATION_PRECOMPILE_ADDRESS).getDelegateAmount( + delegator, + operator, + clientChainId, + address(restakeToken) + ); assertEq(actualDelegateAmount, totalDelegate - undelegateAmount); // 3. third layerzero relayers should watch the response message packet and relay the message to source chain endpoint @@ -271,11 +304,19 @@ contract DelegateTest is ExocoreDeployer { function generateUID(uint64 nonce, bool fromClientChainToExocore) internal view returns (bytes32 uid) { if (fromClientChainToExocore) { uid = GUID.generate( - nonce, clientChainId, address(clientGateway), exocoreChainId, address(exocoreGateway).toBytes32() + nonce, + clientChainId, + address(clientGateway), + exocoreChainId, + address(exocoreGateway).toBytes32() ); } else { uid = GUID.generate( - nonce, exocoreChainId, address(exocoreGateway), clientChainId, address(clientGateway).toBytes32() + nonce, + exocoreChainId, + address(exocoreGateway), + clientChainId, + address(clientGateway).toBytes32() ); } } diff --git a/test/foundry/DepositWithdrawPrinciple.t.sol b/test/foundry/DepositWithdrawPrinciple.t.sol index 9088deef..ca76e52a 100644 --- a/test/foundry/DepositWithdrawPrinciple.t.sol +++ b/test/foundry/DepositWithdrawPrinciple.t.sol @@ -18,7 +18,10 @@ contract DepositWithdrawPrincipleTest is ExocoreDeployer { event DepositResult(bool indexed success, address indexed token, address indexed depositor, uint256 amount); event WithdrawPrincipleResult( - bool indexed success, address indexed token, address indexed withdrawer, uint256 amount + bool indexed success, + address indexed token, + address indexed withdrawer, + uint256 amount ); event Transfer(address indexed from, address indexed to, uint256 amount); event MessageSent(GatewayStorage.Action indexed act, bytes32 packetId, uint64 nonce, uint256 nativeFee); @@ -81,8 +84,12 @@ contract DepositWithdrawPrincipleTest is ExocoreDeployer { // exocore gateway should return response message to exocore network layerzero endpoint vm.expectEmit(true, true, true, true, address(exocoreLzEndpoint)); lastlyUpdatedPrincipleBalance = depositAmount; - bytes memory depositResponsePayload = - abi.encodePacked(GatewayStorage.Action.RESPOND, uint64(1), true, lastlyUpdatedPrincipleBalance); + bytes memory depositResponsePayload = abi.encodePacked( + GatewayStorage.Action.RESPOND, + uint64(1), + true, + lastlyUpdatedPrincipleBalance + ); uint256 depositResponseNativeFee = exocoreGateway.quote(clientChainId, depositResponsePayload); bytes32 depositResponseId = generateUID(1, false); emit NewPacket( @@ -149,7 +156,8 @@ contract DepositWithdrawPrincipleTest is ExocoreDeployer { withdrawRequestNativeFee ); clientGateway.withdrawPrincipleFromExocore{value: withdrawRequestNativeFee}( - address(restakeToken), withdrawAmount + address(restakeToken), + withdrawAmount ); // second layerzero relayers should watch the request message packet and relay the message to destination endpoint @@ -157,8 +165,12 @@ contract DepositWithdrawPrincipleTest is ExocoreDeployer { // exocore gateway should return response message to exocore network layerzero endpoint vm.expectEmit(true, true, true, true, address(exocoreLzEndpoint)); lastlyUpdatedPrincipleBalance -= withdrawAmount; - bytes memory withdrawResponsePayload = - abi.encodePacked(GatewayStorage.Action.RESPOND, uint64(2), true, lastlyUpdatedPrincipleBalance); + bytes memory withdrawResponsePayload = abi.encodePacked( + GatewayStorage.Action.RESPOND, + uint64(2), + true, + lastlyUpdatedPrincipleBalance + ); uint256 withdrawResponseNativeFee = exocoreGateway.quote(clientChainId, withdrawResponsePayload); bytes32 withdrawResponseId = generateUID(2, false); emit NewPacket( @@ -207,7 +219,9 @@ contract DepositWithdrawPrincipleTest is ExocoreDeployer { // before native stake and deposit, we simulate proper block environment states to make proof valid /// we set the timestamp of proof to be exactly the timestamp that the validator container get activated on beacon chain - uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + _getActivationEpoch(validatorContainer) * SECONDS_PER_EPOCH; + uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + + _getActivationEpoch(validatorContainer) * + SECONDS_PER_EPOCH; mockProofTimestamp = activationTimestamp; validatorProof.beaconBlockTimestamp = mockProofTimestamp; @@ -223,11 +237,13 @@ contract DepositWithdrawPrincipleTest is ExocoreDeployer { ); // 1. firstly depositor should stake to beacon chain by depositing 32 ETH to ETHPOS contract - ExoCapsule expectedCapsule = ExoCapsule(Create2.computeAddress( - bytes32(uint256(uint160(depositor.addr))), - keccak256(abi.encodePacked(BEACON_PROXY_BYTECODE, abi.encode(address(capsuleBeacon), ""))), - address(clientGateway) - )); + ExoCapsule expectedCapsule = ExoCapsule( + Create2.computeAddress( + bytes32(uint256(uint160(depositor.addr))), + keccak256(abi.encodePacked(BEACON_PROXY_BYTECODE, abi.encode(address(capsuleBeacon), ""))), + address(clientGateway) + ) + ); vm.expectEmit(true, true, true, true, address(clientGateway)); emit CapsuleCreated(depositor.addr, address(expectedCapsule)); emit StakedWithCapsule(depositor.addr, address(expectedCapsule)); @@ -246,11 +262,7 @@ contract DepositWithdrawPrincipleTest is ExocoreDeployer { /// replace expectedCapsule with capsule bytes32 capsuleSlotInGateway = bytes32( - stdstore - .target(address(clientGatewayLogic)) - .sig("ownerToCapsule(address)") - .with_key(depositor.addr) - .find() + stdstore.target(address(clientGatewayLogic)).sig("ownerToCapsule(address)").with_key(depositor.addr).find() ); vm.store(address(clientGateway), capsuleSlotInGateway, bytes32(uint256(uint160(address(capsule))))); assertEq(address(clientGateway.ownerToCapsule(depositor.addr)), address(capsule)); @@ -293,8 +305,12 @@ contract DepositWithdrawPrincipleTest is ExocoreDeployer { /// exocore gateway should return response message to exocore network layerzero endpoint uint256 lastlyUpdatedPrincipleBalance = depositAmount; - bytes memory depositResponsePayload = - abi.encodePacked(GatewayStorage.Action.RESPOND, uint64(1), true, lastlyUpdatedPrincipleBalance); + bytes memory depositResponsePayload = abi.encodePacked( + GatewayStorage.Action.RESPOND, + uint64(1), + true, + lastlyUpdatedPrincipleBalance + ); uint256 depositResponseNativeFee = exocoreGateway.quote(clientChainId, depositResponsePayload); bytes32 depositResponseId = generateUID(1, false); @@ -343,11 +359,19 @@ contract DepositWithdrawPrincipleTest is ExocoreDeployer { function generateUID(uint64 nonce, bool fromClientChainToExocore) internal view returns (bytes32 uid) { if (fromClientChainToExocore) { uid = GUID.generate( - nonce, clientChainId, address(clientGateway), exocoreChainId, address(exocoreGateway).toBytes32() + nonce, + clientChainId, + address(clientGateway), + exocoreChainId, + address(exocoreGateway).toBytes32() ); } else { uid = GUID.generate( - nonce, exocoreChainId, address(exocoreGateway), clientChainId, address(clientGateway).toBytes32() + nonce, + exocoreChainId, + address(exocoreGateway), + clientChainId, + address(clientGateway).toBytes32() ); } } diff --git a/test/foundry/ExoCapsule.t.sol b/test/foundry/ExoCapsule.t.sol index 58484e61..75be16bf 100644 --- a/test/foundry/ExoCapsule.t.sol +++ b/test/foundry/ExoCapsule.t.sol @@ -39,7 +39,7 @@ contract SetUp is Test { uint64 internal constant SLOTS_PER_EPOCH = 32; /// @notice The number of seconds in a slot in the beacon chain uint64 internal constant SECONDS_PER_SLOT = 12; - /// @notice Number of seconds per epoch: 384 == 32 slots/epoch * 12 seconds/slot + /// @notice Number of seconds per epoch: 384 == 32 slots/epoch * 12 seconds/slot uint64 internal constant SECONDS_PER_EPOCH = SLOTS_PER_EPOCH * SECONDS_PER_SLOT; uint256 internal constant VERIFY_BALANCE_UPDATE_WINDOW_SECONDS = 4.5 hours; @@ -54,9 +54,15 @@ contract SetUp is Test { validatorProof.stateRoot = stdJson.readBytes32(validatorInfo, ".beaconStateRoot"); require(validatorProof.stateRoot != bytes32(0), "state root should not be empty"); - validatorProof.stateRootProof = stdJson.readBytes32Array(validatorInfo, ".StateRootAgainstLatestBlockHeaderProof"); + validatorProof.stateRootProof = stdJson.readBytes32Array( + validatorInfo, + ".StateRootAgainstLatestBlockHeaderProof" + ); require(validatorProof.stateRootProof.length == 3, "state root proof should have 3 nodes"); - validatorProof.validatorContainerRootProof = stdJson.readBytes32Array(validatorInfo, ".WithdrawalCredentialProof"); + validatorProof.validatorContainerRootProof = stdJson.readBytes32Array( + validatorInfo, + ".WithdrawalCredentialProof" + ); require(validatorProof.validatorContainerRootProof.length == 46, "validator root proof should have 46 nodes"); validatorProof.validatorIndex = stdJson.readUint(validatorInfo, ".validatorIndex"); require(validatorProof.validatorIndex != 0, "validator root index should not be 0"); @@ -80,7 +86,9 @@ contract SetUp is Test { stdstore.target(capsuleAddress).sig("capsuleOwner()").checked_write(bytes32(uint256(uint160(capsuleOwner)))); - stdstore.target(capsuleAddress).sig("beaconOracle()").checked_write(bytes32(uint256(uint160(address(beaconOracle))))); + stdstore.target(capsuleAddress).sig("beaconOracle()").checked_write( + bytes32(uint256(uint160(address(beaconOracle)))) + ); } function _getCapsuleFromWithdrawalCredentials(bytes32 withdrawalCredentials) internal pure returns (address) { @@ -113,7 +121,9 @@ contract VerifyDepositProof is SetUp { using stdStorage for StdStorage; function test_verifyDepositProof_success() public { - uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + _getActivationEpoch(validatorContainer) * SECONDS_PER_EPOCH; + uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + + _getActivationEpoch(validatorContainer) * + SECONDS_PER_EPOCH; mockProofTimestamp = activationTimestamp; mockCurrentBlockTimestamp = mockProofTimestamp + SECONDS_PER_SLOT; vm.warp(mockCurrentBlockTimestamp); @@ -127,7 +137,9 @@ contract VerifyDepositProof is SetUp { capsule.verifyDepositProof(validatorContainer, validatorProof); - ExoCapsuleStorage.Validator memory validator = capsule.getRegisteredValidatorByPubkey(_getPubkey(validatorContainer)); + ExoCapsuleStorage.Validator memory validator = capsule.getRegisteredValidatorByPubkey( + _getPubkey(validatorContainer) + ); assertEq(uint8(validator.status), uint8(ExoCapsuleStorage.VALIDATOR_STATUS.REGISTERED)); assertEq(validator.validatorIndex, validatorProof.validatorIndex); assertEq(validator.mostRecentBalanceUpdateTimestamp, validatorProof.beaconBlockTimestamp); @@ -135,7 +147,9 @@ contract VerifyDepositProof is SetUp { } function test_verifyDepositProof_revert_validatorAlreadyDeposited() public { - uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + _getActivationEpoch(validatorContainer) * SECONDS_PER_EPOCH; + uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + + _getActivationEpoch(validatorContainer) * + SECONDS_PER_EPOCH; mockProofTimestamp = activationTimestamp; mockCurrentBlockTimestamp = mockProofTimestamp + SECONDS_PER_SLOT; vm.warp(mockCurrentBlockTimestamp); @@ -150,12 +164,16 @@ contract VerifyDepositProof is SetUp { capsule.verifyDepositProof(validatorContainer, validatorProof); // deposit again should revert - vm.expectRevert(abi.encodeWithSelector(ExoCapsule.DoubleDepositedValidator.selector, _getPubkey(validatorContainer))); + vm.expectRevert( + abi.encodeWithSelector(ExoCapsule.DoubleDepositedValidator.selector, _getPubkey(validatorContainer)) + ); capsule.verifyDepositProof(validatorContainer, validatorProof); } function test_verifyDepositProof_revert_staleProof() public { - uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + _getActivationEpoch(validatorContainer) * SECONDS_PER_EPOCH; + uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + + _getActivationEpoch(validatorContainer) * + SECONDS_PER_EPOCH; mockProofTimestamp = activationTimestamp + 1 hours; mockCurrentBlockTimestamp = mockProofTimestamp + VERIFY_BALANCE_UPDATE_WINDOW_SECONDS + 1 seconds; vm.warp(mockCurrentBlockTimestamp); @@ -168,12 +186,20 @@ contract VerifyDepositProof is SetUp { ); // deposit should revert because of proof is stale - vm.expectRevert(abi.encodeWithSelector(ExoCapsule.StaleValidatorContainer.selector, _getPubkey(validatorContainer), mockProofTimestamp)); + vm.expectRevert( + abi.encodeWithSelector( + ExoCapsule.StaleValidatorContainer.selector, + _getPubkey(validatorContainer), + mockProofTimestamp + ) + ); capsule.verifyDepositProof(validatorContainer, validatorProof); } function test_verifyDepositProof_revert_malformedValidatorContainer() public { - uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + _getActivationEpoch(validatorContainer) * SECONDS_PER_EPOCH; + uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + + _getActivationEpoch(validatorContainer) * + SECONDS_PER_EPOCH; mockProofTimestamp = activationTimestamp; mockCurrentBlockTimestamp = mockProofTimestamp + SECONDS_PER_SLOT; vm.warp(mockCurrentBlockTimestamp); @@ -189,18 +215,24 @@ contract VerifyDepositProof is SetUp { // construct malformed validator container that has extra fields validatorContainer.push(bytes32(uint256(123))); - vm.expectRevert(abi.encodeWithSelector(ExoCapsule.InvalidValidatorContainer.selector, _getPubkey(validatorContainer))); + vm.expectRevert( + abi.encodeWithSelector(ExoCapsule.InvalidValidatorContainer.selector, _getPubkey(validatorContainer)) + ); capsule.verifyDepositProof(validatorContainer, validatorProof); vm.revertTo(snapshot); // construct malformed validator container that misses fields validatorContainer.pop(); - vm.expectRevert(abi.encodeWithSelector(ExoCapsule.InvalidValidatorContainer.selector, _getPubkey(validatorContainer))); + vm.expectRevert( + abi.encodeWithSelector(ExoCapsule.InvalidValidatorContainer.selector, _getPubkey(validatorContainer)) + ); capsule.verifyDepositProof(validatorContainer, validatorProof); } function test_verifyDepositProof_revert_inactiveValidatorContainer() public { - uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + _getActivationEpoch(validatorContainer) * SECONDS_PER_EPOCH; + uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + + _getActivationEpoch(validatorContainer) * + SECONDS_PER_EPOCH; vm.mockCall( address(beaconOracle), @@ -213,12 +245,16 @@ contract VerifyDepositProof is SetUp { mockCurrentBlockTimestamp = mockProofTimestamp + SECONDS_PER_SLOT; vm.warp(mockCurrentBlockTimestamp); validatorProof.beaconBlockTimestamp = mockProofTimestamp; - vm.expectRevert(abi.encodeWithSelector(ExoCapsule.InactiveValidatorContainer.selector, _getPubkey(validatorContainer))); + vm.expectRevert( + abi.encodeWithSelector(ExoCapsule.InactiveValidatorContainer.selector, _getPubkey(validatorContainer)) + ); capsule.verifyDepositProof(validatorContainer, validatorProof); } function test_verifyDepositProof_revert_mismatchWithdrawalCredentials() public { - uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + _getActivationEpoch(validatorContainer) * SECONDS_PER_EPOCH; + uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + + _getActivationEpoch(validatorContainer) * + SECONDS_PER_EPOCH; mockProofTimestamp = activationTimestamp; mockCurrentBlockTimestamp = mockProofTimestamp + SECONDS_PER_SLOT; vm.warp(mockCurrentBlockTimestamp); @@ -247,7 +283,9 @@ contract VerifyDepositProof is SetUp { } function test_verifyDepositProof_revert_proofNotMatchWithBeaconRoot() public { - uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + _getActivationEpoch(validatorContainer) * SECONDS_PER_EPOCH; + uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + + _getActivationEpoch(validatorContainer) * + SECONDS_PER_EPOCH; mockProofTimestamp = activationTimestamp; mockCurrentBlockTimestamp = mockProofTimestamp + SECONDS_PER_SLOT; vm.warp(mockCurrentBlockTimestamp); @@ -261,7 +299,9 @@ contract VerifyDepositProof is SetUp { ); // verify proof against mismatch beacon block root - vm.expectRevert(abi.encodeWithSelector(ExoCapsule.InvalidValidatorContainer.selector, _getPubkey(validatorContainer))); + vm.expectRevert( + abi.encodeWithSelector(ExoCapsule.InvalidValidatorContainer.selector, _getPubkey(validatorContainer)) + ); capsule.verifyDepositProof(validatorContainer, validatorProof); } -} \ No newline at end of file +} diff --git a/test/foundry/ExocoreDeployer.t.sol b/test/foundry/ExocoreDeployer.t.sol index a922ecb0..f77a96d8 100644 --- a/test/foundry/ExocoreDeployer.t.sol +++ b/test/foundry/ExocoreDeployer.t.sol @@ -56,7 +56,7 @@ contract ExocoreDeployer is Test { uint64 internal constant SLOTS_PER_EPOCH = 32; /// @notice The number of seconds in a slot in the beacon chain uint64 internal constant SECONDS_PER_SLOT = 12; - /// @notice Number of seconds per epoch: 384 == 32 slots/epoch * 12 seconds/slot + /// @notice Number of seconds per epoch: 384 == 32 slots/epoch * 12 seconds/slot uint64 internal constant SECONDS_PER_EPOCH = SLOTS_PER_EPOCH * SECONDS_PER_SLOT; uint256 internal constant VERIFY_BALANCE_UPDATE_WINDOW_SECONDS = 4.5 hours; uint256 constant GWEI_TO_WEI = 1e9; @@ -106,9 +106,15 @@ contract ExocoreDeployer is Test { validatorProof.stateRoot = stdJson.readBytes32(validatorInfo, ".beaconStateRoot"); require(validatorProof.stateRoot != bytes32(0), "state root should not be empty"); - validatorProof.stateRootProof = stdJson.readBytes32Array(validatorInfo, ".StateRootAgainstLatestBlockHeaderProof"); + validatorProof.stateRootProof = stdJson.readBytes32Array( + validatorInfo, + ".StateRootAgainstLatestBlockHeaderProof" + ); require(validatorProof.stateRootProof.length == 3, "state root proof should have 3 nodes"); - validatorProof.validatorContainerRootProof = stdJson.readBytes32Array(validatorInfo, ".WithdrawalCredentialProof"); + validatorProof.validatorContainerRootProof = stdJson.readBytes32Array( + validatorInfo, + ".WithdrawalCredentialProof" + ); require(validatorProof.validatorContainerRootProof.length == 46, "validator root proof should have 46 nodes"); validatorProof.validatorIndex = stdJson.readUint(validatorInfo, ".validatorIndex"); require(validatorProof.validatorIndex != 0, "validator root index should not be 0"); @@ -146,7 +152,7 @@ contract ExocoreDeployer is Test { // deploy and initialize client chain contracts whitelistTokens.push(address(restakeToken)); - + ProxyAdmin proxyAdmin = new ProxyAdmin(); clientGatewayLogic = new ClientChainGateway( address(clientChainLzEndpoint), @@ -184,7 +190,8 @@ contract ExocoreDeployer is Test { address(exocoreGatewayLogic), address(proxyAdmin), abi.encodeWithSelector( - exocoreGatewayLogic.initialize.selector, payable(exocoreValidatorSet.addr) + exocoreGatewayLogic.initialize.selector, + payable(exocoreValidatorSet.addr) ) ) ) @@ -193,10 +200,12 @@ contract ExocoreDeployer is Test { // set the destination endpoint for corresponding destinations in endpoint mock NonShortCircuitEndpointV2Mock(address(clientChainLzEndpoint)).setDestLzEndpoint( - address(exocoreGateway), address(exocoreLzEndpoint) + address(exocoreGateway), + address(exocoreLzEndpoint) ); NonShortCircuitEndpointV2Mock(address(exocoreLzEndpoint)).setDestLzEndpoint( - address(clientGateway), address(clientChainLzEndpoint) + address(clientGateway), + address(clientChainLzEndpoint) ); // Exocore validator set should be the owner of gateway contracts and only owner could call these functions. @@ -227,13 +236,13 @@ contract ExocoreDeployer is Test { // mainnet if (block.chainid == 1) { GENESIS_BLOCK_TIMESTAMP = 1606824023; - // goerli + // goerli } else if (block.chainid == 5) { GENESIS_BLOCK_TIMESTAMP = 1616508000; - // sepolia + // sepolia } else if (block.chainid == 11155111) { GENESIS_BLOCK_TIMESTAMP = 1655733600; - // holesky + // holesky } else if (block.chainid == 17000) { GENESIS_BLOCK_TIMESTAMP = 1695902400; } else { diff --git a/test/foundry/ExocoreGateway.t.sol b/test/foundry/ExocoreGateway.t.sol index 942ea33b..3b03dba8 100644 --- a/test/foundry/ExocoreGateway.t.sol +++ b/test/foundry/ExocoreGateway.t.sol @@ -79,9 +79,7 @@ contract SetUp is Test { vm.prank(exocoreValidatorSet.addr); exocoreGateway.setPeer(clientChainId, address(clientGateway).toBytes32()); - exocoreLzEndpoint.setDestLzEndpoint( - address(clientGateway), address(clientLzEndpoint) - ); + exocoreLzEndpoint.setDestLzEndpoint(address(clientGateway), address(clientLzEndpoint)); // transfer some gas fee to exocore gateway as it has to pay for the relay fee to layerzero endpoint when sending back response deal(address(exocoreGateway), 1e22); @@ -103,7 +101,7 @@ contract SetUp is Test { contract Pausable is SetUp { using AddressCast for address; - + function test_PauseExocoreGateway() public { vm.expectEmit(true, true, true, true, address(exocoreGateway)); emit Paused(exocoreValidatorSet.addr); @@ -158,16 +156,10 @@ contract LzReceive is SetUp { abi.encodePacked(bytes32(bytes20(withdrawer.addr))), uint256(WITHDRAWAL_AMOUNT) ); - bytes memory msg_ = abi.encodePacked( - GatewayStorage.Action.REQUEST_WITHDRAW_PRINCIPLE_FROM_EXOCORE, - payload - ); + bytes memory msg_ = abi.encodePacked(GatewayStorage.Action.REQUEST_WITHDRAW_PRINCIPLE_FROM_EXOCORE, payload); vm.expectEmit(true, true, true, true, address(exocoreGateway)); - emit ExocorePrecompileError( - WITHDRAW_PRECOMPILE_ADDRESS, - uint64(1) - ); + emit ExocorePrecompileError(WITHDRAW_PRECOMPILE_ADDRESS, uint64(1)); vm.prank(address(exocoreLzEndpoint)); exocoreGateway.lzReceive( @@ -178,4 +170,4 @@ contract LzReceive is SetUp { bytes("") ); } -} \ No newline at end of file +} diff --git a/test/foundry/MyToken.sol b/test/foundry/MyToken.sol index 19adad31..e3092656 100644 --- a/test/foundry/MyToken.sol +++ b/test/foundry/MyToken.sol @@ -7,11 +7,14 @@ contract MyToken is ERC20Burnable { uint8 private _decimals; constructor( - string memory name, string memory symbol, uint8 customDecimals, - address[] memory initialAddresses, uint256 initialBalance + string memory name, + string memory symbol, + uint8 customDecimals, + address[] memory initialAddresses, + uint256 initialBalance ) ERC20(name, symbol) { _mint(msg.sender, initialBalance * 100); - for(uint256 i = 0; i < initialAddresses.length; i++) { + for (uint256 i = 0; i < initialAddresses.length; i++) { _mint(initialAddresses[i], initialBalance); } _decimals = customDecimals; diff --git a/test/foundry/WithdrawReward.t.sol b/test/foundry/WithdrawReward.t.sol index 9db86028..8f45faa9 100644 --- a/test/foundry/WithdrawReward.t.sol +++ b/test/foundry/WithdrawReward.t.sol @@ -45,12 +45,19 @@ contract WithdrawRewardTest is ExocoreDeployer { // client chain layerzero endpoint should emit the message packet including withdraw payload. vm.expectEmit(true, true, true, true, address(clientChainLzEndpoint)); emit NewPacket( - exocoreChainId, address(clientGateway), address(exocoreGateway).toBytes32(), 1, withdrawRequestPayload + exocoreChainId, + address(clientGateway), + address(exocoreGateway).toBytes32(), + 1, + withdrawRequestPayload ); // client chain gateway should emit MessageSent event vm.expectEmit(true, true, true, true, address(clientGateway)); emit MessageSent( - GatewayStorage.Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE, requestId, uint64(1), requestNativeFee + GatewayStorage.Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE, + requestId, + uint64(1), + requestNativeFee ); clientGateway.withdrawRewardFromExocore{value: requestNativeFee}(address(restakeToken), withdrawAmount); @@ -58,8 +65,12 @@ contract WithdrawRewardTest is ExocoreDeployer { // exocore gateway should return response message to exocore network layerzero endpoint vm.expectEmit(true, true, true, true, address(exocoreLzEndpoint)); - bytes memory withdrawResponsePayload = - abi.encodePacked(GatewayStorage.Action.RESPOND, uint64(1), true, uint256(1234)); + bytes memory withdrawResponsePayload = abi.encodePacked( + GatewayStorage.Action.RESPOND, + uint64(1), + true, + uint256(1234) + ); uint256 responseNativeFee = exocoreGateway.quote(clientChainId, withdrawResponsePayload); bytes32 responseId = generateUID(1, false); emit NewPacket( @@ -97,11 +108,19 @@ contract WithdrawRewardTest is ExocoreDeployer { function generateUID(uint64 nonce, bool fromClientChainToExocore) internal view returns (bytes32 uid) { if (fromClientChainToExocore) { uid = GUID.generate( - nonce, clientChainId, address(clientGateway), exocoreChainId, address(exocoreGateway).toBytes32() + nonce, + clientChainId, + address(clientGateway), + exocoreChainId, + address(exocoreGateway).toBytes32() ); } else { uid = GUID.generate( - nonce, exocoreChainId, address(exocoreGateway), clientChainId, address(clientGateway).toBytes32() + nonce, + exocoreChainId, + address(exocoreGateway), + clientChainId, + address(clientGateway).toBytes32() ); } } diff --git a/test/mocks/ClaimRewardMock.sol b/test/mocks/ClaimRewardMock.sol index 2b7beec5..bf58b2be 100644 --- a/test/mocks/ClaimRewardMock.sol +++ b/test/mocks/ClaimRewardMock.sol @@ -3,10 +3,12 @@ pragma solidity ^0.8.19; import {IClaimReward} from "../../src/interfaces/precompiles/IClaimReward.sol"; contract ClaimRewardMock is IClaimReward { - function claimReward(uint32 clientChainLzId, bytes memory assetsAddress, bytes memory withdrawer, uint256 opAmount) - external - returns (bool success, uint256 latestAssetState) - { + function claimReward( + uint32 clientChainLzId, + bytes memory assetsAddress, + bytes memory withdrawer, + uint256 opAmount + ) external returns (bool success, uint256 latestAssetState) { require(assetsAddress.length == 32, "invalid asset address"); require(withdrawer.length == 32, "invalid withdrawer address"); return (true, uint256(1234)); diff --git a/test/mocks/DelegationMock.sol b/test/mocks/DelegationMock.sol index 473ded91..8a2bf5f7 100644 --- a/test/mocks/DelegationMock.sol +++ b/test/mocks/DelegationMock.sol @@ -35,7 +35,12 @@ contract DelegationMock is IDelegation { require(operatorAddr.length == 42, "invalid operator address"); delegateTo[stakerAddress][operatorAddr][clientChainLzId][assetsAddress] += opAmount; emit DelegateRequestProcessed( - clientChainLzId, lzNonce, assetsAddress, stakerAddress, string(operatorAddr), opAmount + clientChainLzId, + lzNonce, + assetsAddress, + stakerAddress, + string(operatorAddr), + opAmount ); return true; @@ -55,13 +60,23 @@ contract DelegationMock is IDelegation { require(opAmount <= delegateTo[stakerAddress][operatorAddr][clientChainLzId][assetsAddress], "amount overflow"); delegateTo[stakerAddress][operatorAddr][clientChainLzId][assetsAddress] -= opAmount; emit UndelegateRequestProcessed( - clientChainLzId, lzNonce, assetsAddress, stakerAddress, string(operatorAddr), opAmount + clientChainLzId, + lzNonce, + assetsAddress, + stakerAddress, + string(operatorAddr), + opAmount ); return true; } - function getDelegateAmount(address delegator, string memory operator, uint32 clientChainLzId, address token) public view returns (uint256) { + function getDelegateAmount( + address delegator, + string memory operator, + uint32 clientChainLzId, + address token + ) public view returns (uint256) { return delegateTo[_addressToBytes(delegator)][bytes(operator)][clientChainLzId][_addressToBytes(token)]; } diff --git a/test/mocks/DepositMock.sol b/test/mocks/DepositMock.sol index a21ecb4d..efa6910e 100644 --- a/test/mocks/DepositMock.sol +++ b/test/mocks/DepositMock.sol @@ -11,14 +11,16 @@ contract DepositMock is IDeposit { bytes memory assetsAddress, bytes memory stakerAddress, uint256 opAmount - ) - external - returns (bool success,uint256 latestAssetState) - { + ) external returns (bool success, uint256 latestAssetState) { require(assetsAddress.length == 32, "invalid asset address"); require(stakerAddress.length == 32, "invalid staker address"); principleBalances[clientChainLzId][assetsAddress][stakerAddress] += opAmount; - WithdrawPrincipleMock(WITHDRAW_PRECOMPILE_ADDRESS).depositTo(clientChainLzId, assetsAddress, stakerAddress, opAmount); + WithdrawPrincipleMock(WITHDRAW_PRECOMPILE_ADDRESS).depositTo( + clientChainLzId, + assetsAddress, + stakerAddress, + opAmount + ); return (true, principleBalances[clientChainLzId][assetsAddress][stakerAddress]); } @@ -27,11 +29,8 @@ contract DepositMock is IDeposit { bytes memory assetsAddress, bytes memory withdrawer, uint256 opAmount - ) - external - returns (bool success,uint256 latestAssetState) - { + ) external returns (bool success, uint256 latestAssetState) { require(opAmount <= principleBalances[clientChainLzId][assetsAddress][withdrawer], "withdraw amount overflow"); principleBalances[clientChainLzId][assetsAddress][withdrawer] -= opAmount; } -} \ No newline at end of file +} diff --git a/test/mocks/DepositWithdrawMock.sol b/test/mocks/DepositWithdrawMock.sol index 6e49a73b..1bc56530 100644 --- a/test/mocks/DepositWithdrawMock.sol +++ b/test/mocks/DepositWithdrawMock.sol @@ -6,10 +6,12 @@ import {IWithdraw} from "../../src/interfaces/precompiles/IWithdrawPrinciple.sol contract DepositWithdrawMock is IDeposit, IWithdraw { mapping(uint32 => mapping(bytes => mapping(bytes => uint256))) public principleBalances; - function depositTo(uint32 clientChainLzId, bytes memory assetsAddress, bytes memory stakerAddress, uint256 opAmount) - external - returns (bool success, uint256 latestAssetState) - { + function depositTo( + uint32 clientChainLzId, + bytes memory assetsAddress, + bytes memory stakerAddress, + uint256 opAmount + ) external returns (bool success, uint256 latestAssetState) { require(assetsAddress.length == 32, "invalid asset address"); require(stakerAddress.length == 32, "invalid staker address"); principleBalances[clientChainLzId][assetsAddress][stakerAddress] += opAmount; diff --git a/test/mocks/ETHPOSDepositMock.sol b/test/mocks/ETHPOSDepositMock.sol index 8dee88c1..4250b848 100644 --- a/test/mocks/ETHPOSDepositMock.sol +++ b/test/mocks/ETHPOSDepositMock.sol @@ -3,7 +3,6 @@ pragma solidity ^0.8.19; import "src/interfaces/IETHPOSDeposit.sol"; contract ETHPOSDepositMock is IETHPOSDeposit { - function deposit( bytes calldata pubkey, bytes calldata withdrawal_credentials, @@ -11,7 +10,6 @@ contract ETHPOSDepositMock is IETHPOSDeposit { bytes32 deposit_data_root ) external payable {} - function get_deposit_root() external pure returns (bytes32) { bytes32 root; return root; @@ -24,4 +22,3 @@ contract ETHPOSDepositMock is IETHPOSDeposit { return root; } } - diff --git a/test/mocks/EndpointV2Mock.sol b/test/mocks/EndpointV2Mock.sol index a230117a..a1e1eb8c 100644 --- a/test/mocks/EndpointV2Mock.sol +++ b/test/mocks/EndpointV2Mock.sol @@ -2,13 +2,7 @@ pragma solidity 0.8.22; import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; -import { - ILayerZeroEndpointV2, - MessagingParams, - MessagingReceipt, - MessagingFee, - Origin -} from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; +import {ILayerZeroEndpointV2, MessagingParams, MessagingReceipt, MessagingFee, Origin} from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; import {ExecutionState} from "@layerzerolabs/lz-evm-protocol-v2/contracts/EndpointV2ViewUpgradeable.sol"; import {ILayerZeroReceiver} from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol"; import {SetConfigParam} from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLibManager.sol"; @@ -39,12 +33,10 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { uint32 public immutable eid; mapping(address => address) public lzEndpointLookup; - mapping(address receiver => mapping(uint32 srcEid => mapping(bytes32 sender => uint64 nonce))) public - lazyInboundNonce; - mapping( - address receiver - => mapping(uint32 srcEid => mapping(bytes32 sender => mapping(uint64 inboundNonce => bytes32 payloadHash))) - ) public inboundPayloadHash; + mapping(address receiver => mapping(uint32 srcEid => mapping(bytes32 sender => uint64 nonce))) + public lazyInboundNonce; + mapping(address receiver => mapping(uint32 srcEid => mapping(bytes32 sender => mapping(uint64 inboundNonce => bytes32 payloadHash)))) + public inboundPayloadHash; mapping(address sender => mapping(uint32 dstEid => mapping(bytes32 receiver => uint64 nonce))) public outboundNonce; RelayerFeeConfig public relayerFeeConfig; @@ -91,12 +83,10 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { verifierFee = 1e16; } - function send(MessagingParams calldata _params, address _refundAddress) - public - payable - sendContext(_params.dstEid, msg.sender) - returns (MessagingReceipt memory receipt) - { + function send( + MessagingParams calldata _params, + address _refundAddress + ) public payable sendContext(_params.dstEid, msg.sender) returns (MessagingReceipt memory receipt) { if (_params.payInLzToken) revert Errors.LZ_LzTokenUnavailable(); address lzEndpoint = lzEndpointLookup[_params.receiver.bytes32ToAddress()]; @@ -122,7 +112,7 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { // refund if they send too much uint256 amount = msg.value - receipt.fee.nativeFee; if (amount > 0) { - (bool success,) = _refundAddress.call{value: amount}(""); + (bool success, ) = _refundAddress.call{value: amount}(""); require(success, "LayerZeroMock: failed to refund"); } @@ -133,14 +123,23 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { // TODO fix // composed calls with correct gas - Origin memory origin = - Origin({srcEid: packet.srcEid, sender: packet.sender.addressToBytes32(), nonce: packet.nonce}); + Origin memory origin = Origin({ + srcEid: packet.srcEid, + sender: packet.sender.addressToBytes32(), + nonce: packet.nonce + }); bytes memory payload = PacketV1Codec.encodePayload(packet); bytes32 payloadHash = keccak256(payload); EndpointV2Mock(lzEndpoint).receivePayload{value: dstAmount}( - origin, packet.receiver.bytes32ToAddress(), payloadHash, packet.message, totalGas, dstAmount, packet.guid + origin, + packet.receiver.bytes32ToAddress(), + payloadHash, + packet.message, + totalGas, + dstAmount, + packet.guid ); } @@ -155,12 +154,23 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { ) external payable receiveNonReentrant { inboundPayloadHash[_receiver][_origin.srcEid][_origin.sender][_origin.nonce] = _payloadHash; if (_msgValue > 0) { - try ILayerZeroReceiver(_receiver).lzReceive{value: _msgValue, gas: _gas}( - _origin, _guid, _message, address(0), "" - ) {} catch (bytes memory) /*reason*/ {} + try + ILayerZeroReceiver(_receiver).lzReceive{value: _msgValue, gas: _gas}( + _origin, + _guid, + _message, + address(0), + "" + ) + {} catch (bytes memory) /*reason*/ { + + } } else { - try ILayerZeroReceiver(_receiver).lzReceive{gas: _gas}(_origin, _guid, _message, address(0), "") {} - catch (bytes memory) /*reason*/ {} + try ILayerZeroReceiver(_receiver).lzReceive{gas: _gas}(_origin, _guid, _message, address(0), "") {} catch ( + bytes memory + ) /*reason*/ { + + } } } @@ -179,20 +189,18 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { uint256 basePrice = (nativeFee * relayerFeeConfig.dstPriceRatio) / 10 ** 10; // pricePerByte = (dstGasPriceInWei * gasPerBytes) * tokenConversionRate - uint256 pricePerByte = ( - (relayerFeeConfig.dstGasPriceInWei * relayerFeeConfig.gasPerByte * relayerFeeConfig.dstPriceRatio) - / 10 ** 10 - ) * _payloadSize; + uint256 pricePerByte = ((relayerFeeConfig.dstGasPriceInWei * + relayerFeeConfig.gasPerByte * + relayerFeeConfig.dstPriceRatio) / 10 ** 10) * _payloadSize; return basePrice + pricePerByte; } - function _quote(MessagingParams calldata _params, address /*_sender*/ ) - internal - view - returns (MessagingFee memory messagingFee) - { - (bytes memory executorOptions,) = splitOptions(_params.options); + function _quote( + MessagingParams calldata _params, + address /*_sender*/ + ) internal view returns (MessagingFee memory messagingFee) { + (bytes memory executorOptions, ) = splitOptions(_params.options); // 2) get Executor fee uint256 executorFee = this.getExecutorFee(_params.message.length, executorOptions); @@ -219,11 +227,9 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { lzEndpointLookup[destAddr] = lzEndpointAddr; } - function _decodeExecutorOptions(bytes calldata _options) - internal - view - returns (uint256 dstAmount, uint256 totalGas) - { + function _decodeExecutorOptions( + bytes calldata _options + ) internal view returns (uint256 dstAmount, uint256 totalGas) { if (_options.length == 0) { revert IExecutorFeeLib.Executor_NoOptions(); } @@ -240,7 +246,7 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { dstAmount += value; totalGas += gas; } else if (optionType == ExecutorOptions.OPTION_TYPE_NATIVE_DROP) { - (uint128 nativeDropAmount,) = ExecutorOptions.decodeNativeDropOption(option); + (uint128 nativeDropAmount, ) = ExecutorOptions.decodeNativeDropOption(option); dstAmount += nativeDropAmount; } else if (optionType == ExecutorOptions.OPTION_TYPE_LZCOMPOSE) { (, uint128 gas, uint128 value) = ExecutorOptions.decodeLzComposeOption(option); @@ -269,11 +275,9 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { return (executorOpts, workerOpts); } - function decode(bytes calldata _options) - internal - pure - returns (bytes memory executorOptions, bytes memory dvnOptions) - { + function decode( + bytes calldata _options + ) internal pure returns (bytes memory executorOptions, bytes memory dvnOptions) { // at least 2 bytes for the option type, but can have no options if (_options.length < 2) revert UlnOptions.LZ_ULN_InvalidWorkerOptions(0); @@ -301,8 +305,12 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { lastWorkerId = workerId; } else if (workerId != lastWorkerId) { bytes calldata op = _options[start:cursor]; // slice out the last worker's options - (executorOptions, dvnOptions) = - _insertWorkerOptions(executorOptions, dvnOptions, lastWorkerId, op); + (executorOptions, dvnOptions) = _insertWorkerOptions( + executorOptions, + dvnOptions, + lastWorkerId, + op + ); // reset the start cursor and lastWorkerId start = cursor; @@ -338,8 +346,9 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { bytes calldata _newOptions ) private pure returns (bytes memory, bytes memory) { if (_workerId == ExecutorOptions.WORKER_ID) { - _executorOptions = - _executorOptions.length == 0 ? _newOptions : abi.encodePacked(_executorOptions, _newOptions); + _executorOptions = _executorOptions.length == 0 + ? _newOptions + : abi.encodePacked(_executorOptions, _newOptions); } else if (_workerId == DVNOptions.WORKER_ID) { _dvnOptions = _dvnOptions.length == 0 ? _newOptions : abi.encodePacked(_dvnOptions, _newOptions); } else { @@ -348,11 +357,10 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { return (_executorOptions, _dvnOptions); } - function decodeLegacyOptions(uint16 _optionType, bytes calldata _options) - internal - pure - returns (bytes memory executorOptions) - { + function decodeLegacyOptions( + uint16 _optionType, + bytes calldata _options + ) internal pure returns (bytes memory executorOptions) { if (_optionType == UlnOptions.TYPE_1) { if (_options.length != 34) revert UlnOptions.LZ_ULN_InvalidLegacyType1Option(); @@ -413,39 +421,38 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external {} - mapping( - address from => mapping(address to => mapping(bytes32 guid => mapping(uint16 index => bytes32 messageHash))) - ) public composeQueue; + mapping(address from => mapping(address to => mapping(bytes32 guid => mapping(uint16 index => bytes32 messageHash)))) + public composeQueue; - function defaultReceiveLibrary(uint32 /*_eid*/ ) external pure returns (address) { + function defaultReceiveLibrary(uint32 /*_eid*/) external pure returns (address) { return address(0); } - function defaultReceiveLibraryTimeout(uint32 /*_eid*/ ) external pure returns (address lib, uint256 expiry) { + function defaultReceiveLibraryTimeout(uint32 /*_eid*/) external pure returns (address lib, uint256 expiry) { return (address(0), 0); } - function defaultSendLibrary(uint32 /*_eid*/ ) external pure returns (address) { + function defaultSendLibrary(uint32 /*_eid*/) external pure returns (address) { return address(0); } - function executable(Origin calldata, /*_origin*/ address /*receiver*/ ) external pure returns (ExecutionState) { + function executable(Origin calldata, /*_origin*/ address /*receiver*/) external pure returns (ExecutionState) { return ExecutionState.NotExecutable; } - function getConfig(address, /*_oapp*/ address, /*_lib*/ uint32, /*_eid*/ uint32 /*_configType*/ ) - external - pure - returns (bytes memory config) - { + function getConfig( + address, + /*_oapp*/ address, + /*_lib*/ uint32, + /*_eid*/ uint32 /*_configType*/ + ) external pure returns (bytes memory config) { return bytes("0x"); } - function getReceiveLibrary(address, /*receiver*/ uint32 /*_eid*/ ) - external - pure - returns (address lib, bool isDefault) - { + function getReceiveLibrary( + address, + /*receiver*/ uint32 /*_eid*/ + ) external pure returns (address lib, bool isDefault) { return (address(0), false); } @@ -455,7 +462,7 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { return addresses; } - function getSendLibrary(address, /*_sender*/ uint32 /*_eid*/ ) external pure returns (address lib) { + function getSendLibrary(address, /*_sender*/ uint32 /*_eid*/) external pure returns (address lib) { return address(0); } @@ -463,32 +470,32 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { return lazyInboundNonce[_receiver][_srcEid][_sender]; } - function isDefaultSendLibrary(address, /*_sender*/ uint32 /*_eid*/ ) external pure returns (bool) { + function isDefaultSendLibrary(address, /*_sender*/ uint32 /*_eid*/) external pure returns (bool) { return false; } - function isRegisteredLibrary(address /*_lib*/ ) external pure returns (bool) { + function isRegisteredLibrary(address /*_lib*/) external pure returns (bool) { return false; } - function isSupportedEid(uint32 /*_eid*/ ) external pure returns (bool) { + function isSupportedEid(uint32 /*_eid*/) external pure returns (bool) { return false; } function lzCompose( - address, /*_from,*/ - address, /*_to,*/ - bytes32, /*_guid,*/ - uint16, /*_index,*/ - bytes calldata, /*_message,*/ + address /*_from,*/, + address /*_to,*/, + bytes32 /*_guid,*/, + uint16 /*_index,*/, + bytes calldata /*_message,*/, bytes calldata /*_extraData*/ ) external payable {} function lzReceive( - Origin calldata, /*_origin,*/ - address, /*_receiver,*/ - bytes32, /*_guid,*/ - bytes calldata, /*_message,*/ + Origin calldata /*_origin,*/, + address /*_receiver,*/, + bytes32 /*_guid,*/, + bytes calldata /*_message,*/, bytes calldata /*_extraData*/ ) external payable {} @@ -500,19 +507,19 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { return address(0); } - function nextGuid(address, /*_sender,*/ uint32, /*_dstEid,*/ bytes32 /*_receiver*/ ) - external - pure - returns (bytes32) - { + function nextGuid( + address, + /*_sender,*/ uint32, + /*_dstEid,*/ bytes32 /*_receiver*/ + ) external pure returns (bytes32) { return 0; } function nilify( - address, /*_oapp,*/ - uint32, /*_srcEid,*/ - bytes32, /*_sender,*/ - uint64, /*_nonce,*/ + address /*_oapp,*/, + uint32 /*_srcEid,*/, + bytes32 /*_sender,*/, + uint64 /*_nonce,*/, bytes32 /*_payloadHash*/ ) external {} @@ -522,23 +529,21 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { mapping(address receiver => mapping(uint32 srcEid => Timeout)) public receiveLibraryTimeout; - function registerLibrary(address /*_lib*/ ) public {} + function registerLibrary(address /*_lib*/) public {} - function sendCompose(address, /*_to*/ bytes32, /*_guid*/ uint16, /*_index*/ bytes calldata /*_message*/ ) - external - {} + function sendCompose(address, /*_to*/ bytes32, /*_guid*/ uint16, /*_index*/ bytes calldata /*_message*/) external {} - function setConfig(address, /*_oapp*/ address, /*_lib*/ SetConfigParam[] calldata /*_params*/ ) external {} + function setConfig(address, /*_oapp*/ address, /*_lib*/ SetConfigParam[] calldata /*_params*/) external {} - function setDefaultReceiveLibrary(uint32, /*_eid*/ address, /*_newLib*/ uint256 /*_gracePeriod*/ ) external {} + function setDefaultReceiveLibrary(uint32, /*_eid*/ address, /*_newLib*/ uint256 /*_gracePeriod*/) external {} - function setDefaultReceiveLibraryTimeout(uint32, /*_eid*/ address, /*_lib*/ uint256 /*_expiry*/ ) external {} + function setDefaultReceiveLibraryTimeout(uint32, /*_eid*/ address, /*_lib*/ uint256 /*_expiry*/) external {} - function setDefaultSendLibrary(uint32, /*_eid*/ address /*_newLib*/ ) external {} + function setDefaultSendLibrary(uint32, /*_eid*/ address /*_newLib*/) external {} - function setDelegate(address /*_delegate*/ ) external {} + function setDelegate(address /*_delegate*/) external {} - function setLzToken(address /*_lzToken*/ ) external {} + function setLzToken(address /*_lzToken*/) external {} function setReceiveLibrary( address, @@ -560,34 +565,32 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { uint256 /*_gracePeriod*/ ) external {} - function setSendLibrary(address, /*_oapp*/ uint32, /*_eid*/ address /*_newLib*/ ) external {} + function setSendLibrary(address, /*_oapp*/ uint32, /*_eid*/ address /*_newLib*/) external {} - function skip(address, /*_oapp*/ uint32, /*_srcEid*/ bytes32, /*_sender*/ uint64 /*_nonce*/ ) external {} + function skip(address, /*_oapp*/ uint32, /*_srcEid*/ bytes32, /*_sender*/ uint64 /*_nonce*/) external {} function verifiable( - Origin calldata, /*_origin*/ - address, /*_receiver*/ - address, /*_receiveLib*/ + Origin calldata /*_origin*/, + address /*_receiver*/, + address /*_receiveLib*/, bytes32 /*_payloadHash*/ ) external pure returns (bool) { return false; } - function verify(Origin calldata, /*origin*/ address, /*_receiver*/ bytes32 /*_payloadHash*/ ) external {} + function verify(Origin calldata, /*origin*/ address, /*_receiver*/ bytes32 /*_payloadHash*/) external {} // Helper Functions - function executeNativeAirDropAndReturnLzGas(bytes calldata _options) - public - returns (uint256 totalGas, uint256 dstAmount) - { - (bytes memory executorOpts,) = decode(_options); + function executeNativeAirDropAndReturnLzGas( + bytes calldata _options + ) public returns (uint256 totalGas, uint256 dstAmount) { + (bytes memory executorOpts, ) = decode(_options); return this._executeNativeAirDropAndReturnLzGas(executorOpts); } - function _executeNativeAirDropAndReturnLzGas(bytes calldata _options) - public - returns (uint256 totalGas, uint256 dstAmount) - { + function _executeNativeAirDropAndReturnLzGas( + bytes calldata _options + ) public returns (uint256 totalGas, uint256 dstAmount) { if (_options.length == 0) { revert IExecutorFeeLib.Executor_NoOptions(); } @@ -603,7 +606,7 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { dstAmount += value; } else if (optionType == ExecutorOptions.OPTION_TYPE_NATIVE_DROP) { (uint128 nativeDropAmount, bytes32 receiver) = ExecutorOptions.decodeNativeDropOption(option); - (bool success,) = receiver.bytes32ToAddress().call{value: nativeDropAmount}(""); + (bool success, ) = receiver.bytes32ToAddress().call{value: nativeDropAmount}(""); if (!success) { emit ValueTransferFailed(receiver.bytes32ToAddress(), nativeDropAmount); } @@ -615,23 +618,25 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { if (cursor != _options.length) revert IExecutorFeeLib.Executor_InvalidExecutorOptions(cursor); } - function _initializable(Origin calldata _origin, address _receiver, uint64 _lazyInboundNonce) - internal - view - returns (bool) - { - return _lazyInboundNonce > 0 // allowInitializePath already checked - || ILayerZeroReceiver(_receiver).allowInitializePath(_origin); + function _initializable( + Origin calldata _origin, + address _receiver, + uint64 _lazyInboundNonce + ) internal view returns (bool) { + return + _lazyInboundNonce > 0 || // allowInitializePath already checked + ILayerZeroReceiver(_receiver).allowInitializePath(_origin); } /// @dev bytes(0) payloadHash can never be submitted - function _verifiable(Origin calldata _origin, address _receiver, uint64 _lazyInboundNonce) - internal - view - returns (bool) - { - return _origin.nonce > _lazyInboundNonce // either initializing an empty slot or reverifying - || inboundPayloadHash[_receiver][_origin.srcEid][_origin.sender][_origin.nonce] != EMPTY_PAYLOAD_HASH; // only allow reverifying if it hasn't been executed + function _verifiable( + Origin calldata _origin, + address _receiver, + uint64 _lazyInboundNonce + ) internal view returns (bool) { + return + _origin.nonce > _lazyInboundNonce || // either initializing an empty slot or reverifying + inboundPayloadHash[_receiver][_origin.srcEid][_origin.sender][_origin.nonce] != EMPTY_PAYLOAD_HASH; // only allow reverifying if it hasn't been executed } // ========================= VIEW FUNCTIONS FOR OFFCHAIN ONLY ========================= @@ -648,11 +653,11 @@ contract EndpointV2Mock is ILayerZeroEndpointV2, MessagingContext { /// @dev called when the endpoint checks if the msgLib attempting to verify the msg is the configured msgLib of the Oapp /// @dev this check provides the ability for Oapp to lock in a trusted msgLib /// @dev it will fist check if the msgLib is the currently configured one. then check if the msgLib is the one in grace period of msgLib versioning upgrade - function isValidReceiveLibrary(address, /*_receiver*/ uint32, /*_srcEid*/ address /*_actualReceiveLib*/ ) - public - pure - returns (bool) - { + function isValidReceiveLibrary( + address, + /*_receiver*/ uint32, + /*_srcEid*/ address /*_actualReceiveLib*/ + ) public pure returns (bool) { return true; } } diff --git a/test/mocks/ExocoreGatewayMock.sol b/test/mocks/ExocoreGatewayMock.sol index 974c807f..db896e2b 100644 --- a/test/mocks/ExocoreGatewayMock.sol +++ b/test/mocks/ExocoreGatewayMock.sol @@ -103,8 +103,9 @@ contract ExocoreGatewayMock is whiteListFunctionSelectors[Action.REQUEST_DEPOSIT] = this.requestDeposit.selector; whiteListFunctionSelectors[Action.REQUEST_DELEGATE_TO] = this.requestDelegateTo.selector; whiteListFunctionSelectors[Action.REQUEST_UNDELEGATE_FROM] = this.requestUndelegateFrom.selector; - whiteListFunctionSelectors[Action.REQUEST_WITHDRAW_PRINCIPLE_FROM_EXOCORE] = - this.requestWithdrawPrinciple.selector; + whiteListFunctionSelectors[Action.REQUEST_WITHDRAW_PRINCIPLE_FROM_EXOCORE] = this + .requestWithdrawPrinciple + .selector; whiteListFunctionSelectors[Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE] = this.requestWithdrawReward.selector; __Ownable_init_unchained(exocoreValidatorSetAddress); @@ -117,8 +118,8 @@ contract ExocoreGatewayMock is // For manual calls, this function should be called immediately after deployment and // then never needs to be called again. function markBootstrapOnAllChains() public { - (bool success, uint16[] memory clientChainIds) = - IClientChains(CLIENT_CHAINS_PRECOMPILE_MOCK_ADDRESS).getClientChains(); + (bool success, uint16[] memory clientChainIds) = IClientChains(CLIENT_CHAINS_PRECOMPILE_MOCK_ADDRESS) + .getClientChains(); require(success, "ExocoreGateway: failed to get client chain ids"); for (uint256 i = 0; i < clientChainIds.length; i++) { @@ -133,14 +134,16 @@ contract ExocoreGatewayMock is function pause() external { require( - msg.sender == exocoreValidatorSetAddress, "ExocoreGateway: caller is not Exocore validator set aggregated address" + msg.sender == exocoreValidatorSetAddress, + "ExocoreGateway: caller is not Exocore validator set aggregated address" ); _pause(); } function unpause() external { require( - msg.sender == exocoreValidatorSetAddress, "ExocoreGateway: caller is not Exocore validator set aggregated address" + msg.sender == exocoreValidatorSetAddress, + "ExocoreGateway: caller is not Exocore validator set aggregated address" ); _unpause(); } @@ -154,8 +157,9 @@ contract ExocoreGatewayMock is revert UnsupportedRequest(act); } - (bool success, bytes memory responseOrReason) = - address(this).call(abi.encodePacked(selector_, abi.encode(_origin.srcEid, _origin.nonce, payload[1:]))); + (bool success, bytes memory responseOrReason) = address(this).call( + abi.encodePacked(selector_, abi.encode(_origin.srcEid, _origin.nonce, payload[1:])) + ); if (!success) { revert RequestExecuteFailed(act, _origin.nonce, responseOrReason); } @@ -171,13 +175,7 @@ contract ExocoreGatewayMock is uint256 amount = uint256(bytes32(payload[64:96])); (bool success, bytes memory responseOrReason) = DEPOSIT_PRECOMPILE_MOCK_ADDRESS.call( - abi.encodeWithSelector( - DEPOSIT_FUNCTION_SELECTOR, - srcChainId, - token, - depositor, - amount - ) + abi.encodeWithSelector(DEPOSIT_FUNCTION_SELECTOR, srcChainId, token, depositor, amount) ); uint256 lastlyUpdatedPrincipleBalance; @@ -185,16 +183,23 @@ contract ExocoreGatewayMock is (, lastlyUpdatedPrincipleBalance) = abi.decode(responseOrReason, (bool, uint256)); } _sendInterchainMsg( - srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success, lastlyUpdatedPrincipleBalance) + srcChainId, + Action.RESPOND, + abi.encodePacked(lzNonce, success, lastlyUpdatedPrincipleBalance) ); } - function requestWithdrawPrinciple(uint32 srcChainId, uint64 lzNonce, bytes calldata payload) - public - onlyCalledFromThis - { + function requestWithdrawPrinciple( + uint32 srcChainId, + uint64 lzNonce, + bytes calldata payload + ) public onlyCalledFromThis { if (payload.length != WITHDRAW_PRINCIPLE_REQUEST_LENGTH) { - revert InvalidRequestLength(Action.REQUEST_WITHDRAW_PRINCIPLE_FROM_EXOCORE, WITHDRAW_PRINCIPLE_REQUEST_LENGTH, payload.length); + revert InvalidRequestLength( + Action.REQUEST_WITHDRAW_PRINCIPLE_FROM_EXOCORE, + WITHDRAW_PRINCIPLE_REQUEST_LENGTH, + payload.length + ); } bytes calldata token = payload[:32]; @@ -202,13 +207,7 @@ contract ExocoreGatewayMock is uint256 amount = uint256(bytes32(payload[64:96])); (bool success, bytes memory responseOrReason) = WITHDRAW_PRINCIPLE_PRECOMPILE_MOCK_ADDRESS.call( - abi.encodeWithSelector( - WITHDRAW_PRINCIPLE_FUNCTION_SELECTOR, - srcChainId, - token, - withdrawer, - amount - ) + abi.encodeWithSelector(WITHDRAW_PRINCIPLE_FUNCTION_SELECTOR, srcChainId, token, withdrawer, amount) ); uint256 lastlyUpdatedPrincipleBalance; @@ -216,16 +215,23 @@ contract ExocoreGatewayMock is (, lastlyUpdatedPrincipleBalance) = abi.decode(responseOrReason, (bool, uint256)); } _sendInterchainMsg( - srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success, lastlyUpdatedPrincipleBalance) + srcChainId, + Action.RESPOND, + abi.encodePacked(lzNonce, success, lastlyUpdatedPrincipleBalance) ); } - function requestWithdrawReward(uint32 srcChainId, uint64 lzNonce, bytes calldata payload) - public - onlyCalledFromThis - { + function requestWithdrawReward( + uint32 srcChainId, + uint64 lzNonce, + bytes calldata payload + ) public onlyCalledFromThis { if (payload.length != CLAIM_REWARD_REQUEST_LENGTH) { - revert InvalidRequestLength(Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE, CLAIM_REWARD_REQUEST_LENGTH, payload.length); + revert InvalidRequestLength( + Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE, + CLAIM_REWARD_REQUEST_LENGTH, + payload.length + ); } bytes calldata token = payload[:32]; @@ -233,13 +239,7 @@ contract ExocoreGatewayMock is uint256 amount = uint256(bytes32(payload[64:96])); (bool success, bytes memory responseOrReason) = CLAIM_REWARD_PRECOMPILE_MOCK_ADDRESS.call( - abi.encodeWithSelector( - CLAIM_REWARD_FUNCTION_SELECTOR, - srcChainId, - token, - withdrawer, - amount - ) + abi.encodeWithSelector(CLAIM_REWARD_FUNCTION_SELECTOR, srcChainId, token, withdrawer, amount) ); uint256 lastlyUpdatedRewardBalance; @@ -259,7 +259,7 @@ contract ExocoreGatewayMock is bytes calldata operator = payload[64:106]; uint256 amount = uint256(bytes32(payload[106:138])); - (bool success,) = DELEGATION_PRECOMPILE_MOCK_ADDRESS.call( + (bool success, ) = DELEGATION_PRECOMPILE_MOCK_ADDRESS.call( abi.encodeWithSelector( DELEGATE_TO_THROUGH_CLIENT_CHAIN_FUNCTION_SELECTOR, srcChainId, @@ -273,10 +273,11 @@ contract ExocoreGatewayMock is _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success)); } - function requestUndelegateFrom(uint32 srcChainId, uint64 lzNonce, bytes calldata payload) - public - onlyCalledFromThis - { + function requestUndelegateFrom( + uint32 srcChainId, + uint64 lzNonce, + bytes calldata payload + ) public onlyCalledFromThis { if (payload.length != UNDELEGATE_REQUEST_LENGTH) { revert InvalidRequestLength(Action.REQUEST_UNDELEGATE_FROM, UNDELEGATE_REQUEST_LENGTH, payload.length); } @@ -286,7 +287,7 @@ contract ExocoreGatewayMock is bytes memory operator = payload[64:106]; uint256 amount = uint256(bytes32(payload[106:138])); - (bool success,) = DELEGATION_PRECOMPILE_MOCK_ADDRESS.call( + (bool success, ) = DELEGATION_PRECOMPILE_MOCK_ADDRESS.call( abi.encodeWithSelector( UNDELEGATE_FROM_THROUGH_CLIENT_CHAIN_FUNCTION_SELECTOR, srcChainId, @@ -302,31 +303,36 @@ contract ExocoreGatewayMock is function _sendInterchainMsg(uint32 srcChainId, Action act, bytes memory actionArgs) internal whenNotPaused { bytes memory payload = abi.encodePacked(act, actionArgs); - bytes memory options = OptionsBuilder.newOptions().addExecutorLzReceiveOption( - DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE - ).addExecutorOrderedExecutionOption(); + bytes memory options = OptionsBuilder + .newOptions() + .addExecutorLzReceiveOption(DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE) + .addExecutorOrderedExecutionOption(); MessagingFee memory fee = _quote(srcChainId, payload, options, false); - MessagingReceipt memory receipt = - _lzSend(srcChainId, payload, options, MessagingFee(fee.nativeFee, 0), exocoreValidatorSetAddress, true); + MessagingReceipt memory receipt = _lzSend( + srcChainId, + payload, + options, + MessagingFee(fee.nativeFee, 0), + exocoreValidatorSetAddress, + true + ); emit MessageSent(act, receipt.guid, receipt.nonce, receipt.fee.nativeFee); } function quote(uint32 srcChainid, bytes memory _message) public view returns (uint256 nativeFee) { - bytes memory options = OptionsBuilder.newOptions().addExecutorLzReceiveOption( - DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE - ).addExecutorOrderedExecutionOption(); + bytes memory options = OptionsBuilder + .newOptions() + .addExecutorLzReceiveOption(DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE) + .addExecutorOrderedExecutionOption(); MessagingFee memory fee = _quote(srcChainid, _message, options, false); return fee.nativeFee; } - function nextNonce(uint32 srcEid, bytes32 sender) - public - view - virtual - override(ILayerZeroReceiver, OAppReceiverUpgradeable) - returns (uint64) - { + function nextNonce( + uint32 srcEid, + bytes32 sender + ) public view virtual override(ILayerZeroReceiver, OAppReceiverUpgradeable) returns (uint64) { return inboundNonce[srcEid][sender] + 1; } diff --git a/test/mocks/Faucet.sol b/test/mocks/Faucet.sol index df65a019..a53d53af 100644 --- a/test/mocks/Faucet.sol +++ b/test/mocks/Faucet.sol @@ -19,7 +19,7 @@ contract Faucet { revert("gas airdrop finished in this block"); } // Send the amount to the address that requested it - (bool success,) = msg.sender.call{value: amount}(""); + (bool success, ) = msg.sender.call{value: amount}(""); if (success) { emit GasSent(msg.sender, amount); } diff --git a/test/mocks/NonShortCircuitEndpointV2Mock.sol b/test/mocks/NonShortCircuitEndpointV2Mock.sol index ea39122a..0253f63f 100644 --- a/test/mocks/NonShortCircuitEndpointV2Mock.sol +++ b/test/mocks/NonShortCircuitEndpointV2Mock.sol @@ -2,13 +2,7 @@ pragma solidity 0.8.22; import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; -import { - ILayerZeroEndpointV2, - MessagingParams, - MessagingReceipt, - MessagingFee, - Origin -} from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; +import {ILayerZeroEndpointV2, MessagingParams, MessagingReceipt, MessagingFee, Origin} from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; import {ExecutionState} from "@layerzerolabs/lz-evm-protocol-v2/contracts/EndpointV2ViewUpgradeable.sol"; import {ILayerZeroReceiver} from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol"; import {SetConfigParam} from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLibManager.sol"; @@ -39,12 +33,10 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext uint32 public immutable eid; mapping(address => address) public lzEndpointLookup; - mapping(address receiver => mapping(uint32 srcEid => mapping(bytes32 sender => uint64 nonce))) public - lazyInboundNonce; - mapping( - address receiver - => mapping(uint32 srcEid => mapping(bytes32 sender => mapping(uint64 inboundNonce => bytes32 payloadHash))) - ) public inboundPayloadHash; + mapping(address receiver => mapping(uint32 srcEid => mapping(bytes32 sender => uint64 nonce))) + public lazyInboundNonce; + mapping(address receiver => mapping(uint32 srcEid => mapping(bytes32 sender => mapping(uint64 inboundNonce => bytes32 payloadHash)))) + public inboundPayloadHash; mapping(address sender => mapping(uint32 dstEid => mapping(bytes32 receiver => uint64 nonce))) public outboundNonce; RelayerFeeConfig public relayerFeeConfig; @@ -84,7 +76,12 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext event ValueTransferFailed(address indexed to, uint256 indexed quantity); event NewPacket(uint32, address, bytes32, uint64, bytes); event PayloadStored( - uint32 srcChainId, bytes32 srcAddress, address dstAddress, uint64 nonce, bytes payload, bytes reason + uint32 srcChainId, + bytes32 srcAddress, + address dstAddress, + uint64 nonce, + bytes payload, + bytes reason ); constructor(uint32 _eid, address _exocoreValidatorSet) { @@ -104,12 +101,10 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext verifierFee = 1e16; } - function send(MessagingParams calldata _params, address _refundAddress) - public - payable - sendContext(_params.dstEid, msg.sender) - returns (MessagingReceipt memory receipt) - { + function send( + MessagingParams calldata _params, + address _refundAddress + ) public payable sendContext(_params.dstEid, msg.sender) returns (MessagingReceipt memory receipt) { if (_params.payInLzToken) revert Errors.LZ_LzTokenUnavailable(); address lzEndpoint = lzEndpointLookup[_params.receiver.bytes32ToAddress()]; @@ -135,7 +130,7 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext // refund if they send too much uint256 amount = msg.value - receipt.fee.nativeFee; if (amount > 0) { - (bool success,) = _refundAddress.call{value: amount}(""); + (bool success, ) = _refundAddress.call{value: amount}(""); require(success, "LayerZeroMock: failed to refund"); } @@ -158,9 +153,13 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext _sendMessage(packet.dstEid, msg.sender, packet.receiver, packet.nonce, packet.message); } - function _sendMessage(uint32 dstChainId, address srcAddress, bytes32 dstAddr, uint64 nonce, bytes memory payload) - internal - { + function _sendMessage( + uint32 dstChainId, + address srcAddress, + bytes32 dstAddr, + uint64 nonce, + bytes memory payload + ) internal { emit NewPacket(dstChainId, srcAddress, dstAddr, nonce, payload); } @@ -192,11 +191,12 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext } } - function _hasPayloadHash(address _receiver, uint32 _srcEid, bytes32 _sender, uint64 _nonce) - internal - view - returns (bool) - { + function _hasPayloadHash( + address _receiver, + uint32 _srcEid, + bytes32 _sender, + uint64 _nonce + ) internal view returns (bool) { return inboundPayloadHash[_receiver][_srcEid][_sender][_nonce] != EMPTY_PAYLOAD_HASH; } @@ -215,20 +215,18 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext uint256 basePrice = (nativeFee * relayerFeeConfig.dstPriceRatio) / 10 ** 10; // pricePerByte = (dstGasPriceInWei * gasPerBytes) * tokenConversionRate - uint256 pricePerByte = ( - (relayerFeeConfig.dstGasPriceInWei * relayerFeeConfig.gasPerByte * relayerFeeConfig.dstPriceRatio) - / 10 ** 10 - ) * _payloadSize; + uint256 pricePerByte = ((relayerFeeConfig.dstGasPriceInWei * + relayerFeeConfig.gasPerByte * + relayerFeeConfig.dstPriceRatio) / 10 ** 10) * _payloadSize; return basePrice + pricePerByte; } - function _quote(MessagingParams calldata _params, address /*_sender*/ ) - internal - view - returns (MessagingFee memory messagingFee) - { - (bytes memory executorOptions,) = splitOptions(_params.options); + function _quote( + MessagingParams calldata _params, + address /*_sender*/ + ) internal view returns (MessagingFee memory messagingFee) { + (bytes memory executorOptions, ) = splitOptions(_params.options); // 2) get Executor fee uint256 executorFee = this.getExecutorFee(_params.message.length, executorOptions); @@ -255,10 +253,12 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext return lazyInboundNonce[_receiver][_srcEid][_sender]; } - function resetInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender, uint64 _nonce) - external - onlyExocoreValidatorSet - { + function resetInboundNonce( + address _receiver, + uint32 _srcEid, + bytes32 _sender, + uint64 _nonce + ) external onlyExocoreValidatorSet { lazyInboundNonce[_receiver][_srcEid][_sender] = _nonce; } @@ -266,10 +266,12 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext return outboundNonce[_sender][_dstEid][_receiver]; } - function resetOutboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver, uint64 _nonce) - external - onlyExocoreValidatorSet - { + function resetOutboundNonce( + address _sender, + uint32 _dstEid, + bytes32 _receiver, + uint64 _nonce + ) external onlyExocoreValidatorSet { outboundNonce[_sender][_dstEid][_receiver] = _nonce; } @@ -277,11 +279,9 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext lzEndpointLookup[destAddr] = lzEndpointAddr; } - function _decodeExecutorOptions(bytes calldata _options) - internal - view - returns (uint256 dstAmount, uint256 totalGas) - { + function _decodeExecutorOptions( + bytes calldata _options + ) internal view returns (uint256 dstAmount, uint256 totalGas) { if (_options.length == 0) { revert IExecutorFeeLib.Executor_NoOptions(); } @@ -308,7 +308,7 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext dstAmount += value; lzReceiveGas += gas; } else if (optionType == ExecutorOptions.OPTION_TYPE_NATIVE_DROP) { - (uint128 nativeDropAmount,) = ExecutorOptions.decodeNativeDropOption(option); + (uint128 nativeDropAmount, ) = ExecutorOptions.decodeNativeDropOption(option); dstAmount += nativeDropAmount; } else if (optionType == ExecutorOptions.OPTION_TYPE_LZCOMPOSE) { // endpoint v1 does not support lzCompose @@ -345,11 +345,9 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext return (executorOpts, workerOpts); } - function decode(bytes calldata _options) - internal - pure - returns (bytes memory executorOptions, bytes memory dvnOptions) - { + function decode( + bytes calldata _options + ) internal pure returns (bytes memory executorOptions, bytes memory dvnOptions) { // at least 2 bytes for the option type, but can have no options if (_options.length < 2) revert UlnOptions.LZ_ULN_InvalidWorkerOptions(0); @@ -377,8 +375,12 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext lastWorkerId = workerId; } else if (workerId != lastWorkerId) { bytes calldata op = _options[start:cursor]; // slice out the last worker's options - (executorOptions, dvnOptions) = - _insertWorkerOptions(executorOptions, dvnOptions, lastWorkerId, op); + (executorOptions, dvnOptions) = _insertWorkerOptions( + executorOptions, + dvnOptions, + lastWorkerId, + op + ); // reset the start cursor and lastWorkerId start = cursor; @@ -414,8 +416,9 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext bytes calldata _newOptions ) private pure returns (bytes memory, bytes memory) { if (_workerId == ExecutorOptions.WORKER_ID) { - _executorOptions = - _executorOptions.length == 0 ? _newOptions : abi.encodePacked(_executorOptions, _newOptions); + _executorOptions = _executorOptions.length == 0 + ? _newOptions + : abi.encodePacked(_executorOptions, _newOptions); } else if (_workerId == DVNOptions.WORKER_ID) { _dvnOptions = _dvnOptions.length == 0 ? _newOptions : abi.encodePacked(_dvnOptions, _newOptions); } else { @@ -424,11 +427,10 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext return (_executorOptions, _dvnOptions); } - function decodeLegacyOptions(uint16 _optionType, bytes calldata _options) - internal - pure - returns (bytes memory executorOptions) - { + function decodeLegacyOptions( + uint16 _optionType, + bytes calldata _options + ) internal pure returns (bytes memory executorOptions) { if (_optionType == UlnOptions.TYPE_1) { if (_options.length != 34) revert UlnOptions.LZ_ULN_InvalidLegacyType1Option(); @@ -489,39 +491,38 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external {} - mapping( - address from => mapping(address to => mapping(bytes32 guid => mapping(uint16 index => bytes32 messageHash))) - ) public composeQueue; + mapping(address from => mapping(address to => mapping(bytes32 guid => mapping(uint16 index => bytes32 messageHash)))) + public composeQueue; - function defaultReceiveLibrary(uint32 /*_eid*/ ) external pure returns (address) { + function defaultReceiveLibrary(uint32 /*_eid*/) external pure returns (address) { return address(0); } - function defaultReceiveLibraryTimeout(uint32 /*_eid*/ ) external pure returns (address lib, uint256 expiry) { + function defaultReceiveLibraryTimeout(uint32 /*_eid*/) external pure returns (address lib, uint256 expiry) { return (address(0), 0); } - function defaultSendLibrary(uint32 /*_eid*/ ) external pure returns (address) { + function defaultSendLibrary(uint32 /*_eid*/) external pure returns (address) { return address(0); } - function executable(Origin calldata, /*_origin*/ address /*receiver*/ ) external pure returns (ExecutionState) { + function executable(Origin calldata, /*_origin*/ address /*receiver*/) external pure returns (ExecutionState) { return ExecutionState.NotExecutable; } - function getConfig(address, /*_oapp*/ address, /*_lib*/ uint32, /*_eid*/ uint32 /*_configType*/ ) - external - pure - returns (bytes memory config) - { + function getConfig( + address, + /*_oapp*/ address, + /*_lib*/ uint32, + /*_eid*/ uint32 /*_configType*/ + ) external pure returns (bytes memory config) { return bytes("0x"); } - function getReceiveLibrary(address, /*receiver*/ uint32 /*_eid*/ ) - external - pure - returns (address lib, bool isDefault) - { + function getReceiveLibrary( + address, + /*receiver*/ uint32 /*_eid*/ + ) external pure returns (address lib, bool isDefault) { return (address(0), false); } @@ -531,7 +532,7 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext return addresses; } - function getSendLibrary(address, /*_sender*/ uint32 /*_eid*/ ) external pure returns (address lib) { + function getSendLibrary(address, /*_sender*/ uint32 /*_eid*/) external pure returns (address lib) { return address(0); } @@ -539,24 +540,24 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext return lazyInboundNonce[_receiver][_srcEid][_sender]; } - function isDefaultSendLibrary(address, /*_sender*/ uint32 /*_eid*/ ) external pure returns (bool) { + function isDefaultSendLibrary(address, /*_sender*/ uint32 /*_eid*/) external pure returns (bool) { return false; } - function isRegisteredLibrary(address /*_lib*/ ) external pure returns (bool) { + function isRegisteredLibrary(address /*_lib*/) external pure returns (bool) { return false; } - function isSupportedEid(uint32 /*_eid*/ ) external pure returns (bool) { + function isSupportedEid(uint32 /*_eid*/) external pure returns (bool) { return false; } function lzCompose( - address, /*_from,*/ - address, /*_to,*/ - bytes32, /*_guid,*/ - uint16, /*_index,*/ - bytes calldata, /*_message,*/ + address /*_from,*/, + address /*_to,*/, + bytes32 /*_guid,*/, + uint16 /*_index,*/, + bytes calldata /*_message,*/, bytes calldata /*_extraData*/ ) external payable {} @@ -576,19 +577,19 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext return address(0); } - function nextGuid(address, /*_sender,*/ uint32, /*_dstEid,*/ bytes32 /*_receiver*/ ) - external - pure - returns (bytes32) - { + function nextGuid( + address, + /*_sender,*/ uint32, + /*_dstEid,*/ bytes32 /*_receiver*/ + ) external pure returns (bytes32) { return 0; } function nilify( - address, /*_oapp,*/ - uint32, /*_srcEid,*/ - bytes32, /*_sender,*/ - uint64, /*_nonce,*/ + address /*_oapp,*/, + uint32 /*_srcEid,*/, + bytes32 /*_sender,*/, + uint64 /*_nonce,*/, bytes32 /*_payloadHash*/ ) external {} @@ -598,23 +599,21 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext mapping(address receiver => mapping(uint32 srcEid => Timeout)) public receiveLibraryTimeout; - function registerLibrary(address /*_lib*/ ) public {} + function registerLibrary(address /*_lib*/) public {} - function sendCompose(address, /*_to*/ bytes32, /*_guid*/ uint16, /*_index*/ bytes calldata /*_message*/ ) - external - {} + function sendCompose(address, /*_to*/ bytes32, /*_guid*/ uint16, /*_index*/ bytes calldata /*_message*/) external {} - function setConfig(address, /*_oapp*/ address, /*_lib*/ SetConfigParam[] calldata /*_params*/ ) external {} + function setConfig(address, /*_oapp*/ address, /*_lib*/ SetConfigParam[] calldata /*_params*/) external {} - function setDefaultReceiveLibrary(uint32, /*_eid*/ address, /*_newLib*/ uint256 /*_gracePeriod*/ ) external {} + function setDefaultReceiveLibrary(uint32, /*_eid*/ address, /*_newLib*/ uint256 /*_gracePeriod*/) external {} - function setDefaultReceiveLibraryTimeout(uint32, /*_eid*/ address, /*_lib*/ uint256 /*_expiry*/ ) external {} + function setDefaultReceiveLibraryTimeout(uint32, /*_eid*/ address, /*_lib*/ uint256 /*_expiry*/) external {} - function setDefaultSendLibrary(uint32, /*_eid*/ address /*_newLib*/ ) external {} + function setDefaultSendLibrary(uint32, /*_eid*/ address /*_newLib*/) external {} - function setDelegate(address /*_delegate*/ ) external {} + function setDelegate(address /*_delegate*/) external {} - function setLzToken(address /*_lzToken*/ ) external {} + function setLzToken(address /*_lzToken*/) external {} function setReceiveLibrary( address, @@ -636,34 +635,32 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext uint256 /*_gracePeriod*/ ) external {} - function setSendLibrary(address, /*_oapp*/ uint32, /*_eid*/ address /*_newLib*/ ) external {} + function setSendLibrary(address, /*_oapp*/ uint32, /*_eid*/ address /*_newLib*/) external {} - function skip(address, /*_oapp*/ uint32, /*_srcEid*/ bytes32, /*_sender*/ uint64 /*_nonce*/ ) external {} + function skip(address, /*_oapp*/ uint32, /*_srcEid*/ bytes32, /*_sender*/ uint64 /*_nonce*/) external {} function verifiable( - Origin calldata, /*_origin*/ - address, /*_receiver*/ - address, /*_receiveLib*/ + Origin calldata /*_origin*/, + address /*_receiver*/, + address /*_receiveLib*/, bytes32 /*_payloadHash*/ ) external pure returns (bool) { return false; } - function verify(Origin calldata, /*origin*/ address, /*_receiver*/ bytes32 /*_payloadHash*/ ) external {} + function verify(Origin calldata, /*origin*/ address, /*_receiver*/ bytes32 /*_payloadHash*/) external {} // Helper Functions - function executeNativeAirDropAndReturnLzGas(bytes calldata _options) - public - returns (uint256 totalGas, uint256 dstAmount) - { - (bytes memory executorOpts,) = decode(_options); + function executeNativeAirDropAndReturnLzGas( + bytes calldata _options + ) public returns (uint256 totalGas, uint256 dstAmount) { + (bytes memory executorOpts, ) = decode(_options); return this._executeNativeAirDropAndReturnLzGas(executorOpts); } - function _executeNativeAirDropAndReturnLzGas(bytes calldata _options) - public - returns (uint256 totalGas, uint256 dstAmount) - { + function _executeNativeAirDropAndReturnLzGas( + bytes calldata _options + ) public returns (uint256 totalGas, uint256 dstAmount) { if (_options.length == 0) { revert IExecutorFeeLib.Executor_NoOptions(); } @@ -679,7 +676,7 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext dstAmount += value; } else if (optionType == ExecutorOptions.OPTION_TYPE_NATIVE_DROP) { (uint128 nativeDropAmount, bytes32 receiver) = ExecutorOptions.decodeNativeDropOption(option); - (bool success,) = receiver.bytes32ToAddress().call{value: nativeDropAmount}(""); + (bool success, ) = receiver.bytes32ToAddress().call{value: nativeDropAmount}(""); if (!success) { emit ValueTransferFailed(receiver.bytes32ToAddress(), nativeDropAmount); } @@ -693,23 +690,25 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext if (cursor != _options.length) revert IExecutorFeeLib.Executor_InvalidExecutorOptions(cursor); } - function _initializable(Origin calldata _origin, address _receiver, uint64 _lazyInboundNonce) - internal - view - returns (bool) - { - return _lazyInboundNonce > 0 // allowInitializePath already checked - || ILayerZeroReceiver(_receiver).allowInitializePath(_origin); + function _initializable( + Origin calldata _origin, + address _receiver, + uint64 _lazyInboundNonce + ) internal view returns (bool) { + return + _lazyInboundNonce > 0 || // allowInitializePath already checked + ILayerZeroReceiver(_receiver).allowInitializePath(_origin); } /// @dev bytes(0) payloadHash can never be submitted - function _verifiable(Origin calldata _origin, address _receiver, uint64 _lazyInboundNonce) - internal - view - returns (bool) - { - return _origin.nonce > _lazyInboundNonce // either initializing an empty slot or reverifying - || inboundPayloadHash[_receiver][_origin.srcEid][_origin.sender][_origin.nonce] != EMPTY_PAYLOAD_HASH; // only allow reverifying if it hasn't been executed + function _verifiable( + Origin calldata _origin, + address _receiver, + uint64 _lazyInboundNonce + ) internal view returns (bool) { + return + _origin.nonce > _lazyInboundNonce || // either initializing an empty slot or reverifying + inboundPayloadHash[_receiver][_origin.srcEid][_origin.sender][_origin.nonce] != EMPTY_PAYLOAD_HASH; // only allow reverifying if it hasn't been executed } // ========================= VIEW FUNCTIONS FOR OFFCHAIN ONLY ========================= @@ -726,11 +725,11 @@ contract NonShortCircuitEndpointV2Mock is ILayerZeroEndpointV2, MessagingContext /// @dev called when the endpoint checks if the msgLib attempting to verify the msg is the configured msgLib of the Oapp /// @dev this check provides the ability for Oapp to lock in a trusted msgLib /// @dev it will fist check if the msgLib is the currently configured one. then check if the msgLib is the one in grace period of msgLib versioning upgrade - function isValidReceiveLibrary(address, /*_receiver*/ uint32, /*_srcEid*/ address /*_actualReceiveLib*/ ) - public - pure - returns (bool) - { + function isValidReceiveLibrary( + address, + /*_receiver*/ uint32, + /*_srcEid*/ address /*_actualReceiveLib*/ + ) public pure returns (bool) { return true; } } diff --git a/test/mocks/NonShortCircuitLzEndpointMock.sol b/test/mocks/NonShortCircuitLzEndpointMock.sol index 9ea1bc23..ef9ff8aa 100644 --- a/test/mocks/NonShortCircuitLzEndpointMock.sol +++ b/test/mocks/NonShortCircuitLzEndpointMock.sol @@ -93,7 +93,12 @@ contract NonShortCircuitLzEndpointMock is ILayerZeroEndpoint { event UaForceResumeReceive(uint16 chainId, bytes srcAddress); event PayloadCleared(uint16 srcChainId, bytes srcAddress, uint64 nonce, address dstAddress); event PayloadStored( - uint16 srcChainId, bytes srcAddress, address dstAddress, uint64 nonce, bytes payload, bytes reason + uint16 srcChainId, + bytes srcAddress, + address dstAddress, + uint64 nonce, + bytes payload, + bytes reason ); event ValueTransferFailed(address indexed to, uint256 indexed quantity); event Packet(uint16, address, address, uint64, bytes); @@ -143,8 +148,13 @@ contract NonShortCircuitLzEndpointMock is ILayerZeroEndpoint { // not handle zro token bytes memory adapterParams = _adapterParams.length > 0 ? _adapterParams : defaultAdapterParams; - (uint256 nativeFee,) = - estimateFees(_chainId, msg.sender, _payload, _zroPaymentAddress != address(0x0), adapterParams); + (uint256 nativeFee, ) = estimateFees( + _chainId, + msg.sender, + _payload, + _zroPaymentAddress != address(0x0), + adapterParams + ); require(msg.value >= nativeFee, "LayerZeroMock: not enough native for fees"); uint64 nonce = ++outboundNonce[_chainId][msg.sender]; @@ -153,16 +163,16 @@ contract NonShortCircuitLzEndpointMock is ILayerZeroEndpoint { // refund if they send too much uint256 amount = msg.value - nativeFee; if (amount > 0) { - (bool success,) = _refundAddress.call{value: amount}(""); + (bool success, ) = _refundAddress.call{value: amount}(""); require(success, "LayerZeroMock: failed to refund"); } } // Mock the process of receiving msg on dst chain // Mock the relayer paying the dstNativeAddr the amount of extra native token - (,, uint256 dstNativeAmt, address payable dstNativeAddr) = LzLib.decodeAdapterParams(adapterParams); + (, , uint256 dstNativeAmt, address payable dstNativeAddr) = LzLib.decodeAdapterParams(adapterParams); if (dstNativeAmt > 0) { - (bool success,) = dstNativeAddr.call{value: dstNativeAmt}(""); + (bool success, ) = dstNativeAddr.call{value: dstNativeAmt}(""); if (!success) { emit ValueTransferFailed(dstNativeAddr, dstNativeAmt); } @@ -172,9 +182,13 @@ contract NonShortCircuitLzEndpointMock is ILayerZeroEndpoint { _sendMessage(_chainId, msg.sender, dstAddr, nonce, payload); } - function _sendMessage(uint16 dstChainId, address srcAddress, address dstAddr, uint64 nonce, bytes memory payload) - internal - { + function _sendMessage( + uint16 dstChainId, + address srcAddress, + address dstAddr, + uint64 nonce, + bytes memory payload + ) internal { emit Packet(dstChainId, srcAddress, dstAddr, nonce, payload); } @@ -213,15 +227,23 @@ contract NonShortCircuitLzEndpointMock is ILayerZeroEndpoint { msgs.push(newMsg); } } else if (nextMsgBlocked) { - storedPayload[_srcChainId][_path] = StoredPayload(uint64(_payload.length), _dstAddress, keccak256(_payload)); + storedPayload[_srcChainId][_path] = StoredPayload( + uint64(_payload.length), + _dstAddress, + keccak256(_payload) + ); emit PayloadStored(_srcChainId, _path, _dstAddress, _nonce, _payload, bytes("")); // ensure the next msgs that go through are no longer blocked nextMsgBlocked = false; } else { - try ILayerZeroReceiver(_dstAddress).lzReceive{gas: _gasLimit}(_srcChainId, _path, _nonce, _payload) {} - catch (bytes memory reason) { - storedPayload[_srcChainId][_path] = - StoredPayload(uint64(_payload.length), _dstAddress, keccak256(_payload)); + try + ILayerZeroReceiver(_dstAddress).lzReceive{gas: _gasLimit}(_srcChainId, _path, _nonce, _payload) + {} catch (bytes memory reason) { + storedPayload[_srcChainId][_path] = StoredPayload( + uint64(_payload.length), + _dstAddress, + keccak256(_payload) + ); emit PayloadStored(_srcChainId, _path, _dstAddress, _nonce, _payload, reason); // ensure the next msgs that go through are no longer blocked nextMsgBlocked = false; @@ -233,10 +255,11 @@ contract NonShortCircuitLzEndpointMock is ILayerZeroEndpoint { return inboundNonce[_chainID][_path]; } - function resetInboundNonce(uint16 _srcChainId, bytes calldata _path, uint64 _nonce) - external - onlyExocoreValidatorSet - { + function resetInboundNonce( + uint16 _srcChainId, + bytes calldata _path, + uint64 _nonce + ) external onlyExocoreValidatorSet { inboundNonce[_srcChainId][_path] = _nonce; } @@ -244,10 +267,11 @@ contract NonShortCircuitLzEndpointMock is ILayerZeroEndpoint { return outboundNonce[_chainID][_srcAddress]; } - function resetOutboundNonce(uint16 _dstChainId, address _srcAddress, uint64 _nonce) - external - onlyExocoreValidatorSet - { + function resetOutboundNonce( + uint16 _dstChainId, + address _srcAddress, + uint64 _nonce + ) external onlyExocoreValidatorSet { outboundNonce[_dstChainId][_srcAddress] = _nonce; } @@ -319,31 +343,33 @@ contract NonShortCircuitLzEndpointMock is ILayerZeroEndpoint { return _receive_entered_state == _ENTERED; } - function getConfig(uint16, /*_version*/ uint16, /*_chainId*/ address, /*_ua*/ uint256 /*_configType*/ ) - external - pure - override - returns (bytes memory) - { + function getConfig( + uint16, + /*_version*/ uint16, + /*_chainId*/ address, + /*_ua*/ uint256 /*_configType*/ + ) external pure override returns (bytes memory) { return ""; } - function getSendVersion(address /*_userApplication*/ ) external pure override returns (uint16) { + function getSendVersion(address /*_userApplication*/) external pure override returns (uint16) { return 1; } - function getReceiveVersion(address /*_userApplication*/ ) external pure override returns (uint16) { + function getReceiveVersion(address /*_userApplication*/) external pure override returns (uint16) { return 1; } - function setConfig(uint16, /*_version*/ uint16, /*_chainId*/ uint256, /*_configType*/ bytes memory /*_config*/ ) - external - override - {} + function setConfig( + uint16, + /*_version*/ uint16, + /*_chainId*/ uint256, + /*_configType*/ bytes memory /*_config*/ + ) external override {} - function setSendVersion(uint16 /*version*/ ) external override {} + function setSendVersion(uint16 /*version*/) external override {} - function setReceiveVersion(uint16 /*version*/ ) external override {} + function setReceiveVersion(uint16 /*version*/) external override {} function forceResumeReceive(uint16 _srcChainId, bytes calldata _path) external override { StoredPayload storage sp = storedPayload[_srcChainId][_path]; @@ -417,11 +443,7 @@ contract NonShortCircuitLzEndpointMock is ILayerZeroEndpoint { } } - function _getProtocolFees(bool _payInZro, uint256 _relayerFee, uint256 _oracleFee) - internal - view - returns (uint256) - { + function _getProtocolFees(bool _payInZro, uint256 _relayerFee, uint256 _oracleFee) internal view returns (uint256) { if (_payInZro) { return protocolFeeConfig.zroFee; } else { @@ -430,13 +452,13 @@ contract NonShortCircuitLzEndpointMock is ILayerZeroEndpoint { } function _getRelayerFee( - uint16, /* _dstChainId */ - uint16, /* _outboundProofType */ - address, /* _userApplication */ + uint16 /* _dstChainId */, + uint16 /* _outboundProofType */, + address /* _userApplication */, uint256 _payloadSize, bytes memory _adapterParams ) internal view returns (uint256) { - (uint16 txType, uint256 extraGas, uint256 dstNativeAmt,) = LzLib.decodeAdapterParams(_adapterParams); + (uint16 txType, uint256 extraGas, uint256 dstNativeAmt, ) = LzLib.decodeAdapterParams(_adapterParams); uint256 totalRemoteToken; // = baseGas + extraGas + requiredNativeAmount if (txType == 2) { require(relayerFeeConfig.dstNativeAmtCap >= dstNativeAmt, "LayerZeroMock: dstNativeAmt too large "); @@ -451,9 +473,9 @@ contract NonShortCircuitLzEndpointMock is ILayerZeroEndpoint { uint256 basePrice = (totalRemoteToken * relayerFeeConfig.dstPriceRatio) / 10 ** 10; // pricePerByte = (dstGasPriceInWei * gasPerBytes) * tokenConversionRate - uint256 pricePerByte = ( - relayerFeeConfig.dstGasPriceInWei * relayerFeeConfig.gasPerByte * relayerFeeConfig.dstPriceRatio - ) / 10 ** 10; + uint256 pricePerByte = (relayerFeeConfig.dstGasPriceInWei * + relayerFeeConfig.gasPerByte * + relayerFeeConfig.dstPriceRatio) / 10 ** 10; return basePrice + _payloadSize * pricePerByte; } diff --git a/test/mocks/WithdrawPrincipleMock.sol b/test/mocks/WithdrawPrincipleMock.sol index 364ab911..8823ac3a 100644 --- a/test/mocks/WithdrawPrincipleMock.sol +++ b/test/mocks/WithdrawPrincipleMock.sol @@ -11,10 +11,7 @@ contract WithdrawPrincipleMock is IWithdraw { bytes memory assetsAddress, bytes memory stakerAddress, uint256 opAmount - ) - external - returns (bool success,uint256 latestAssetState) - { + ) external returns (bool success, uint256 latestAssetState) { principleBalances[clientChainLzId][assetsAddress][stakerAddress] += opAmount; } @@ -23,10 +20,7 @@ contract WithdrawPrincipleMock is IWithdraw { bytes memory assetsAddress, bytes memory withdrawer, uint256 opAmount - ) - external - returns (bool success,uint256 latestAssetState) - { + ) external returns (bool success, uint256 latestAssetState) { require(assetsAddress.length == 32, "invalid asset address"); require(withdrawer.length == 32, "invalid staker address"); require(opAmount <= principleBalances[clientChainLzId][assetsAddress][withdrawer], "withdraw amount overflow"); @@ -34,4 +28,4 @@ contract WithdrawPrincipleMock is IWithdraw { DepositMock(DEPOSIT_PRECOMPILE_ADDRESS).withdrawPrinciple(clientChainLzId, assetsAddress, withdrawer, opAmount); return (true, principleBalances[clientChainLzId][assetsAddress][withdrawer]); } -} \ No newline at end of file +}