From 01130ca9c986b9ea860e4408bc7907d20a1f92aa Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Tue, 24 Dec 2024 21:45:57 +0200 Subject: [PATCH 01/11] update to solidity 0.8.28 and make entry points nonreantrant --- contracts/foundry.toml | 10 +- contracts/scripts/Deploy.sol | 2 +- contracts/scripts/DeployBeefyClient.sol | 4 +- contracts/scripts/DeployLocal.sol | 7 +- contracts/scripts/DeployLocalGatewayLogic.sol | 2 +- contracts/scripts/FundAgent.sol | 2 +- contracts/scripts/UpgradeShell.sol | 8 +- contracts/scripts/westend/UpgradeShell.sol | 20 +- contracts/src/Agent.sol | 2 +- contracts/src/AgentExecutor.sol | 2 +- contracts/src/Assets.sol | 55 ++-- contracts/src/BeefyClient.sol | 82 +++-- contracts/src/Gateway.sol | 16 +- contracts/src/GatewayProxy.sol | 2 +- contracts/src/MultiAddress.sol | 13 +- contracts/src/Params.sol | 2 +- contracts/src/Shell.sol | 6 +- contracts/src/SubstrateTypes.sol | 24 +- contracts/src/Token.sol | 19 +- contracts/src/TokenLib.sol | 41 ++- contracts/src/Types.sol | 7 +- contracts/src/Upgrade.sol | 6 +- contracts/src/Verification.sol | 38 ++- contracts/src/interfaces/IERC20.sol | 6 +- contracts/src/interfaces/IERC20Permit.sol | 13 +- contracts/src/interfaces/IGateway.sol | 10 +- contracts/src/interfaces/IInitializable.sol | 2 +- contracts/src/interfaces/IShell.sol | 5 +- contracts/src/interfaces/IUpgradable.sol | 2 +- .../interfaces/extensions/IERC20Metadata.sol | 2 +- contracts/src/storage/AssetsStorage.sol | 2 +- contracts/src/storage/CoreStorage.sol | 2 +- contracts/src/storage/OperatorStorage.sol | 2 +- contracts/src/storage/PricingStorage.sol | 2 +- contracts/src/upgrades/Gateway202410.sol | 2 +- contracts/src/utils/Address.sol | 2 +- contracts/src/utils/Bitfield.sol | 32 +- contracts/src/utils/Bits.sol | 8 +- contracts/src/utils/Call.sol | 8 +- contracts/src/utils/ERC1967.sol | 5 +- contracts/src/utils/MMRProof.sol | 19 +- contracts/src/utils/Math.sol | 2 +- contracts/src/utils/SafeTransfer.sol | 5 +- contracts/src/utils/ScaleCodec.sol | 11 +- contracts/src/utils/SubstrateMerkleProof.sol | 14 +- contracts/src/utils/Uint16Array.sol | 2 +- contracts/test/Agent.t.sol | 8 +- contracts/test/BeefyClient.t.sol | 189 +++++++++--- contracts/test/Bitfield.t.sol | 5 +- contracts/test/ForkUpgrade.t.sol | 63 +++- contracts/test/Gateway.t.sol | 292 ++++++++++++++---- contracts/test/MMRProof.t.sol | 12 +- contracts/test/Math.t.sol | 18 +- contracts/test/ScaleCodec.t.sol | 23 +- contracts/test/Shell.t.sol | 2 +- contracts/test/Uint16Array.t.sol | 2 +- contracts/test/Verification.t.sol | 37 ++- contracts/test/mocks/BeefyClientMock.sol | 19 +- contracts/test/mocks/BitfieldWrapper.sol | 2 +- contracts/test/mocks/MMRProofWrapper.sol | 13 +- contracts/test/mocks/MockGateway.sol | 11 +- contracts/test/mocks/MockGatewayV2.sol | 2 +- contracts/test/mocks/VerificationWrapper.sol | 20 +- 63 files changed, 886 insertions(+), 360 deletions(-) diff --git a/contracts/foundry.toml b/contracts/foundry.toml index 639d0e08be..fda03816ca 100644 --- a/contracts/foundry.toml +++ b/contracts/foundry.toml @@ -1,5 +1,5 @@ [profile.default] -solc_version = "0.8.25" +solc_version = "0.8.28" optimizer = true optimizer_runs = 20000 via_ir = false @@ -13,10 +13,18 @@ fs_permissions = [ ignored_error_codes = [ # DeployLocal.sol is never deployed 5574, + # tstore + 2394, ] +evm_version = 'Cancun' + [profile.production] via_ir = true [profile.production.etherscan] mainnet = { key = "${ETHERSCAN_API_KEY}" } + +[fmt] +number_underscore = "thousands" +line_length = 99 diff --git a/contracts/scripts/Deploy.sol b/contracts/scripts/Deploy.sol index aee33b8022..a26a9cb372 100644 --- a/contracts/scripts/Deploy.sol +++ b/contracts/scripts/Deploy.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {Script} from "forge-std/Script.sol"; import {GatewayProxy} from "../src/GatewayProxy.sol"; diff --git a/contracts/scripts/DeployBeefyClient.sol b/contracts/scripts/DeployBeefyClient.sol index a8ef395926..40ca588f5a 100644 --- a/contracts/scripts/DeployBeefyClient.sol +++ b/contracts/scripts/DeployBeefyClient.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {Script} from "forge-std/Script.sol"; import {BeefyClient} from "../src/BeefyClient.sol"; @@ -18,7 +18,7 @@ contract DeployBeefyClient is Script { function readConfig() internal pure returns (Config memory config) { // Checkpoint generated using the script `./beefy-checkpoint.js` script in Polkadot-JS. config = Config({ - startBlock: 21087413, + startBlock: 21_087_413, current: BeefyClient.ValidatorSet({ id: 644, length: 297, diff --git a/contracts/scripts/DeployLocal.sol b/contracts/scripts/DeployLocal.sol index 441ab9926c..711c513f85 100644 --- a/contracts/scripts/DeployLocal.sol +++ b/contracts/scripts/DeployLocal.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {WETH9} from "canonical-weth/WETH9.sol"; import {Script} from "forge-std/Script.sol"; @@ -49,8 +49,9 @@ contract DeployLocal is Script { uint256 randaoCommitDelay = vm.envUint("RANDAO_COMMIT_DELAY"); uint256 randaoCommitExpiration = vm.envUint("RANDAO_COMMIT_EXP"); uint256 minimumSignatures = vm.envUint("MINIMUM_REQUIRED_SIGNATURES"); - BeefyClient beefyClient = - new BeefyClient(randaoCommitDelay, randaoCommitExpiration, minimumSignatures, startBlock, current, next); + BeefyClient beefyClient = new BeefyClient( + randaoCommitDelay, randaoCommitExpiration, minimumSignatures, startBlock, current, next + ); ParaID bridgeHubParaID = ParaID.wrap(uint32(vm.envUint("BRIDGE_HUB_PARAID"))); bytes32 bridgeHubAgentID = vm.envBytes32("BRIDGE_HUB_AGENT_ID"); diff --git a/contracts/scripts/DeployLocalGatewayLogic.sol b/contracts/scripts/DeployLocalGatewayLogic.sol index 326c8b5f16..e13cf038fe 100644 --- a/contracts/scripts/DeployLocalGatewayLogic.sol +++ b/contracts/scripts/DeployLocalGatewayLogic.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {AgentExecutor} from "../src/AgentExecutor.sol"; import {Gateway} from "../src//Gateway.sol"; diff --git a/contracts/scripts/FundAgent.sol b/contracts/scripts/FundAgent.sol index 37eedceb6b..c25affd4c1 100644 --- a/contracts/scripts/FundAgent.sol +++ b/contracts/scripts/FundAgent.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {WETH9} from "canonical-weth/WETH9.sol"; import {Script} from "forge-std/Script.sol"; diff --git a/contracts/scripts/UpgradeShell.sol b/contracts/scripts/UpgradeShell.sol index 7fc0c9de46..cac0499753 100644 --- a/contracts/scripts/UpgradeShell.sol +++ b/contracts/scripts/UpgradeShell.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {WETH9} from "canonical-weth/WETH9.sol"; import {Script} from "forge-std/Script.sol"; @@ -84,7 +84,11 @@ contract UpgradeShell is Script { IShell shell = IShell(config.gatewayProxy); - shell.upgrade(address(gatewayLogic), address(gatewayLogic).codehash, abi.encode(config.initializerParams)); + shell.upgrade( + address(gatewayLogic), + address(gatewayLogic).codehash, + abi.encode(config.initializerParams) + ); vm.stopBroadcast(); } diff --git a/contracts/scripts/westend/UpgradeShell.sol b/contracts/scripts/westend/UpgradeShell.sol index 01b9cc0cf4..80b7a59638 100644 --- a/contracts/scripts/westend/UpgradeShell.sol +++ b/contracts/scripts/westend/UpgradeShell.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {WETH9} from "canonical-weth/WETH9.sol"; import {Script} from "forge-std/Script.sol"; @@ -39,17 +39,17 @@ contract UpgradeShell is Script { bridgeHubParaID: ParaID.wrap(1002), bridgeHubAgentID: 0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314, foreignTokenDecimals: 12, - maxDestinationFee: 2000000000000, + maxDestinationFee: 2_000_000_000_000, initializerParams: Gateway.Config({ mode: OperatingMode.Normal, - deliveryCost: 200000000000, // 0.2 Wnd + deliveryCost: 200_000_000_000, // 0.2 Wnd registerTokenFee: 0.002 ether, assetHubParaID: ParaID.wrap(1000), assetHubAgentID: 0x81c5ab2571199e3188135178f3c2c8e2d268be1313d029b30f534fa579b69b79, - assetHubCreateAssetFee: 200000000000, // 0.2 Wnd - assetHubReserveTransferFee: 200000000000, // 0.2 Wnd - exchangeRate: ud60x18(2400000000000000), - multiplier: ud60x18(1330000000000000000), + assetHubCreateAssetFee: 200_000_000_000, // 0.2 Wnd + assetHubReserveTransferFee: 200_000_000_000, // 0.2 Wnd + exchangeRate: ud60x18(2_400_000_000_000_000), + multiplier: ud60x18(1_330_000_000_000_000_000), rescueOperator: 0x302F0B71B8aD3CF6dD90aDb668E49b2168d652fd }) }); @@ -75,7 +75,11 @@ contract UpgradeShell is Script { IShell shell = IShell(config.gatewayProxy); - shell.upgrade(address(gatewayLogic), address(gatewayLogic).codehash, abi.encode(config.initializerParams)); + shell.upgrade( + address(gatewayLogic), + address(gatewayLogic).codehash, + abi.encode(config.initializerParams) + ); vm.stopBroadcast(); } diff --git a/contracts/src/Agent.sol b/contracts/src/Agent.sol index d98092d9f2..25bb014e35 100644 --- a/contracts/src/Agent.sol +++ b/contracts/src/Agent.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; /// @title An agent contract that acts on behalf of a consensus system on Polkadot /// @dev Instances of this contract act as an agents for arbitrary consensus systems on Polkadot. These consensus systems diff --git a/contracts/src/AgentExecutor.sol b/contracts/src/AgentExecutor.sol index 629a25381e..f201ab3cc8 100644 --- a/contracts/src/AgentExecutor.sol +++ b/contracts/src/AgentExecutor.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {AgentExecuteCommand, ParaID} from "./Types.sol"; import {SubstrateTypes} from "./SubstrateTypes.sol"; diff --git a/contracts/src/Assets.sol b/contracts/src/Assets.sol index 11fa5c12c9..4f8b9fdc30 100644 --- a/contracts/src/Assets.sol +++ b/contracts/src/Assets.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {IERC20} from "./interfaces/IERC20.sol"; import {IGateway} from "./interfaces/IGateway.sol"; @@ -40,7 +40,9 @@ library Assets { } /// @dev transfer tokens from the sender to the specified agent - function _transferToAgent(address agent, address token, address sender, uint128 amount) internal { + function _transferToAgent(address agent, address token, address sender, uint128 amount) + internal + { if (!token.isContract()) { revert InvalidToken(); } @@ -67,11 +69,11 @@ library Assets { return _sendTokenCosts(destinationChain, destinationChainFee, maxDestinationChainFee); } - function _sendTokenCosts(ParaID destinationChain, uint128 destinationChainFee, uint128 maxDestinationChainFee) - internal - view - returns (Costs memory costs) - { + function _sendTokenCosts( + ParaID destinationChain, + uint128 destinationChainFee, + uint128 maxDestinationChainFee + ) internal view returns (Costs memory costs) { AssetsStorage.Layout storage $ = AssetsStorage.layout(); if ($.assetHubParaID == destinationChain) { costs.foreign = $.assetHubReserveTransferFee; @@ -116,7 +118,13 @@ library Assets { if (info.foreignID == bytes32(0)) { return _sendNativeToken( - token, sender, destinationChain, destinationAddress, destinationChainFee, maxDestinationChainFee, amount + token, + sender, + destinationChain, + destinationAddress, + destinationChainFee, + maxDestinationChainFee, + amount ); } else { return _sendForeignToken( @@ -147,7 +155,8 @@ library Assets { _transferToAgent($.assetHubAgent, token, sender, amount); ticket.dest = $.assetHubParaID; - ticket.costs = _sendTokenCosts(destinationChain, destinationChainFee, maxDestinationChainFee); + ticket.costs = + _sendTokenCosts(destinationChain, destinationChainFee, maxDestinationChainFee); // Construct a message payload if (destinationChain == $.assetHubParaID) { @@ -210,7 +219,8 @@ library Assets { Token(token).burn(sender, amount); ticket.dest = $.assetHubParaID; - ticket.costs = _sendTokenCosts(destinationChain, destinationChainFee, maxDestinationChainFee); + ticket.costs = + _sendTokenCosts(destinationChain, destinationChainFee, maxDestinationChainFee); // Construct a message payload if (destinationChain == $.assetHubParaID && destinationAddress.isAddress32()) { @@ -254,7 +264,7 @@ library Assets { // It means that registration can be retried. // But register a PNA here is not allowed TokenInfo storage info = $.tokenRegistry[token]; - if(info.foreignID != bytes32(0)) { + if (info.foreignID != bytes32(0)) { revert TokenAlreadyRegistered(); } info.isRegistered = true; @@ -267,9 +277,12 @@ library Assets { } // @dev Register a new fungible Polkadot token for an agent - function registerForeignToken(bytes32 foreignTokenID, string memory name, string memory symbol, uint8 decimals) - external - { + function registerForeignToken( + bytes32 foreignTokenID, + string memory name, + string memory symbol, + uint8 decimals + ) external { AssetsStorage.Layout storage $ = AssetsStorage.layout(); if ($.tokenAddressOf[foreignTokenID] != address(0)) { revert TokenAlreadyRegistered(); @@ -284,15 +297,21 @@ library Assets { } // @dev Mint foreign token from Polkadot - function mintForeignToken(bytes32 foreignTokenID, address recipient, uint256 amount) external { + function mintForeignToken(bytes32 foreignTokenID, address recipient, uint256 amount) + external + { address token = _ensureTokenAddressOf(foreignTokenID); Token(token).mint(recipient, amount); } // @dev Transfer ERC20 to `recipient` - function transferNativeToken(address executor, address agent, address token, address recipient, uint128 amount) - external - { + function transferNativeToken( + address executor, + address agent, + address token, + address recipient, + uint128 amount + ) external { bytes memory call = abi.encodeCall(AgentExecutor.transferToken, (token, recipient, amount)); (bool success,) = Agent(payable(agent)).invoke(executor, call); if (!success) { diff --git a/contracts/src/BeefyClient.sol b/contracts/src/BeefyClient.sol index adde28830b..eed2cb166c 100644 --- a/contracts/src/BeefyClient.sol +++ b/contracts/src/BeefyClient.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {ECDSA} from "openzeppelin/utils/cryptography/ECDSA.sol"; import {SubstrateMerkleProof} from "./utils/SubstrateMerkleProof.sol"; @@ -247,9 +247,11 @@ contract BeefyClient { * @param bitfield a bitfield claiming which validators have signed the commitment * @param proof a proof that a single validator from currentValidatorSet has signed the commitment */ - function submitInitial(Commitment calldata commitment, uint256[] calldata bitfield, ValidatorProof calldata proof) - external - { + function submitInitial( + Commitment calldata commitment, + uint256[] calldata bitfield, + ValidatorProof calldata proof + ) external { if (commitment.blockNumber <= latestBeefyBlock) { revert StaleCommitment(); } @@ -258,7 +260,9 @@ contract BeefyClient { uint16 signatureUsageCount; if (commitment.validatorSetID == currentValidatorSet.id) { signatureUsageCount = currentValidatorSet.usageCounters.get(proof.index); - currentValidatorSet.usageCounters.set(proof.index, signatureUsageCount.saturatingAdd(1)); + currentValidatorSet.usageCounters.set( + proof.index, signatureUsageCount.saturatingAdd(1) + ); vset = currentValidatorSet; } else if (commitment.validatorSetID == nextValidatorSet.id) { signatureUsageCount = nextValidatorSet.usageCounters.get(proof.index); @@ -269,8 +273,10 @@ contract BeefyClient { } // Check if merkle proof is valid based on the validatorSetRoot and if proof is included in bitfield - if (!isValidatorInSet(vset, proof.account, proof.index, proof.proof) || !Bitfield.isSet(bitfield, proof.index)) - { + if ( + !isValidatorInSet(vset, proof.account, proof.index, proof.proof) + || !Bitfield.isSet(bitfield, proof.index) + ) { revert InvalidValidatorProof(); } @@ -291,7 +297,9 @@ contract BeefyClient { blockNumber: uint64(block.number), validatorSetLen: uint32(vset.length), numRequiredSignatures: uint32( - computeNumRequiredSignatures(vset.length, signatureUsageCount, minNumRequiredSignatures) + computeNumRequiredSignatures( + vset.length, signatureUsageCount, minNumRequiredSignatures + ) ), prevRandao: 0, bitfieldHash: keccak256(abi.encodePacked(bitfield)) @@ -371,8 +379,9 @@ contract BeefyClient { if (leaf.nextAuthoritySetID != nextValidatorSet.id + 1) { revert InvalidMMRLeaf(); } - bool leafIsValid = - MMRProof.verifyLeafProof(newMMRRoot, keccak256(encodeMMRLeaf(leaf)), leafProof, leafProofOrder); + bool leafIsValid = MMRProof.verifyLeafProof( + newMMRRoot, keccak256(encodeMMRLeaf(leaf)), leafProof, leafProofOrder + ); if (!leafIsValid) { revert InvalidMMRLeafProof(); } @@ -434,13 +443,19 @@ contract BeefyClient { if (ticket.bitfieldHash != keccak256(abi.encodePacked(bitfield))) { revert InvalidBitfield(); } - return Bitfield.subsample(ticket.prevRandao, bitfield, ticket.numRequiredSignatures, ticket.validatorSetLen); + return Bitfield.subsample( + ticket.prevRandao, bitfield, ticket.numRequiredSignatures, ticket.validatorSetLen + ); } /* Internal Functions */ // Creates a unique ticket ID for a new interactive prover-verifier session - function createTicketID(address account, bytes32 commitmentHash) internal pure returns (bytes32 value) { + function createTicketID(address account, bytes32 commitmentHash) + internal + pure + returns (bytes32 value) + { assembly { mstore(0x00, account) mstore(0x20, commitmentHash) @@ -525,7 +540,11 @@ contract BeefyClient { } // Ensure that the commitment provides a new MMR root - function ensureProvidesMMRRoot(Commitment calldata commitment) internal pure returns (bytes32) { + function ensureProvidesMMRRoot(Commitment calldata commitment) + internal + pure + returns (bytes32) + { for (uint256 i = 0; i < commitment.payload.length; i++) { if (commitment.payload[i].payloadID == MMR_ROOT_ID) { if (commitment.payload[i].data.length != 32) { @@ -538,7 +557,11 @@ contract BeefyClient { revert CommitmentNotRelevant(); } - function encodeCommitment(Commitment calldata commitment) internal pure returns (bytes memory) { + function encodeCommitment(Commitment calldata commitment) + internal + pure + returns (bytes memory) + { return bytes.concat( encodeCommitmentPayload(commitment.payload), ScaleCodec.encodeU32(commitment.blockNumber), @@ -546,11 +569,18 @@ contract BeefyClient { ); } - function encodeCommitmentPayload(PayloadItem[] calldata items) internal pure returns (bytes memory) { + function encodeCommitmentPayload(PayloadItem[] calldata items) + internal + pure + returns (bytes memory) + { bytes memory payload = ScaleCodec.checkedEncodeCompactU32(items.length); for (uint256 i = 0; i < items.length; i++) { payload = bytes.concat( - payload, items[i].payloadID, ScaleCodec.checkedEncodeCompactU32(items[i].data.length), items[i].data + payload, + items[i].payloadID, + ScaleCodec.checkedEncodeCompactU32(items[i].data.length), + items[i].data ); } @@ -577,11 +607,12 @@ contract BeefyClient { * @param proof Merkle proof required for validation of the address * @return true if the validator is in the set */ - function isValidatorInSet(ValidatorSetState storage vset, address account, uint256 index, bytes32[] calldata proof) - internal - view - returns (bool) - { + function isValidatorInSet( + ValidatorSetState storage vset, + address account, + uint256 index, + bytes32[] calldata proof + ) internal view returns (bool) { bytes32 hashedLeaf = keccak256(abi.encodePacked(account)); return SubstrateMerkleProof.verify(vset.root, hashedLeaf, index, vset.length, proof); } @@ -589,10 +620,11 @@ contract BeefyClient { /** * @dev Basic validation of a ticket for submitFinal */ - function validateTicket(bytes32 ticketID, Commitment calldata commitment, uint256[] calldata bitfield) - internal - view - { + function validateTicket( + bytes32 ticketID, + Commitment calldata commitment, + uint256[] calldata bitfield + ) internal view { Ticket storage ticket = tickets[ticketID]; if (ticket.blockNumber == 0) { diff --git a/contracts/src/Gateway.sol b/contracts/src/Gateway.sol index 685627fe34..69dc4e6576 100644 --- a/contracts/src/Gateway.sol +++ b/contracts/src/Gateway.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {MerkleProof} from "openzeppelin/utils/cryptography/MerkleProof.sol"; import {Verification} from "./Verification.sol"; @@ -108,6 +108,14 @@ contract Gateway is IGateway, IInitializable, IUpgradable { _; } + modifier nonreentrant() { + assembly { + if tload(0) { revert(0, 0) } + tstore(0, 1) + } + _; + } + constructor( address beefyClient, address agentExecutor, @@ -137,7 +145,7 @@ contract Gateway is IGateway, IInitializable, IUpgradable { InboundMessage calldata message, bytes32[] calldata leafProof, Verification.Proof calldata headerProof - ) external { + ) external nonreentrant { uint256 startGas = gasleft(); Channel storage channel = _ensureChannel(message.channelID); @@ -437,7 +445,7 @@ contract Gateway is IGateway, IInitializable, IUpgradable { } // Register an Ethereum-native token in the gateway and on AssetHub - function registerToken(address token) external payable { + function registerToken(address token) external payable nonreentrant { _submitOutbound(Assets.registerToken(token)); } @@ -457,7 +465,7 @@ contract Gateway is IGateway, IInitializable, IUpgradable { MultiAddress calldata destinationAddress, uint128 destinationFee, uint128 amount - ) external payable { + ) external payable nonreentrant { Ticket memory ticket = Assets.sendToken( token, msg.sender, destinationChain, destinationAddress, destinationFee, MAX_DESTINATION_FEE, amount ); diff --git a/contracts/src/GatewayProxy.sol b/contracts/src/GatewayProxy.sol index b66bc91f83..a6a738e923 100644 --- a/contracts/src/GatewayProxy.sol +++ b/contracts/src/GatewayProxy.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {ERC1967} from "./utils/ERC1967.sol"; import {Call} from "./utils/Call.sol"; diff --git a/contracts/src/MultiAddress.sol b/contracts/src/MultiAddress.sol index f9b90b36bf..97c3fd9c8b 100644 --- a/contracts/src/MultiAddress.sol +++ b/contracts/src/MultiAddress.sol @@ -1,8 +1,15 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; - -using {isIndex, asIndex, isAddress32, asAddress32, isAddress20, asAddress20} for MultiAddress global; +pragma solidity 0.8.28; + +using { + isIndex, + asIndex, + isAddress32, + asAddress32, + isAddress20, + asAddress20 +} for MultiAddress global; /// @dev An address for an on-chain account struct MultiAddress { diff --git a/contracts/src/Params.sol b/contracts/src/Params.sol index 882c2c7856..dd1e21fea7 100644 --- a/contracts/src/Params.sol +++ b/contracts/src/Params.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {ChannelID, OperatingMode} from "./Types.sol"; import {UD60x18} from "prb/math/src/UD60x18.sol"; diff --git a/contracts/src/Shell.sol b/contracts/src/Shell.sol index c440c6c6bc..0b614b5c40 100644 --- a/contracts/src/Shell.sol +++ b/contracts/src/Shell.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {Upgrade} from "./Upgrade.sol"; import {IInitializable} from "./interfaces/IInitializable.sol"; @@ -22,7 +22,9 @@ contract Shell is IShell, IUpgradable, IInitializable { OPERATOR = _operator; } - function upgrade(address impl, bytes32 implCodeHash, bytes calldata initializerParams) external { + function upgrade(address impl, bytes32 implCodeHash, bytes calldata initializerParams) + external + { if (msg.sender != OPERATOR) { revert Unauthorized(); } diff --git a/contracts/src/SubstrateTypes.sol b/contracts/src/SubstrateTypes.sol index 296f32ce57..9cf576d360 100644 --- a/contracts/src/SubstrateTypes.sol +++ b/contracts/src/SubstrateTypes.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {ScaleCodec} from "./utils/ScaleCodec.sol"; import {ParaID} from "./Types.sol"; @@ -71,11 +71,12 @@ library SubstrateTypes { * `NativeTokensMessage::Mint` */ // destination is AccountID32 address on AssetHub - function SendTokenToAssetHubAddress32(address token, bytes32 recipient, uint128 xcmFee, uint128 amount) - internal - view - returns (bytes memory) - { + function SendTokenToAssetHubAddress32( + address token, + bytes32 recipient, + uint128 xcmFee, + uint128 amount + ) internal view returns (bytes memory) { return bytes.concat( bytes1(0x00), ScaleCodec.encodeU64(uint64(block.chainid)), @@ -134,11 +135,12 @@ library SubstrateTypes { ); } - function SendForeignTokenToAssetHubAddress32(bytes32 tokenID, bytes32 recipient, uint128 xcmFee, uint128 amount) - internal - view - returns (bytes memory) - { + function SendForeignTokenToAssetHubAddress32( + bytes32 tokenID, + bytes32 recipient, + uint128 xcmFee, + uint128 amount + ) internal view returns (bytes memory) { return bytes.concat( bytes1(0x00), ScaleCodec.encodeU64(uint64(block.chainid)), diff --git a/contracts/src/Token.sol b/contracts/src/Token.sol index f66a9e34be..c73e1c4329 100644 --- a/contracts/src/Token.sol +++ b/contracts/src/Token.sol @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: 2023 Axelar Network // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {IERC20} from "./interfaces/IERC20.sol"; import {IERC20Permit} from "./interfaces/IERC20Permit.sol"; @@ -132,7 +132,10 @@ contract Token is IERC20, IERC20Permit { * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ - function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) { + function transferFrom(address sender, address recipient, uint256 amount) + external + returns (bool) + { return token.transferFrom(sender, recipient, amount); } @@ -170,9 +173,15 @@ contract Token is IERC20, IERC20Permit { return token.decreaseAllowance(spender, subtractedValue); } - function permit(address issuer, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) - external - { + function permit( + address issuer, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) external { token.permit(DOMAIN_SEPARATOR, issuer, spender, value, deadline, v, r, s); } diff --git a/contracts/src/TokenLib.sol b/contracts/src/TokenLib.sol index de21ea679f..db0f4d85ce 100644 --- a/contracts/src/TokenLib.sol +++ b/contracts/src/TokenLib.sol @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: 2023 Axelar Network // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {IERC20} from "./interfaces/IERC20.sol"; import {IERC20Permit} from "./interfaces/IERC20Permit.sol"; @@ -33,7 +33,10 @@ library TokenLib { * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ - function transfer(Token storage token, address sender, address recipient, uint256 amount) external returns (bool) { + function transfer(Token storage token, address sender, address recipient, uint256 amount) + external + returns (bool) + { _transfer(token, sender, recipient, amount); return true; } @@ -90,7 +93,10 @@ library TokenLib { * * - `spender` cannot be the zero address. */ - function approve(Token storage token, address owner, address spender, uint256 amount) external returns (bool) { + function approve(Token storage token, address owner, address spender, uint256 amount) + external + returns (bool) + { _approve(token, owner, spender, amount); return true; } @@ -140,7 +146,10 @@ library TokenLib { * * - `spender` cannot be the zero address. */ - function increaseAllowance(Token storage token, address spender, uint256 addedValue) external returns (bool) { + function increaseAllowance(Token storage token, address spender, uint256 addedValue) + external + returns (bool) + { uint256 _allowance = token.allowance[msg.sender][spender]; if (_allowance != type(uint256).max) { _approve(token, msg.sender, spender, _allowance + addedValue); @@ -162,7 +171,10 @@ library TokenLib { * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ - function decreaseAllowance(Token storage token, address spender, uint256 subtractedValue) external returns (bool) { + function decreaseAllowance(Token storage token, address spender, uint256 subtractedValue) + external + returns (bool) + { uint256 _allowance = token.allowance[msg.sender][spender]; if (_allowance != type(uint256).max) { if (_allowance < subtractedValue) { @@ -198,7 +210,16 @@ library TokenLib { abi.encodePacked( EIP191_PREFIX_FOR_EIP712_STRUCTURED_DATA, domainSeparator, - keccak256(abi.encode(PERMIT_SIGNATURE_HASH, issuer, spender, value, token.nonces[issuer]++, deadline)) + keccak256( + abi.encode( + PERMIT_SIGNATURE_HASH, + issuer, + spender, + value, + token.nonces[issuer]++, + deadline + ) + ) ) ); @@ -224,7 +245,9 @@ library TokenLib { * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ - function _transfer(Token storage token, address sender, address recipient, uint256 amount) internal { + function _transfer(Token storage token, address sender, address recipient, uint256 amount) + internal + { if (sender == address(0) || recipient == address(0)) { revert IERC20.InvalidAccount(); } @@ -245,7 +268,9 @@ library TokenLib { * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ - function _approve(Token storage token, address owner, address spender, uint256 amount) internal { + function _approve(Token storage token, address owner, address spender, uint256 amount) + internal + { if (owner == address(0) || spender == address(0)) { revert IERC20.InvalidAccount(); } diff --git a/contracts/src/Types.sol b/contracts/src/Types.sol index 02e8bd0acc..665b2b7ed9 100644 --- a/contracts/src/Types.sol +++ b/contracts/src/Types.sol @@ -1,9 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import { - MultiAddress, multiAddressFromUint32, multiAddressFromBytes32, multiAddressFromBytes20 + MultiAddress, + multiAddressFromUint32, + multiAddressFromBytes32, + multiAddressFromBytes20 } from "./MultiAddress.sol"; import {UD60x18} from "prb/math/src/UD60x18.sol"; diff --git a/contracts/src/Upgrade.sol b/contracts/src/Upgrade.sol index 49e30702ee..8753e02c6b 100644 --- a/contracts/src/Upgrade.sol +++ b/contracts/src/Upgrade.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {ERC1967} from "./utils/ERC1967.sol"; import {Call} from "./utils/Call.sol"; @@ -12,7 +12,9 @@ import {IUpgradable} from "./interfaces/IUpgradable.sol"; library Upgrade { using Address for address; - function upgrade(address impl, bytes32 implCodeHash, bytes memory initializerParams) internal { + function upgrade(address impl, bytes32 implCodeHash, bytes memory initializerParams) + internal + { // Verify that the implementation is actually a contract if (!impl.isContract()) { revert IUpgradable.InvalidContract(); diff --git a/contracts/src/Verification.sol b/contracts/src/Verification.sol index 186f7e5c8b..d2dbb17e3b 100644 --- a/contracts/src/Verification.sol +++ b/contracts/src/Verification.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {SubstrateMerkleProof} from "./utils/SubstrateMerkleProof.sol"; import {BeefyClient} from "./BeefyClient.sol"; @@ -100,11 +100,12 @@ library Verification { /// @param commitment The message commitment root expected to be contained within the /// digest of BridgeHub parachain header. /// @param proof The chain of proofs described above - function verifyCommitment(address beefyClient, bytes4 encodedParaID, bytes32 commitment, Proof calldata proof) - external - view - returns (bool) - { + function verifyCommitment( + address beefyClient, + bytes4 encodedParaID, + bytes32 commitment, + Proof calldata proof + ) external view returns (bool) { // Verify that parachain header contains the commitment if (!isCommitmentInHeaderDigest(commitment, proof.header)) { return false; @@ -125,7 +126,9 @@ library Verification { bytes32 leafHash = createMMRLeaf(proof.leafPartial, parachainHeadsRoot); // Verify that the MMR leaf is part of the MMR maintained by the BEEFY light client - return BeefyClient(beefyClient).verifyMMRLeafProof(leafHash, proof.leafProof, proof.leafProofOrder); + return BeefyClient(beefyClient).verifyMMRLeafProof( + leafHash, proof.leafProof, proof.leafProofOrder + ); } // Verify that a message commitment is in the header digest @@ -136,7 +139,8 @@ library Verification { { for (uint256 i = 0; i < header.digestItems.length; i++) { if ( - header.digestItems[i].kind == DIGEST_ITEM_OTHER && header.digestItems[i].data.length == 33 + header.digestItems[i].kind == DIGEST_ITEM_OTHER + && header.digestItems[i].data.length == 33 && header.digestItems[i].data[0] == DIGEST_ITEM_OTHER_SNOWBRIDGE && commitment == bytes32(header.digestItems[i].data[1:]) ) { @@ -148,7 +152,11 @@ library Verification { // SCALE-Encodes: Vec // Reference: https://github.com/paritytech/substrate/blob/14e0a0b628f9154c5a2c870062c3aac7df8983ed/primitives/runtime/src/generic/digest.rs#L40 - function encodeDigestItems(DigestItem[] calldata digestItems) internal pure returns (bytes memory) { + function encodeDigestItems(DigestItem[] calldata digestItems) + internal + pure + returns (bytes memory) + { // encode all digest items into a buffer bytes memory accum = hex""; for (uint256 i = 0; i < digestItems.length; i++) { @@ -158,7 +166,11 @@ library Verification { return bytes.concat(ScaleCodec.checkedEncodeCompactU32(digestItems.length), accum); } - function encodeDigestItem(DigestItem calldata digestItem) internal pure returns (bytes memory) { + function encodeDigestItem(DigestItem calldata digestItem) + internal + pure + returns (bytes memory) + { if ( digestItem.kind == DIGEST_ITEM_PRERUNTIME || digestItem.kind == DIGEST_ITEM_CONSENSUS || digestItem.kind == DIGEST_ITEM_SEAL @@ -221,7 +233,11 @@ library Verification { // SCALE-encode: MMRLeaf // Reference: https://github.com/paritytech/substrate/blob/14e0a0b628f9154c5a2c870062c3aac7df8983ed/primitives/consensus/beefy/src/mmr.rs#L52 - function createMMRLeaf(MMRLeafPartial memory leaf, bytes32 parachainHeadsRoot) internal pure returns (bytes32) { + function createMMRLeaf(MMRLeafPartial memory leaf, bytes32 parachainHeadsRoot) + internal + pure + returns (bytes32) + { bytes memory encodedLeaf = bytes.concat( ScaleCodec.encodeU8(leaf.version), ScaleCodec.encodeU32(leaf.parentNumber), diff --git a/contracts/src/interfaces/IERC20.sol b/contracts/src/interfaces/IERC20.sol index 5e921d62db..0dac92ada4 100644 --- a/contracts/src/interfaces/IERC20.sol +++ b/contracts/src/interfaces/IERC20.sol @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: 2023 Axelar Network // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; /** * @dev Interface of the ERC20 standard as defined in the EIP. @@ -65,7 +65,9 @@ interface IERC20 { * * Emits a {Transfer} event. */ - function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); + function transferFrom(address sender, address recipient, uint256 amount) + external + returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to diff --git a/contracts/src/interfaces/IERC20Permit.sol b/contracts/src/interfaces/IERC20Permit.sol index bcd8163669..bc8f4b7bdc 100644 --- a/contracts/src/interfaces/IERC20Permit.sol +++ b/contracts/src/interfaces/IERC20Permit.sol @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: 2023 Axelar Network // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; interface IERC20Permit { error PermitExpired(); @@ -14,6 +14,13 @@ interface IERC20Permit { function nonces(address account) external view returns (uint256); - function permit(address issuer, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) - external; + function permit( + address issuer, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) external; } diff --git a/contracts/src/interfaces/IGateway.sol b/contracts/src/interfaces/IGateway.sol index 1657b73577..c5b8ce9075 100644 --- a/contracts/src/interfaces/IGateway.sol +++ b/contracts/src/interfaces/IGateway.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {OperatingMode, InboundMessage, ParaID, ChannelID, MultiAddress} from "../Types.sol"; import {Verification} from "../Verification.sol"; @@ -12,10 +12,14 @@ interface IGateway { */ // Emitted when inbound message has been dispatched - event InboundMessageDispatched(ChannelID indexed channelID, uint64 nonce, bytes32 indexed messageID, bool success); + event InboundMessageDispatched( + ChannelID indexed channelID, uint64 nonce, bytes32 indexed messageID, bool success + ); // Emitted when an outbound message has been accepted for delivery to a Polkadot parachain - event OutboundMessageAccepted(ChannelID indexed channelID, uint64 nonce, bytes32 indexed messageID, bytes payload); + event OutboundMessageAccepted( + ChannelID indexed channelID, uint64 nonce, bytes32 indexed messageID, bytes payload + ); // Emitted when an agent has been created for a consensus system on Polkadot event AgentCreated(bytes32 agentID, address agent); diff --git a/contracts/src/interfaces/IInitializable.sol b/contracts/src/interfaces/IInitializable.sol index d725dc4d48..e22af42e38 100644 --- a/contracts/src/interfaces/IInitializable.sol +++ b/contracts/src/interfaces/IInitializable.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; /** * @title Initialization of gateway logic contracts diff --git a/contracts/src/interfaces/IShell.sol b/contracts/src/interfaces/IShell.sol index 2066714172..7794a9cde8 100644 --- a/contracts/src/interfaces/IShell.sol +++ b/contracts/src/interfaces/IShell.sol @@ -1,12 +1,13 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; interface IShell { error Unauthorized(); // Upgrade gateway shell to a new implementation - function upgrade(address impl, bytes32 implCodeHash, bytes calldata initializerParams) external; + function upgrade(address impl, bytes32 implCodeHash, bytes calldata initializerParams) + external; // Retrieve address of trusted operator function operator() external returns (address); diff --git a/contracts/src/interfaces/IUpgradable.sol b/contracts/src/interfaces/IUpgradable.sol index beaf62c1d2..268e5bd825 100644 --- a/contracts/src/interfaces/IUpgradable.sol +++ b/contracts/src/interfaces/IUpgradable.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; interface IUpgradable { // The new implementation address is a not a contract diff --git a/contracts/src/interfaces/extensions/IERC20Metadata.sol b/contracts/src/interfaces/extensions/IERC20Metadata.sol index 7f36ccad2a..c3f7eb035c 100644 --- a/contracts/src/interfaces/extensions/IERC20Metadata.sol +++ b/contracts/src/interfaces/extensions/IERC20Metadata.sol @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: 2024 Snowfork // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) -pragma solidity 0.8.25; +pragma solidity 0.8.28; import "../IERC20.sol"; diff --git a/contracts/src/storage/AssetsStorage.sol b/contracts/src/storage/AssetsStorage.sol index 57b5bab21a..8204fb7dd0 100644 --- a/contracts/src/storage/AssetsStorage.sol +++ b/contracts/src/storage/AssetsStorage.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {TokenInfo, ParaID} from "../Types.sol"; diff --git a/contracts/src/storage/CoreStorage.sol b/contracts/src/storage/CoreStorage.sol index 1f8b24a705..35e6ec03c2 100644 --- a/contracts/src/storage/CoreStorage.sol +++ b/contracts/src/storage/CoreStorage.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {Channel, OperatingMode, ChannelID, ParaID} from "../Types.sol"; diff --git a/contracts/src/storage/OperatorStorage.sol b/contracts/src/storage/OperatorStorage.sol index f49e7b001e..5389a12e63 100644 --- a/contracts/src/storage/OperatorStorage.sol +++ b/contracts/src/storage/OperatorStorage.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; library OperatorStorage { struct Layout { diff --git a/contracts/src/storage/PricingStorage.sol b/contracts/src/storage/PricingStorage.sol index 3369e0b396..08bb47c089 100644 --- a/contracts/src/storage/PricingStorage.sol +++ b/contracts/src/storage/PricingStorage.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {UD60x18} from "prb/math/src/UD60x18.sol"; diff --git a/contracts/src/upgrades/Gateway202410.sol b/contracts/src/upgrades/Gateway202410.sol index d049fa825a..655ee06c87 100644 --- a/contracts/src/upgrades/Gateway202410.sol +++ b/contracts/src/upgrades/Gateway202410.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import "../Gateway.sol"; diff --git a/contracts/src/utils/Address.sol b/contracts/src/utils/Address.sol index af9c74ba6a..a8032cdcd4 100644 --- a/contracts/src/utils/Address.sol +++ b/contracts/src/utils/Address.sol @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: 2023 Axelar Network // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; library Address { // Checks whether `account` is a contract diff --git a/contracts/src/utils/Bitfield.sol b/contracts/src/utils/Bitfield.sol index 8a3910c5b2..457f7320f9 100644 --- a/contracts/src/utils/Bitfield.sol +++ b/contracts/src/utils/Bitfield.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {Bits} from "./Bits.sol"; @@ -11,14 +11,22 @@ library Bitfield { * @dev Constants used to efficiently calculate the hamming weight of a bitfield. See * https://en.wikipedia.org/wiki/Hamming_weight#Efficient_implementation for an explanation of those constants. */ - uint256 internal constant M1 = 0x5555555555555555555555555555555555555555555555555555555555555555; - uint256 internal constant M2 = 0x3333333333333333333333333333333333333333333333333333333333333333; - uint256 internal constant M4 = 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f; - uint256 internal constant M8 = 0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff; - uint256 internal constant M16 = 0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff; - uint256 internal constant M32 = 0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff; - uint256 internal constant M64 = 0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff; - uint256 internal constant M128 = 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff; + uint256 internal constant M1 = + 0x5555555555555555555555555555555555555555555555555555555555555555; + uint256 internal constant M2 = + 0x3333333333333333333333333333333333333333333333333333333333333333; + uint256 internal constant M4 = + 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f; + uint256 internal constant M8 = + 0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff; + uint256 internal constant M16 = + 0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff; + uint256 internal constant M32 = + 0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff; + uint256 internal constant M64 = + 0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff; + uint256 internal constant M128 = + 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff; uint256 internal constant ONE = uint256(1); @@ -119,7 +127,11 @@ library Bitfield { self[element] = self[element].clearBit(uint8(index)); } - function makeIndex(uint256 seed, uint256 iteration, uint256 length) internal pure returns (uint256 index) { + function makeIndex(uint256 seed, uint256 iteration, uint256 length) + internal + pure + returns (uint256 index) + { assembly { mstore(0x00, seed) mstore(0x20, iteration) diff --git a/contracts/src/utils/Bits.sol b/contracts/src/utils/Bits.sol index 570a0b947c..1f21a532d9 100644 --- a/contracts/src/utils/Bits.sol +++ b/contracts/src/utils/Bits.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork // Code from https://github.com/ethereum/solidity-examples -pragma solidity 0.8.25; +pragma solidity 0.8.28; library Bits { uint256 internal constant ONE = uint256(1); @@ -78,7 +78,11 @@ library Bits { // - '0 < numBits <= 256' // - 'startIndex < 256' // - 'numBits + startIndex <= 256' - function bits(uint256 self, uint8 startIndex, uint16 numBits) internal pure returns (uint256) { + function bits(uint256 self, uint8 startIndex, uint16 numBits) + internal + pure + returns (uint256) + { require(0 < numBits && startIndex < 256 && startIndex + numBits <= 256, "out of bounds"); return (self >> startIndex) & (ONES >> (256 - numBits)); } diff --git a/contracts/src/utils/Call.sol b/contracts/src/utils/Call.sol index f4e78f667b..51fb033081 100644 --- a/contracts/src/utils/Call.sol +++ b/contracts/src/utils/Call.sol @@ -1,11 +1,15 @@ // SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: 2023 OpenZeppelin // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; // Derived from OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) library Call { - function verifyResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { + function verifyResult(bool success, bytes memory returndata) + internal + pure + returns (bytes memory) + { if (success) { return returndata; } else { diff --git a/contracts/src/utils/ERC1967.sol b/contracts/src/utils/ERC1967.sol index 1bb2a349ba..234efcad4e 100644 --- a/contracts/src/utils/ERC1967.sol +++ b/contracts/src/utils/ERC1967.sol @@ -1,11 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; /// @title Minimal implementation of ERC1967 storage slot library ERC1967 { // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) - bytes32 public constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + bytes32 public constant _IMPLEMENTATION_SLOT = + 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; function load() internal view returns (address implementation) { assembly { diff --git a/contracts/src/utils/MMRProof.sol b/contracts/src/utils/MMRProof.sol index c3e0a89858..63e883e29c 100644 --- a/contracts/src/utils/MMRProof.sol +++ b/contracts/src/utils/MMRProof.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; library MMRProof { error ProofSizeExceeded(); @@ -14,11 +14,12 @@ library MMRProof { * @param proof an array of hashes * @param proofOrder a bitfield describing the order of each item (left vs right) */ - function verifyLeafProof(bytes32 root, bytes32 leafHash, bytes32[] calldata proof, uint256 proofOrder) - internal - pure - returns (bool) - { + function verifyLeafProof( + bytes32 root, + bytes32 leafHash, + bytes32[] calldata proof, + uint256 proofOrder + ) internal pure returns (bool) { // Size of the proof is bounded, since `proofOrder` can only contain `MAXIMUM_PROOF_SIZE` orderings. if (proof.length > MAXIMUM_PROOF_SIZE) { revert ProofSizeExceeded(); @@ -31,7 +32,11 @@ library MMRProof { return root == acc; } - function hashPairs(bytes32 x, bytes32 y, uint256 order) internal pure returns (bytes32 value) { + function hashPairs(bytes32 x, bytes32 y, uint256 order) + internal + pure + returns (bytes32 value) + { assembly { switch order case 0 { diff --git a/contracts/src/utils/Math.sol b/contracts/src/utils/Math.sol index e2e21c141a..5c4ceb0742 100644 --- a/contracts/src/utils/Math.sol +++ b/contracts/src/utils/Math.sol @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: 2023 OpenZeppelin // SPDX-FileCopyrightText: 2023 Snowfork // Code from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/Math.sol -pragma solidity 0.8.25; +pragma solidity 0.8.28; /** * @dev Standard math utilities missing in the Solidity language. diff --git a/contracts/src/utils/SafeTransfer.sol b/contracts/src/utils/SafeTransfer.sol index 73e918db10..bbbd597614 100644 --- a/contracts/src/utils/SafeTransfer.sol +++ b/contracts/src/utils/SafeTransfer.sol @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: 2023 Axelar Network // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {IERC20} from "../interfaces/IERC20.sol"; @@ -12,7 +12,8 @@ error NativeTransferFailed(); library SafeTokenCall { function safeCall(IERC20 token, bytes memory callData) internal { (bool success, bytes memory returnData) = address(token).call(callData); - bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool))); + bool transferred = + success && (returnData.length == uint256(0) || abi.decode(returnData, (bool))); if (!transferred || address(token).code.length == 0) { revert TokenTransferFailed(); } diff --git a/contracts/src/utils/ScaleCodec.sol b/contracts/src/utils/ScaleCodec.sol index df9d19fc7e..7305d80521 100644 --- a/contracts/src/utils/ScaleCodec.sol +++ b/contracts/src/utils/ScaleCodec.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; library ScaleCodec { error UnsupportedCompactEncoding(); @@ -38,13 +38,16 @@ library ScaleCodec { v = input; // swap bytes - v = ((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00) >> 8) | ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF) << 8); + v = ((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00) >> 8) + | ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF) << 8); // swap 2-byte long pairs - v = ((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000) >> 16) | ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF) << 16); + v = ((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000) >> 16) + | ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF) << 16); // swap 4-byte long pairs - v = ((v & 0xFFFFFFFF00000000FFFFFFFF00000000) >> 32) | ((v & 0x00000000FFFFFFFF00000000FFFFFFFF) << 32); + v = ((v & 0xFFFFFFFF00000000FFFFFFFF00000000) >> 32) + | ((v & 0x00000000FFFFFFFF00000000FFFFFFFF) << 32); // swap 8-byte long pairs v = (v >> 64) | (v << 64); diff --git a/contracts/src/utils/SubstrateMerkleProof.sol b/contracts/src/utils/SubstrateMerkleProof.sol index 2de609110f..37050ba926 100644 --- a/contracts/src/utils/SubstrateMerkleProof.sol +++ b/contracts/src/utils/SubstrateMerkleProof.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; // Used to verify merkle proofs generated by https://github.com/paritytech/substrate/tree/master/utils/binary-merkle-tree library SubstrateMerkleProof { @@ -20,11 +20,13 @@ library SubstrateMerkleProof { * @param proof the array of proofs to help verify the leaf's membership, ordered from leaf to root * @return a boolean value representing the success or failure of the operation */ - function verify(bytes32 root, bytes32 leaf, uint256 position, uint256 width, bytes32[] calldata proof) - internal - pure - returns (bool) - { + function verify( + bytes32 root, + bytes32 leaf, + uint256 position, + uint256 width, + bytes32[] calldata proof + ) internal pure returns (bool) { if (position >= width) { return false; } diff --git a/contracts/src/utils/Uint16Array.sol b/contracts/src/utils/Uint16Array.sol index 5fa1ec10ec..7180d5cf4b 100644 --- a/contracts/src/utils/Uint16Array.sol +++ b/contracts/src/utils/Uint16Array.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -pragma solidity 0.8.25; +pragma solidity 0.8.28; /** * @title A utility library for 16 bit counters packed in 256 bit array. diff --git a/contracts/test/Agent.t.sol b/contracts/test/Agent.t.sol index c36fb961a0..160a97c9ff 100644 --- a/contracts/test/Agent.t.sol +++ b/contracts/test/Agent.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import "forge-std/Test.sol"; import "forge-std/console.sol"; @@ -29,7 +29,8 @@ contract AgentTest is Test { } function testInvoke() public { - (bool success, bytes memory result) = agent.invoke(executor, abi.encodeCall(Executor.foo, ())); + (bool success, bytes memory result) = + agent.invoke(executor, abi.encodeCall(Executor.foo, ())); assertEq(success, true); assertEq(result, abi.encode(true)); } @@ -44,7 +45,8 @@ contract AgentTest is Test { } function testInvokeFail() public { - (bool success, bytes memory result) = agent.invoke(executor, abi.encodeCall(Executor.fail, ())); + (bool success, bytes memory result) = + agent.invoke(executor, abi.encodeCall(Executor.fail, ())); assertEq(success, false); assertEq(result, bytes.concat(Executor.Failure.selector)); } diff --git a/contracts/test/BeefyClient.t.sol b/contracts/test/BeefyClient.t.sol index 42566ca4ec..d377e2202b 100644 --- a/contracts/test/BeefyClient.t.sol +++ b/contracts/test/BeefyClient.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {Strings} from "openzeppelin/utils/Strings.sol"; import {Test} from "forge-std/Test.sol"; @@ -50,12 +50,15 @@ contract BeefyClientTest is Test { minNumRequiredSignatures = uint8(vm.envOr("MINIMUM_REQUIRED_SIGNATURES", uint256(16))); prevRandao = uint32(vm.envOr("PREV_RANDAO", uint256(377))); - string memory beefyCommitmentFile = string.concat(vm.projectRoot(), "/test/data/beefy-commitment.json"); + string memory beefyCommitmentFile = + string.concat(vm.projectRoot(), "/test/data/beefy-commitment.json"); string memory beefyCommitmentRaw = vm.readFile(beefyCommitmentFile); - bitFieldFile0SignatureCount = string.concat(vm.projectRoot(), "/test/data/beefy-final-bitfield-0.json"); - bitFieldFile3SignatureCount = string.concat(vm.projectRoot(), "/test/data/beefy-final-bitfield-3.json"); + bitFieldFile0SignatureCount = + string.concat(vm.projectRoot(), "/test/data/beefy-final-bitfield-0.json"); + bitFieldFile3SignatureCount = + string.concat(vm.projectRoot(), "/test/data/beefy-final-bitfield-3.json"); blockNumber = uint32(beefyCommitmentRaw.readUint(".params.commitment.blockNumber")); setId = uint32(beefyCommitmentRaw.readUint(".params.commitment.validatorSetID")); @@ -65,16 +68,21 @@ contract BeefyClientTest is Test { leafProofOrder = beefyCommitmentRaw.readUint(".params.leafProofOrder"); decodeMMRLeaf(beefyCommitmentRaw); - string memory beefyValidatorSetFile = string.concat(vm.projectRoot(), "/test/data/beefy-validator-set.json"); + string memory beefyValidatorSetFile = + string.concat(vm.projectRoot(), "/test/data/beefy-validator-set.json"); string memory beefyValidatorSetRaw = vm.readFile(beefyValidatorSetFile); setSize = uint32(beefyValidatorSetRaw.readUint(".validatorSetSize")); root = beefyValidatorSetRaw.readBytes32(".validatorRoot"); bitSetArray = beefyValidatorSetRaw.readUintArray(".participants"); absentBitSetArray = beefyValidatorSetRaw.readUintArray(".absentees"); - console.log("current validator's merkle root is: %s", Strings.toHexString(uint256(root), 32)); + console.log( + "current validator's merkle root is: %s", Strings.toHexString(uint256(root), 32) + ); - beefyClient = new BeefyClientMock(randaoCommitDelay, randaoCommitExpiration, minNumRequiredSignatures); + beefyClient = new BeefyClientMock( + randaoCommitDelay, randaoCommitExpiration, minNumRequiredSignatures + ); bitfield = beefyClient.createInitialBitfield(bitSetArray, setSize); absentBitfield = beefyClient.createInitialBitfield(absentBitSetArray, setSize); @@ -93,8 +101,10 @@ contract BeefyClientTest is Test { function initialize(uint32 _setId) public returns (BeefyClient.Commitment memory) { currentSetId = _setId; nextSetId = _setId + 1; - BeefyClient.ValidatorSet memory vset = BeefyClient.ValidatorSet(currentSetId, setSize, root); - BeefyClient.ValidatorSet memory nextvset = BeefyClient.ValidatorSet(nextSetId, setSize, root); + BeefyClient.ValidatorSet memory vset = + BeefyClient.ValidatorSet(currentSetId, setSize, root); + BeefyClient.ValidatorSet memory nextvset = + BeefyClient.ValidatorSet(nextSetId, setSize, root); beefyClient.initialize_public(0, vset, nextvset); BeefyClient.PayloadItem[] memory payload = new BeefyClient.PayloadItem[](1); payload[0] = BeefyClient.PayloadItem(mmrRootID, abi.encodePacked(mmrRoot)); @@ -107,9 +117,13 @@ contract BeefyClientTest is Test { } } - function loadFinalProofs(string memory finalProofRaw, BeefyClient.ValidatorProof[] storage finalProofs) internal { + function loadFinalProofs( + string memory finalProofRaw, + BeefyClient.ValidatorProof[] storage finalProofs + ) internal { bytes memory proofRaw = finalProofRaw.readBytes(".finalValidatorsProofRaw"); - BeefyClient.ValidatorProof[] memory proofs = abi.decode(proofRaw, (BeefyClient.ValidatorProof[])); + BeefyClient.ValidatorProof[] memory proofs = + abi.decode(proofRaw, (BeefyClient.ValidatorProof[])); for (uint256 i = 0; i < proofs.length; i++) { finalProofs.push(proofs[i]); } @@ -128,7 +142,9 @@ contract BeefyClientTest is Test { } // Regenerate bitField file - function regenerateBitField(string memory bitfieldFile, uint256 numRequiredSignatures) internal { + function regenerateBitField(string memory bitfieldFile, uint256 numRequiredSignatures) + internal + { console.log("print initialBitField"); printBitArray(bitfield); prevRandao = uint32(vm.envOr("PREV_RANDAO", prevRandao)); @@ -137,7 +153,8 @@ contract BeefyClientTest is Test { printBitArray(finalBitfield); string memory finalBitFieldRaw = ""; - finalBitFieldRaw = finalBitFieldRaw.serialize("finalBitFieldRaw", abi.encode(finalBitfield)); + finalBitFieldRaw = + finalBitFieldRaw.serialize("finalBitFieldRaw", abi.encode(finalBitfield)); string memory finaliBitFieldStr = ""; finaliBitFieldStr = finaliBitFieldStr.serialize("finalBitField", finalBitfield); @@ -151,10 +168,14 @@ contract BeefyClientTest is Test { uint8 version = uint8(beefyCommitmentRaw.readUint(".params.leaf.version")); uint32 parentNumber = uint32(beefyCommitmentRaw.readUint(".params.leaf.parentNumber")); bytes32 parentHash = beefyCommitmentRaw.readBytes32(".params.leaf.parentHash"); - uint64 nextAuthoritySetID = uint64(beefyCommitmentRaw.readUint(".params.leaf.nextAuthoritySetID")); - uint32 nextAuthoritySetLen = uint32(beefyCommitmentRaw.readUint(".params.leaf.nextAuthoritySetLen")); - bytes32 nextAuthoritySetRoot = beefyCommitmentRaw.readBytes32(".params.leaf.nextAuthoritySetRoot"); - bytes32 parachainHeadsRoot = beefyCommitmentRaw.readBytes32(".params.leaf.parachainHeadsRoot"); + uint64 nextAuthoritySetID = + uint64(beefyCommitmentRaw.readUint(".params.leaf.nextAuthoritySetID")); + uint32 nextAuthoritySetLen = + uint32(beefyCommitmentRaw.readUint(".params.leaf.nextAuthoritySetLen")); + bytes32 nextAuthoritySetRoot = + beefyCommitmentRaw.readBytes32(".params.leaf.nextAuthoritySetRoot"); + bytes32 parachainHeadsRoot = + beefyCommitmentRaw.readBytes32(".params.leaf.parachainHeadsRoot"); mmrLeaf = BeefyClient.MMRLeaf( version, parentNumber, @@ -181,7 +202,12 @@ contract BeefyClientTest is Test { createFinalProofs(); beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder + commitment, + bitfield, + finalValidatorProofs, + emptyLeaf, + emptyLeafProofs, + emptyLeafProofOrder ); assertEq(beefyClient.latestBeefyBlock(), blockNumber); @@ -236,7 +262,12 @@ contract BeefyClientTest is Test { createFinalProofs(); beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs3SignatureCount, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder + commitment, + bitfield, + finalValidatorProofs3SignatureCount, + emptyLeaf, + emptyLeafProofs, + emptyLeafProofOrder ); assertEq(beefyClient.latestBeefyBlock(), blockNumber); @@ -268,7 +299,9 @@ contract BeefyClientTest is Test { // make an invalid signature vm.expectRevert(BeefyClient.InvalidValidatorProofLength.selector); - beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); + beefyClient.submitFinal( + commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder + ); } function testSubmitFailInvalidSignature() public { @@ -284,10 +317,16 @@ contract BeefyClientTest is Test { createFinalProofs(); // make an invalid signature - finalValidatorProofs[0].r = 0xb5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c; + finalValidatorProofs[0].r = + 0xb5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c; vm.expectRevert(BeefyClient.InvalidSignature.selector); beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder + commitment, + bitfield, + finalValidatorProofs, + emptyLeaf, + emptyLeafProofs, + emptyLeafProofOrder ); } @@ -307,7 +346,12 @@ contract BeefyClientTest is Test { finalValidatorProofs[0].index = 0; vm.expectRevert(BeefyClient.InvalidValidatorProof.selector); beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder + commitment, + bitfield, + finalValidatorProofs, + emptyLeaf, + emptyLeafProofs, + emptyLeafProofOrder ); } @@ -328,7 +372,12 @@ contract BeefyClientTest is Test { vm.expectRevert(BeefyClient.StaleCommitment.selector); beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder + commitment, + bitfield, + finalValidatorProofs, + emptyLeaf, + emptyLeafProofs, + emptyLeafProofOrder ); } @@ -347,7 +396,12 @@ contract BeefyClientTest is Test { bitfield[0] = 0; vm.expectRevert(BeefyClient.InvalidBitfield.selector); beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder + commitment, + bitfield, + finalValidatorProofs, + emptyLeaf, + emptyLeafProofs, + emptyLeafProofOrder ); } @@ -359,7 +413,12 @@ contract BeefyClientTest is Test { // reverted without commit PrevRandao vm.expectRevert(BeefyClient.PrevRandaoNotCaptured.selector); beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder + commitment, + bitfield, + finalValidatorProofs, + emptyLeaf, + emptyLeafProofs, + emptyLeafProofOrder ); } @@ -404,7 +463,9 @@ contract BeefyClientTest is Test { createFinalProofs(); - beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); + beefyClient.submitFinal( + commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder + ); assertEq(beefyClient.latestBeefyBlock(), blockNumber); assertEq(beefyClient.getValidatorCounter(false, finalValidatorProofs[0].index), 1); assertEq(beefyClient.getValidatorCounter(true, finalValidatorProofs[0].index), 0); @@ -429,7 +490,9 @@ contract BeefyClientTest is Test { createFinalProofs(); - beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); + beefyClient.submitFinal( + commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder + ); assertEq(beefyClient.latestBeefyBlock(), blockNumber); assertEq(beefyClient.getValidatorCounter(false, finalValidatorProofs[0].index), 1); assertEq(beefyClient.getValidatorCounter(true, finalValidatorProofs[0].index), 0); @@ -474,7 +537,12 @@ contract BeefyClientTest is Test { createFinalProofs(); beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs3SignatureCount, mmrLeaf, mmrLeafProofs, leafProofOrder + commitment, + bitfield, + finalValidatorProofs3SignatureCount, + mmrLeaf, + mmrLeafProofs, + leafProofOrder ); assertEq(beefyClient.latestBeefyBlock(), blockNumber); assertEq(beefyClient.getValidatorCounter(false, finalValidatorProofs[0].index), 4); @@ -483,7 +551,9 @@ contract BeefyClientTest is Test { assertEq(beefyClient.getValidatorCounter(true, finalValidatorProofs[1].index), 0); } - function testSubmitWithHandoverFailWithInvalidValidatorProofWhenNotProvidingSignatureCount() public { + function testSubmitWithHandoverFailWithInvalidValidatorProofWhenNotProvidingSignatureCount() + public + { //initialize with previous set BeefyClient.Commitment memory commitment = initialize(setId - 1); @@ -503,7 +573,9 @@ contract BeefyClientTest is Test { createFinalProofs(); vm.expectRevert(BeefyClient.InvalidValidatorProofLength.selector); - beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); + beefyClient.submitFinal( + commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder + ); } function testSubmitWithHandoverFailWithoutPrevRandao() public { @@ -513,7 +585,9 @@ contract BeefyClientTest is Test { beefyClient.submitInitial(commitment, bitfield, finalValidatorProofs[0]); vm.expectRevert(BeefyClient.PrevRandaoNotCaptured.selector); - beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); + beefyClient.submitFinal( + commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder + ); } function testSubmitWithHandoverFailStaleCommitment() public { @@ -533,15 +607,21 @@ contract BeefyClientTest is Test { vm.expectRevert(BeefyClient.StaleCommitment.selector); beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder + commitment, + bitfield, + finalValidatorProofs, + emptyLeaf, + emptyLeafProofs, + emptyLeafProofOrder ); } function testScaleEncodeCommit() public { BeefyClient.PayloadItem[] memory _payload = new BeefyClient.PayloadItem[](2); _payload[0] = BeefyClient.PayloadItem(bytes2("ab"), hex"000102"); - _payload[1] = - BeefyClient.PayloadItem(mmrRootID, hex"3ac49cd24778522203e8bf40a4712ea3f07c3803bbd638cb53ebb3564ec13e8c"); + _payload[1] = BeefyClient.PayloadItem( + mmrRootID, hex"3ac49cd24778522203e8bf40a4712ea3f07c3803bbd638cb53ebb3564ec13e8c" + ); BeefyClient.Commitment memory _commitment = BeefyClient.Commitment(5, 7, _payload); @@ -601,7 +681,9 @@ contract BeefyClientTest is Test { initialize(setId + 1); //submit will be reverted with InvalidCommitment vm.expectRevert(BeefyClient.InvalidCommitment.selector); - beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); + beefyClient.submitFinal( + commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder + ); } function testSubmitWithHandoverFailWithInvalidValidatorSet() public { @@ -619,7 +701,9 @@ contract BeefyClientTest is Test { initialize(setId + 1); //submit will be reverted with InvalidCommitment vm.expectRevert(BeefyClient.InvalidCommitment.selector); - beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); + beefyClient.submitFinal( + commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder + ); } function testSubmitFailWithInvalidTicket() public { @@ -633,10 +717,13 @@ contract BeefyClientTest is Test { // Changing the commitment changes its hash, so the ticket can't be found. // A zero value ticket is returned in this case, because submitInitial hasn't run for this commitment. - BeefyClient.Commitment memory _commitment = BeefyClient.Commitment(blockNumber, setId + 1, commitment.payload); + BeefyClient.Commitment memory _commitment = + BeefyClient.Commitment(blockNumber, setId + 1, commitment.payload); //submit will be reverted with InvalidTicket vm.expectRevert(BeefyClient.InvalidTicket.selector); - beefyClient.submitFinal(_commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); + beefyClient.submitFinal( + _commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder + ); } function testSubmitFailWithInvalidMMRLeaf() public { @@ -657,7 +744,9 @@ contract BeefyClientTest is Test { mmrLeaf.nextAuthoritySetID = setId; //submit will be reverted with InvalidMMRLeaf vm.expectRevert(BeefyClient.InvalidMMRLeaf.selector); - beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); + beefyClient.submitFinal( + commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder + ); } function testSubmitFailWithInvalidMMRLeafProof() public { @@ -676,7 +765,9 @@ contract BeefyClientTest is Test { mmrLeaf.parentNumber = 1; //submit will be reverted with InvalidMMRLeafProof vm.expectRevert(BeefyClient.InvalidMMRLeafProof.selector); - beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); + beefyClient.submitFinal( + commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder + ); } function testSubmitFailWithNotEnoughClaims() public { @@ -694,7 +785,8 @@ contract BeefyClientTest is Test { beefyClient.computeNumRequiredSignatures_public(setSize, 0, minNumRequiredSignatures); regenerateBitField(bitFieldFile0SignatureCount, numRequiredSignatures); // Generate a bitfield for signature count 3. - numRequiredSignatures = beefyClient.computeNumRequiredSignatures_public(setSize, 3, minNumRequiredSignatures); + numRequiredSignatures = + beefyClient.computeNumRequiredSignatures_public(setSize, 3, minNumRequiredSignatures); regenerateBitField(bitFieldFile3SignatureCount, numRequiredSignatures); } @@ -709,16 +801,19 @@ contract BeefyClientTest is Test { assertGt(result, 0, "result is greater than zero."); } - function testFuzzSignatureSamplingRanges(uint128 validatorSetLen, uint16 signatureUsageCount, uint16 minSignatures) - public - { + function testFuzzSignatureSamplingRanges( + uint128 validatorSetLen, + uint16 signatureUsageCount, + uint16 minSignatures + ) public { // There must be atleast 1 validator. vm.assume(validatorSetLen > 0); // Min signatures must be less than the amount of validators. vm.assume(beefyClient.computeQuorum_public(validatorSetLen) > minSignatures); - uint256 result = - beefyClient.computeNumRequiredSignatures_public(validatorSetLen, signatureUsageCount, minSignatures); + uint256 result = beefyClient.computeNumRequiredSignatures_public( + validatorSetLen, signatureUsageCount, minSignatures + ); // Calculator 2/3 with flooring due to integer division plus 1. uint256 twoThirdsMajority = uint256(validatorSetLen) * 2 / 3 + 1; diff --git a/contracts/test/Bitfield.t.sol b/contracts/test/Bitfield.t.sol index 2334e399a4..3fe6f3e4f9 100644 --- a/contracts/test/Bitfield.t.sol +++ b/contracts/test/Bitfield.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {Test} from "forge-std/Test.sol"; import {console} from "forge-std/console.sol"; @@ -14,7 +14,8 @@ contract BitfieldTest is Test { function testBitfieldSubsampling() public { BitfieldWrapper bw = new BitfieldWrapper(); - string memory json = vm.readFile(string.concat(vm.projectRoot(), "/test/data/beefy-validator-set.json")); + string memory json = + vm.readFile(string.concat(vm.projectRoot(), "/test/data/beefy-validator-set.json")); uint32 setSize = uint32(json.readUint(".validatorSetSize")); bytes32 root = json.readBytes32(".validatorRoot"); uint256[] memory bitSetArray = json.readUintArray(".participants"); diff --git a/contracts/test/ForkUpgrade.t.sol b/contracts/test/ForkUpgrade.t.sol index 5b1a6069dd..dece813a1e 100644 --- a/contracts/test/ForkUpgrade.t.sol +++ b/contracts/test/ForkUpgrade.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {Test} from "forge-std/Test.sol"; import {console} from "forge-std/console.sol"; @@ -9,16 +9,24 @@ import {IGateway} from "../src/interfaces/IGateway.sol"; import {Gateway} from "../src/Gateway.sol"; import {Gateway202410} from "../src/upgrades/Gateway202410.sol"; import {AgentExecutor} from "../src/AgentExecutor.sol"; -import {UpgradeParams, SetOperatingModeParams, OperatingMode, RegisterForeignTokenParams} from "../src/Params.sol"; +import { + UpgradeParams, + SetOperatingModeParams, + OperatingMode, + RegisterForeignTokenParams +} from "../src/Params.sol"; import {ChannelID, ParaID, OperatingMode, TokenInfo} from "../src/Types.sol"; contract ForkUpgradeTest is Test { address private constant GatewayProxy = 0x27ca963C279c93801941e1eB8799c23f407d68e7; address private constant BeefyClient = 0x6eD05bAa904df3DE117EcFa638d4CB84e1B8A00C; - bytes32 private constant BridgeHubAgent = 0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314; + bytes32 private constant BridgeHubAgent = + 0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314; function setUp() public { - vm.createSelectFork("https://rpc.tenderly.co/fork/b77e07b8-ad6d-4e83-b5be-30a2001964aa", 20645700); + vm.createSelectFork( + "https://rpc.tenderly.co/fork/b77e07b8-ad6d-4e83-b5be-30a2001964aa", 20_645_700 + ); vm.allowCheatcodes(GatewayProxy); vm.startPrank(GatewayProxy); forkUpgrade(); @@ -27,11 +35,15 @@ contract ForkUpgradeTest is Test { function forkUpgrade() public { AgentExecutor executor = new AgentExecutor(); - Gateway202410 newLogic = - new Gateway202410(BeefyClient, address(executor), ParaID.wrap(1002), BridgeHubAgent, 10, 20000000000); + Gateway202410 newLogic = new Gateway202410( + BeefyClient, address(executor), ParaID.wrap(1002), BridgeHubAgent, 10, 20_000_000_000 + ); - UpgradeParams memory params = - UpgradeParams({impl: address(newLogic), implCodeHash: address(newLogic).codehash, initParams: bytes("")}); + UpgradeParams memory params = UpgradeParams({ + impl: address(newLogic), + implCodeHash: address(newLogic).codehash, + initParams: bytes("") + }); vm.expectEmit(true, false, false, false); emit IUpgradable.Upgraded(address(newLogic)); @@ -40,23 +52,42 @@ contract ForkUpgradeTest is Test { } function checkLegacyToken() public { - assert(IGateway(GatewayProxy).isTokenRegistered(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)); - assertEq(IGateway(GatewayProxy).queryForeignTokenID(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2), bytes32("")); - assert(IGateway(GatewayProxy).isTokenRegistered(0xBA41Ddf06B7fFD89D1267b5A93BFeF2424eb2003)); - assertEq(IGateway(GatewayProxy).queryForeignTokenID(0xBA41Ddf06B7fFD89D1267b5A93BFeF2424eb2003), bytes32("")); + assert( + IGateway(GatewayProxy).isTokenRegistered(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2) + ); + assertEq( + IGateway(GatewayProxy).queryForeignTokenID(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2), + bytes32("") + ); + assert( + IGateway(GatewayProxy).isTokenRegistered(0xBA41Ddf06B7fFD89D1267b5A93BFeF2424eb2003) + ); + assertEq( + IGateway(GatewayProxy).queryForeignTokenID(0xBA41Ddf06B7fFD89D1267b5A93BFeF2424eb2003), + bytes32("") + ); } function registerForeignToken() public { bytes32 dotId = 0xa8f2ec5bdd7a07d844ee3bce83f9ba3881f495d96f07cacbeeb77d9e031db4f0; - RegisterForeignTokenParams memory params = - RegisterForeignTokenParams({foreignTokenID: dotId, name: "DOT", symbol: "DOT", decimals: 10}); + RegisterForeignTokenParams memory params = RegisterForeignTokenParams({ + foreignTokenID: dotId, + name: "DOT", + symbol: "DOT", + decimals: 10 + }); vm.expectEmit(true, true, false, false); emit IGateway.ForeignTokenRegistered(dotId, address(0x0)); Gateway202410(GatewayProxy).registerForeignToken(abi.encode(params)); - assert(IGateway(GatewayProxy).isTokenRegistered(0x70D9d338A6b17957B16836a90192BD8CDAe0b53d)); - assertEq(IGateway(GatewayProxy).queryForeignTokenID(0x70D9d338A6b17957B16836a90192BD8CDAe0b53d), dotId); + assert( + IGateway(GatewayProxy).isTokenRegistered(0x70D9d338A6b17957B16836a90192BD8CDAe0b53d) + ); + assertEq( + IGateway(GatewayProxy).queryForeignTokenID(0x70D9d338A6b17957B16836a90192BD8CDAe0b53d), + dotId + ); } function testSanityCheck() public { diff --git a/contracts/test/Gateway.t.sol b/contracts/test/Gateway.t.sol index 96705c5c9f..d8022f619f 100644 --- a/contracts/test/Gateway.t.sol +++ b/contracts/test/Gateway.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {Test} from "forge-std/Test.sol"; import {Strings} from "openzeppelin/utils/Strings.sol"; @@ -21,7 +21,15 @@ import {Verification} from "../src/Verification.sol"; import {Assets} from "../src/Assets.sol"; import {SubstrateTypes} from "./../src/SubstrateTypes.sol"; import {MultiAddress} from "../src/MultiAddress.sol"; -import {Channel, InboundMessage, OperatingMode, ParaID, Command, ChannelID, MultiAddress} from "../src/Types.sol"; +import { + Channel, + InboundMessage, + OperatingMode, + ParaID, + Command, + ChannelID, + MultiAddress +} from "../src/Types.sol"; import {NativeTransferFailed} from "../src/utils/SafeTransfer.sol"; import {PricingStorage} from "../src/storage/PricingStorage.sol"; @@ -62,16 +70,19 @@ contract GatewayTest is Test { event Transfer(address indexed from, address indexed to, uint256 value); ParaID public bridgeHubParaID = ParaID.wrap(1013); - bytes32 public bridgeHubAgentID = 0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314; + bytes32 public bridgeHubAgentID = + 0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314; address public bridgeHubAgent; ParaID public assetHubParaID = ParaID.wrap(1000); - bytes32 public assetHubAgentID = 0x81c5ab2571199e3188135178f3c2c8e2d268be1313d029b30f534fa579b69b79; + bytes32 public assetHubAgentID = + 0x81c5ab2571199e3188135178f3c2c8e2d268be1313d029b30f534fa579b69b79; address public assetHubAgent; address public relayer; - bytes32[] public proof = [bytes32(0x2f9ee6cfdf244060dc28aa46347c5219e303fc95062dd672b4e406ca5c29764b)]; + bytes32[] public proof = + [bytes32(0x2f9ee6cfdf244060dc28aa46347c5219e303fc95062dd672b4e406ca5c29764b)]; bytes public parachainHeaderProof = bytes("validProof"); MockGateway public gatewayLogic; @@ -110,7 +121,12 @@ contract GatewayTest is Test { function setUp() public { AgentExecutor executor = new AgentExecutor(); gatewayLogic = new MockGateway( - address(0), address(executor), bridgeHubParaID, bridgeHubAgentID, foreignTokenDecimals, maxDestinationFee + address(0), + address(executor), + bridgeHubParaID, + bridgeHubAgentID, + foreignTokenDecimals, + maxDestinationFee ); Gateway.Config memory config = Gateway.Config({ mode: OperatingMode.Normal, @@ -201,7 +217,16 @@ contract GatewayTest is Test { hoax(relayer, 1 ether); IGateway(address(gateway)).submitV1( - InboundMessage(assetHubParaID.into(), 1, command, params, maxDispatchGas, maxRefund, reward, messageID), + InboundMessage( + assetHubParaID.into(), + 1, + command, + params, + maxDispatchGas, + maxRefund, + reward, + messageID + ), proof, makeMockProof() ); @@ -214,7 +239,16 @@ contract GatewayTest is Test { hoax(relayer, 1 ether); IGateway(address(gateway)).submitV1( - InboundMessage(assetHubParaID.into(), 1, command, params, maxDispatchGas, maxRefund, reward, messageID), + InboundMessage( + assetHubParaID.into(), + 1, + command, + params, + maxDispatchGas, + maxRefund, + reward, + messageID + ), proof, makeMockProof() ); @@ -223,7 +257,16 @@ contract GatewayTest is Test { vm.expectRevert(Gateway.InvalidNonce.selector); hoax(relayer, 1 ether); IGateway(address(gateway)).submitV1( - InboundMessage(assetHubParaID.into(), 1, command, params, maxDispatchGas, maxRefund, reward, messageID), + InboundMessage( + assetHubParaID.into(), + 1, + command, + params, + maxDispatchGas, + maxRefund, + reward, + messageID + ), proof, makeMockProof() ); @@ -235,7 +278,16 @@ contract GatewayTest is Test { vm.expectRevert(Gateway.ChannelDoesNotExist.selector); hoax(relayer); IGateway(address(gateway)).submitV1( - InboundMessage(ParaID.wrap(42).into(), 1, command, "", maxDispatchGas, maxRefund, reward, messageID), + InboundMessage( + ParaID.wrap(42).into(), + 1, + command, + "", + maxDispatchGas, + maxRefund, + reward, + messageID + ), proof, makeMockProof() ); @@ -251,7 +303,16 @@ contract GatewayTest is Test { hoax(relayer, 1 ether); IGateway(address(gateway)).submitV1( - InboundMessage(assetHubParaID.into(), 1, command, params, maxDispatchGas, maxRefund, reward, messageID), + InboundMessage( + assetHubParaID.into(), + 1, + command, + params, + maxDispatchGas, + maxRefund, + reward, + messageID + ), proof, makeMockProof() ); @@ -274,7 +335,16 @@ contract GatewayTest is Test { uint256 startGas = gasleft(); IGateway(address(gateway)).submitV1( - InboundMessage(assetHubParaID.into(), 1, command, params, maxDispatchGas, maxRefund, reward, messageID), + InboundMessage( + assetHubParaID.into(), + 1, + command, + params, + maxDispatchGas, + maxRefund, + reward, + messageID + ), proof, makeMockProof() ); @@ -300,7 +370,16 @@ contract GatewayTest is Test { hoax(relayer, 1 ether); IGateway(address(gateway)).submitV1( - InboundMessage(assetHubParaID.into(), 1, command, params, maxDispatchGas, maxRefund, reward, messageID), + InboundMessage( + assetHubParaID.into(), + 1, + command, + params, + maxDispatchGas, + maxRefund, + reward, + messageID + ), proof, makeMockProof() ); @@ -326,7 +405,9 @@ contract GatewayTest is Test { token.approve(address(gateway), 1); hoax(user, fee); - IGateway(address(gateway)).sendToken{value: fee}(address(token), ParaID.wrap(0), recipientAddress32, 1, 1); + IGateway(address(gateway)).sendToken{value: fee}( + address(token), ParaID.wrap(0), recipientAddress32, 1, 1 + ); assertEq(user.balance, 0); } @@ -372,15 +453,19 @@ contract GatewayTest is Test { } function testAgentExecutionBadOrigin() public { - TransferNativeFromAgentParams memory params = - TransferNativeFromAgentParams({agentID: bytes32(0), recipient: address(this), amount: 1}); + TransferNativeFromAgentParams memory params = TransferNativeFromAgentParams({ + agentID: bytes32(0), + recipient: address(this), + amount: 1 + }); vm.expectRevert(Gateway.AgentDoesNotExist.selector); MockGateway(address(gateway)).transferNativeFromAgentPublic(abi.encode(params)); } function testAgentExecutionBadPayload() public { - AgentExecuteParams memory params = AgentExecuteParams({agentID: assetHubAgentID, payload: ""}); + AgentExecuteParams memory params = + AgentExecuteParams({agentID: assetHubAgentID, payload: ""}); vm.expectRevert(Gateway.InvalidAgentExecutionPayload.selector); MockGateway(address(gateway)).agentExecutePublic(abi.encode(params)); @@ -410,10 +495,15 @@ contract GatewayTest is Test { ParaID paraID = ParaID.wrap(3042); bytes32 agentID = keccak256("3042"); - MockGateway(address(gateway)).createAgentPublic(abi.encode(CreateAgentParams({agentID: agentID}))); + MockGateway(address(gateway)).createAgentPublic( + abi.encode(CreateAgentParams({agentID: agentID})) + ); - CreateChannelParams memory params = - CreateChannelParams({channelID: paraID.into(), agentID: agentID, mode: OperatingMode.Normal}); + CreateChannelParams memory params = CreateChannelParams({ + channelID: paraID.into(), + agentID: agentID, + mode: OperatingMode.Normal + }); vm.expectEmit(true, false, false, true); emit IGateway.ChannelCreated(paraID.into()); @@ -424,8 +514,11 @@ contract GatewayTest is Test { ParaID paraID = ParaID.wrap(3042); bytes32 agentID = keccak256("3042"); - CreateChannelParams memory params = - CreateChannelParams({channelID: paraID.into(), mode: OperatingMode.Normal, agentID: agentID}); + CreateChannelParams memory params = CreateChannelParams({ + channelID: paraID.into(), + mode: OperatingMode.Normal, + agentID: agentID + }); vm.expectRevert(Gateway.AgentDoesNotExist.selector); MockGateway(address(gateway)).createChannelPublic(abi.encode(params)); @@ -435,10 +528,15 @@ contract GatewayTest is Test { ParaID paraID = ParaID.wrap(3042); bytes32 agentID = keccak256("3042"); - MockGateway(address(gateway)).createAgentPublic(abi.encode(CreateAgentParams({agentID: agentID}))); + MockGateway(address(gateway)).createAgentPublic( + abi.encode(CreateAgentParams({agentID: agentID})) + ); - CreateChannelParams memory params = - CreateChannelParams({channelID: paraID.into(), agentID: agentID, mode: OperatingMode.Normal}); + CreateChannelParams memory params = CreateChannelParams({ + channelID: paraID.into(), + agentID: agentID, + mode: OperatingMode.Normal + }); MockGateway(address(gateway)).createChannelPublic(abi.encode(params)); @@ -452,7 +550,10 @@ contract GatewayTest is Test { uint256 fee = pricing.deliveryCost; bytes memory params = abi.encode( - UpdateChannelParams({channelID: assetHubParaID.into(), mode: OperatingMode.RejectingOutboundMessages}) + UpdateChannelParams({ + channelID: assetHubParaID.into(), + mode: OperatingMode.RejectingOutboundMessages + }) ); vm.expectEmit(true, false, false, true); @@ -466,7 +567,10 @@ contract GatewayTest is Test { function testUpdateChannelFailDoesNotExist() public { bytes memory params = abi.encode( - UpdateChannelParams({channelID: ParaID.wrap(5956).into(), mode: OperatingMode.RejectingOutboundMessages}) + UpdateChannelParams({ + channelID: ParaID.wrap(5956).into(), + mode: OperatingMode.RejectingOutboundMessages + }) ); vm.expectRevert(Gateway.ChannelDoesNotExist.selector); @@ -521,15 +625,19 @@ contract GatewayTest is Test { function testUpgradeFailCodeHashMismatch() public { MockGatewayV2 newLogic = new MockGatewayV2(); - UpgradeParams memory params = - UpgradeParams({impl: address(newLogic), implCodeHash: bytes32(0), initParams: abi.encode(42)}); + UpgradeParams memory params = UpgradeParams({ + impl: address(newLogic), + implCodeHash: bytes32(0), + initParams: abi.encode(42) + }); vm.expectRevert(IUpgradable.InvalidCodeHash.selector); MockGateway(address(gateway)).upgradePublic(abi.encode(params)); } function testSetOperatingMode() public { - SetOperatingModeParams memory params = SetOperatingModeParams({mode: OperatingMode.RejectingOutboundMessages}); + SetOperatingModeParams memory params = + SetOperatingModeParams({mode: OperatingMode.RejectingOutboundMessages}); OperatingMode mode = IGateway(address(gateway)).operatingMode(); assertEq(uint256(mode), 0); @@ -545,8 +653,13 @@ contract GatewayTest is Test { address recipient = makeAddr("recipient"); - bytes memory params = - abi.encode(TransferNativeFromAgentParams({agentID: assetHubAgentID, recipient: recipient, amount: 3 ether})); + bytes memory params = abi.encode( + TransferNativeFromAgentParams({ + agentID: assetHubAgentID, + recipient: recipient, + amount: 3 ether + }) + ); MockGateway(address(gateway)).transferNativeFromAgentPublic(params); @@ -606,7 +719,9 @@ contract GatewayTest is Test { vm.expectEmit(true, false, false, false); emit IGateway.OutboundMessageAccepted(assetHubParaID.into(), 1, messageID, bytes("")); - IGateway(address(gateway)).sendToken{value: fee}(address(token), destPara, recipientAddress32, 1, 1); + IGateway(address(gateway)).sendToken{value: fee}( + address(token), destPara, recipientAddress32, 1, 1 + ); } function testSendTokenAddress32ToAssetHub() public { @@ -629,7 +744,9 @@ contract GatewayTest is Test { vm.expectEmit(true, false, false, false); emit IGateway.OutboundMessageAccepted(assetHubParaID.into(), 1, messageID, bytes("")); - IGateway(address(gateway)).sendToken{value: fee}(address(token), destPara, recipientAddress32, 1, 1); + IGateway(address(gateway)).sendToken{value: fee}( + address(token), destPara, recipientAddress32, 1, 1 + ); } function testSendTokenAddress20() public { @@ -652,7 +769,9 @@ contract GatewayTest is Test { vm.expectEmit(true, false, false, false); emit IGateway.OutboundMessageAccepted(assetHubParaID.into(), 1, messageID, bytes("")); - IGateway(address(gateway)).sendToken{value: fee}(address(token), destPara, recipientAddress20, 1, 1); + IGateway(address(gateway)).sendToken{value: fee}( + address(token), destPara, recipientAddress20, 1, 1 + ); } function testSendTokenAddress20FailsInvalidDestination() public { @@ -667,7 +786,9 @@ contract GatewayTest is Test { // Should fail to send tokens to AssetHub vm.expectRevert(Assets.Unsupported.selector); - IGateway(address(gateway)).sendToken{value: 2 ether}(address(token), destPara, recipientAddress20, 1, 1); + IGateway(address(gateway)).sendToken{value: 2 ether}( + address(token), destPara, recipientAddress20, 1, 1 + ); } /** @@ -698,11 +819,15 @@ contract GatewayTest is Test { IGateway(address(gateway)).registerToken{value: fee}(address(token)); bytes memory params = abi.encode( - UpdateChannelParams({channelID: assetHubParaID.into(), mode: OperatingMode.RejectingOutboundMessages}) + UpdateChannelParams({ + channelID: assetHubParaID.into(), + mode: OperatingMode.RejectingOutboundMessages + }) ); MockGateway(address(gateway)).updateChannelPublic(params); - OperatingMode mode = IGateway(address(gateway)).channelOperatingModeOf(assetHubParaID.into()); + OperatingMode mode = + IGateway(address(gateway)).channelOperatingModeOf(assetHubParaID.into()); assertEq(uint256(mode), 1); // Now all outbound messaging should be disabled @@ -711,7 +836,9 @@ contract GatewayTest is Test { IGateway(address(gateway)).registerToken{value: 1 ether}(address(token)); vm.expectRevert(Gateway.Disabled.selector); - IGateway(address(gateway)).sendToken{value: 1 ether}(address(token), ParaID.wrap(0), recipientAddress32, 1, 1); + IGateway(address(gateway)).sendToken{value: 1 ether}( + address(token), ParaID.wrap(0), recipientAddress32, 1, 1 + ); } /** @@ -758,7 +885,7 @@ contract GatewayTest is Test { assertEq(uint256(channelMode), 0); (, uint128 fee) = gw.pricingParameters(); - assertEq(fee, 10000000000); + assertEq(fee, 10_000_000_000); (uint64 inbound, uint64 outbound) = gw.channelNoncesOf(assetHubParaID.into()); assertEq(inbound, 0); @@ -783,7 +910,9 @@ contract GatewayTest is Test { emit IGateway.InboundMessageDispatched(assetHubParaID.into(), 1, messageID, false); // maxDispatchGas as 1 for `create_agent` is definitely not enough IGateway(address(gateway)).submitV1( - InboundMessage(assetHubParaID.into(), 1, command, params, 1, maxRefund, reward, messageID), + InboundMessage( + assetHubParaID.into(), 1, command, params, 1, maxRefund, reward, messageID + ), proof, makeMockProof() ); @@ -791,7 +920,7 @@ contract GatewayTest is Test { function testSetTokenFees() public { uint256 fee = IGateway(address(gateway)).quoteRegisterTokenFee(); - assertEq(fee, 5000000000000000); + assertEq(fee, 5_000_000_000_000_000); // Double the assetHubCreateAssetFee MockGateway(address(gateway)).setTokenTransferFeesPublic( abi.encode( @@ -804,10 +933,11 @@ contract GatewayTest is Test { ); fee = IGateway(address(gateway)).quoteRegisterTokenFee(); // since deliveryCost not changed, so the total fee increased only by 50% - assertEq(fee, 7500000000000000); + assertEq(fee, 7_500_000_000_000_000); } - bytes32 public expectChannelIDBytes = bytes32(0xc173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539); + bytes32 public expectChannelIDBytes = + bytes32(0xc173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539); function testDeriveChannelID() public { ParaID para_id = ParaID.wrap(1000); @@ -817,7 +947,7 @@ contract GatewayTest is Test { function testSetPricingParameters() public { uint256 fee = IGateway(address(gateway)).quoteRegisterTokenFee(); - assertEq(fee, 5000000000000000); + assertEq(fee, 5_000_000_000_000_000); // Double both the exchangeRate and multiplier. Should lead to an 4x fee increase MockGateway(address(gateway)).setPricingParametersPublic( abi.encode( @@ -830,7 +960,7 @@ contract GatewayTest is Test { ); // Should expect 4x fee increase fee = IGateway(address(gateway)).quoteRegisterTokenFee(); - assertEq(fee, 20000000000000001); + assertEq(fee, 20_000_000_000_000_001); } function testSendTokenWithZeroDestinationFee() public { @@ -846,7 +976,9 @@ contract GatewayTest is Test { fee = IGateway(address(gateway)).quoteSendTokenFee(address(token), destPara, 0); vm.expectRevert(Assets.InvalidDestinationFee.selector); - IGateway(address(gateway)).sendToken{value: fee}(address(token), destPara, recipientAddress32, 0, 1); + IGateway(address(gateway)).sendToken{value: fee}( + address(token), destPara, recipientAddress32, 0, 1 + ); } function testSendTokenWithLargeDestinationFee() public { @@ -861,7 +993,9 @@ contract GatewayTest is Test { IGateway(address(gateway)).registerToken{value: fee}(address(token)); vm.expectRevert(Assets.InvalidDestinationFee.selector); - IGateway(address(gateway)).quoteSendTokenFee(address(token), destPara, maxDestinationFee + 1); + IGateway(address(gateway)).quoteSendTokenFee( + address(token), destPara, maxDestinationFee + 1 + ); vm.expectRevert(Assets.InvalidDestinationFee.selector); IGateway(address(gateway)).sendToken{value: fee}( @@ -870,8 +1004,12 @@ contract GatewayTest is Test { } function testRegisterForeignToken() public { - RegisterForeignTokenParams memory params = - RegisterForeignTokenParams({foreignTokenID: dotTokenID, name: "DOT", symbol: "DOT", decimals: 10}); + RegisterForeignTokenParams memory params = RegisterForeignTokenParams({ + foreignTokenID: dotTokenID, + name: "DOT", + symbol: "DOT", + decimals: 10 + }); vm.expectEmit(true, true, false, false); emit IGateway.ForeignTokenRegistered(bytes32(uint256(1)), address(0)); @@ -882,8 +1020,12 @@ contract GatewayTest is Test { function testRegisterForeignTokenDuplicateFail() public { testRegisterForeignToken(); - RegisterForeignTokenParams memory params = - RegisterForeignTokenParams({foreignTokenID: dotTokenID, name: "DOT", symbol: "DOT", decimals: 10}); + RegisterForeignTokenParams memory params = RegisterForeignTokenParams({ + foreignTokenID: dotTokenID, + name: "DOT", + symbol: "DOT", + decimals: 10 + }); vm.expectRevert(Assets.TokenAlreadyRegistered.selector); @@ -895,8 +1037,11 @@ contract GatewayTest is Test { uint256 amount = 1000; - MintForeignTokenParams memory params = - MintForeignTokenParams({foreignTokenID: bytes32(uint256(1)), recipient: account1, amount: amount}); + MintForeignTokenParams memory params = MintForeignTokenParams({ + foreignTokenID: bytes32(uint256(1)), + recipient: account1, + amount: amount + }); vm.expectEmit(true, true, false, false); emit Transfer(address(0), account1, 1000); @@ -911,8 +1056,11 @@ contract GatewayTest is Test { } function testMintNotRegisteredTokenWillFail() public { - MintForeignTokenParams memory params = - MintForeignTokenParams({foreignTokenID: bytes32(uint256(1)), recipient: account1, amount: 1000}); + MintForeignTokenParams memory params = MintForeignTokenParams({ + foreignTokenID: bytes32(uint256(1)), + recipient: account1, + amount: 1000 + }); vm.expectRevert(Assets.TokenNotRegistered.selector); @@ -936,7 +1084,9 @@ contract GatewayTest is Test { vm.expectEmit(true, false, false, false); emit IGateway.OutboundMessageAccepted(assetHubParaID.into(), 1, messageID, bytes("")); - IGateway(address(gateway)).sendToken{value: 0.1 ether}(address(dotToken), destPara, recipientAddress32, 1, 1); + IGateway(address(gateway)).sendToken{value: 0.1 ether}( + address(dotToken), destPara, recipientAddress32, 1, 1 + ); } function testSendRelayTokenToAssetHubWithAddress20() public { @@ -950,7 +1100,9 @@ contract GatewayTest is Test { vm.prank(account1); vm.expectRevert(Assets.Unsupported.selector); - IGateway(address(gateway)).sendToken{value: 0.1 ether}(address(dotToken), destPara, recipientAddress20, 1, 1); + IGateway(address(gateway)).sendToken{value: 0.1 ether}( + address(dotToken), destPara, recipientAddress20, 1, 1 + ); } function testSendRelayTokenToDestinationChainWithAddress32() public { @@ -964,7 +1116,9 @@ contract GatewayTest is Test { vm.prank(account1); vm.expectRevert(Assets.Unsupported.selector); - IGateway(address(gateway)).sendToken{value: 0.1 ether}(address(dotToken), destPara, recipientAddress32, 1, 1); + IGateway(address(gateway)).sendToken{value: 0.1 ether}( + address(dotToken), destPara, recipientAddress32, 1, 1 + ); } function testSendRelayTokenToDestinationChainWithAddress20() public { @@ -978,7 +1132,9 @@ contract GatewayTest is Test { vm.prank(account1); vm.expectRevert(Assets.Unsupported.selector); - IGateway(address(gateway)).sendToken{value: 0.1 ether}(address(dotToken), destPara, recipientAddress20, 1, 1); + IGateway(address(gateway)).sendToken{value: 0.1 ether}( + address(dotToken), destPara, recipientAddress20, 1, 1 + ); } function testSendNotRegisteredTokenWillFail() public { @@ -986,7 +1142,9 @@ contract GatewayTest is Test { vm.expectRevert(Assets.TokenNotRegistered.selector); - IGateway(address(gateway)).sendToken{value: 0.1 ether}(address(0x0), destPara, recipientAddress32, 1, 1); + IGateway(address(gateway)).sendToken{value: 0.1 ether}( + address(0x0), destPara, recipientAddress32, 1, 1 + ); } function testSendTokenFromNotMintedAccountWillFail() public { @@ -998,9 +1156,13 @@ contract GatewayTest is Test { vm.prank(account1); - vm.expectRevert(abi.encodeWithSelector(IERC20.InsufficientBalance.selector, account1, 0, 1)); + vm.expectRevert( + abi.encodeWithSelector(IERC20.InsufficientBalance.selector, account1, 0, 1) + ); - IGateway(address(gateway)).sendToken{value: 0.1 ether}(address(dotToken), destPara, recipientAddress32, 1, 1); + IGateway(address(gateway)).sendToken{value: 0.1 ether}( + address(dotToken), destPara, recipientAddress32, 1, 1 + ); } function testLegacyAgentExecutionForCompatibility() public { @@ -1008,7 +1170,9 @@ contract GatewayTest is Test { AgentExecuteParams memory params = AgentExecuteParams({ agentID: assetHubAgentID, - payload: abi.encode(AgentExecuteCommand.TransferToken, abi.encode(address(token), address(account2), 10)) + payload: abi.encode( + AgentExecuteCommand.TransferToken, abi.encode(address(token), address(account2), 10) + ) }); bytes memory encodedParams = abi.encode(params); diff --git a/contracts/test/MMRProof.t.sol b/contracts/test/MMRProof.t.sol index 61492b3b84..f8fe51b241 100644 --- a/contracts/test/MMRProof.t.sol +++ b/contracts/test/MMRProof.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {Test} from "forge-std/Test.sol"; import {console} from "forge-std/console.sol"; @@ -43,7 +43,11 @@ contract MMRProofTest is Test { Fixture memory fix = fixture(); for (uint256 i = 0; i < fix.leaves.length; i++) { - assertTrue(wrapper.verifyLeafProof(fix.rootHash, fix.leaves[i], fix.proofs[i].items, fix.proofs[i].order)); + assertTrue( + wrapper.verifyLeafProof( + fix.rootHash, fix.leaves[i], fix.proofs[i].items, fix.proofs[i].order + ) + ); } } @@ -51,6 +55,8 @@ contract MMRProofTest is Test { Fixture memory fix = fixture(); vm.expectRevert(MMRProof.ProofSizeExceeded.selector); - wrapper.verifyLeafProof(fix.rootHash, fix.leaves[0], new bytes32[](257), fix.proofs[0].order); + wrapper.verifyLeafProof( + fix.rootHash, fix.leaves[0], new bytes32[](257), fix.proofs[0].order + ); } } diff --git a/contracts/test/Math.t.sol b/contracts/test/Math.t.sol index 4506998a02..d5a830de4e 100644 --- a/contracts/test/Math.t.sol +++ b/contracts/test/Math.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import "forge-std/Test.sol"; import "forge-std/console.sol"; @@ -56,14 +56,14 @@ contract MathTest is Test { Log2Test(13, 6144), Log2Test(13, 8192), Log2Test(14, 8193), - Log2Test(14, 12288), - Log2Test(14, 16384), - Log2Test(15, 16385), - Log2Test(15, 24576), - Log2Test(15, 32768), - Log2Test(16, 32769), - Log2Test(16, 49152), - Log2Test(16, 65535) + Log2Test(14, 12_288), + Log2Test(14, 16_384), + Log2Test(15, 16_385), + Log2Test(15, 24_576), + Log2Test(15, 32_768), + Log2Test(16, 32_769), + Log2Test(16, 49_152), + Log2Test(16, 65_535) ]; for (uint256 t = 0; t < tests.length; ++t) { diff --git a/contracts/test/ScaleCodec.t.sol b/contracts/test/ScaleCodec.t.sol index ebe1a94856..27c2026699 100644 --- a/contracts/test/ScaleCodec.t.sol +++ b/contracts/test/ScaleCodec.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import "forge-std/Test.sol"; import "forge-std/console.sol"; @@ -9,21 +9,26 @@ import {ScaleCodec} from "../src/utils/ScaleCodec.sol"; contract ScaleCodecTest is Test { function testEncodeU256() public { assertEq( - ScaleCodec.encodeU256(12063978950259949786323707366460749298097791896371638493358994162204017315152), + ScaleCodec.encodeU256( + 12_063_978_950_259_949_786_323_707_366_460_749_298_097_791_896_371_638_493_358_994_162_204_017_315_152 + ), hex"504d8a21dd3868465c8c9f2898b7f014036935fa9a1488629b109d3d59f8ab1a" ); } function testEncodeU128() public { - assertEq(ScaleCodec.encodeU128(35452847761173902980759433963665451267), hex"036935fa9a1488629b109d3d59f8ab1a"); + assertEq( + ScaleCodec.encodeU128(35_452_847_761_173_902_980_759_433_963_665_451_267), + hex"036935fa9a1488629b109d3d59f8ab1a" + ); } function testEncodeU64() public { - assertEq(ScaleCodec.encodeU64(1921902728173129883), hex"9b109d3d59f8ab1a"); + assertEq(ScaleCodec.encodeU64(1_921_902_728_173_129_883), hex"9b109d3d59f8ab1a"); } function testEncodeU32() public { - assertEq(ScaleCodec.encodeU32(447477849), hex"59f8ab1a"); + assertEq(ScaleCodec.encodeU32(447_477_849), hex"59f8ab1a"); } function testEncodeU16() public { @@ -34,10 +39,10 @@ contract ScaleCodecTest is Test { assertEq(ScaleCodec.encodeCompactU32(0), hex"00"); assertEq(ScaleCodec.encodeCompactU32(63), hex"fc"); assertEq(ScaleCodec.encodeCompactU32(64), hex"0101"); - assertEq(ScaleCodec.encodeCompactU32(16383), hex"fdff"); - assertEq(ScaleCodec.encodeCompactU32(16384), hex"02000100"); - assertEq(ScaleCodec.encodeCompactU32(1073741823), hex"feffffff"); - assertEq(ScaleCodec.encodeCompactU32(1073741824), hex"0300000040"); + assertEq(ScaleCodec.encodeCompactU32(16_383), hex"fdff"); + assertEq(ScaleCodec.encodeCompactU32(16_384), hex"02000100"); + assertEq(ScaleCodec.encodeCompactU32(1_073_741_823), hex"feffffff"); + assertEq(ScaleCodec.encodeCompactU32(1_073_741_824), hex"0300000040"); assertEq(ScaleCodec.encodeCompactU32(type(uint32).max), hex"03ffffffff"); } diff --git a/contracts/test/Shell.t.sol b/contracts/test/Shell.t.sol index e8cdac3e3a..a7173bf234 100644 --- a/contracts/test/Shell.t.sol +++ b/contracts/test/Shell.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {Test} from "forge-std/Test.sol"; import {Strings} from "openzeppelin/utils/Strings.sol"; diff --git a/contracts/test/Uint16Array.t.sol b/contracts/test/Uint16Array.t.sol index 013ec08f83..8804014ec0 100644 --- a/contracts/test/Uint16Array.t.sol +++ b/contracts/test/Uint16Array.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import "forge-std/Test.sol"; import "forge-std/console.sol"; diff --git a/contracts/test/Verification.t.sol b/contracts/test/Verification.t.sol index 52263bcd8a..747319bdad 100644 --- a/contracts/test/Verification.t.sol +++ b/contracts/test/Verification.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import "openzeppelin/utils/Strings.sol"; import "forge-std/Test.sol"; @@ -24,7 +24,11 @@ contract VerificationTest is Test { function testCreateParachainHeaderMerkleLeaf() public { Verification.DigestItem[] memory digestItems = new Verification.DigestItem[](3); - digestItems[0] = Verification.DigestItem({kind: 6, consensusEngineID: 0x61757261, data: hex"c1f05e0800000000"}); + digestItems[0] = Verification.DigestItem({ + kind: 6, + consensusEngineID: 0x61757261, + data: hex"c1f05e0800000000" + }); digestItems[1] = Verification.DigestItem({ kind: 4, consensusEngineID: 0x52505352, @@ -38,7 +42,7 @@ contract VerificationTest is Test { Verification.ParachainHeader memory header = Verification.ParachainHeader({ parentHash: 0x1df01d40273b074708115135fd7f76801ad4e4f1266a771a037962ee3a03259d, - number: 866538, + number: 866_538, stateRoot: 0x7b2d59d4de7c629b55a9bc9b76d932616f2011a26f09b52da36e070d6a7eee0d, extrinsicsRoot: 0x9d1c5d256003f68dda03dc33810a88a61f73791dc7ff92b04232a6b1b4f4b3c0, digestItems: digestItems @@ -62,12 +66,15 @@ contract VerificationTest is Test { function testCreateParachainHeaderMerkleFailInvalidHeader() public { Verification.DigestItem[] memory digestItems = new Verification.DigestItem[](1); // Create an invalid digest item - digestItems[0] = - Verification.DigestItem({kind: 666, consensusEngineID: 0x61757261, data: hex"c1f05e0800000000"}); + digestItems[0] = Verification.DigestItem({ + kind: 666, + consensusEngineID: 0x61757261, + data: hex"c1f05e0800000000" + }); Verification.ParachainHeader memory header = Verification.ParachainHeader({ parentHash: 0x1df01d40273b074708115135fd7f76801ad4e4f1266a771a037962ee3a03259d, - number: 866538, + number: 866_538, stateRoot: 0x7b2d59d4de7c629b55a9bc9b76d932616f2011a26f09b52da36e070d6a7eee0d, extrinsicsRoot: 0x9d1c5d256003f68dda03dc33810a88a61f73791dc7ff92b04232a6b1b4f4b3c0, digestItems: digestItems @@ -79,7 +86,11 @@ contract VerificationTest is Test { function testIsCommitmentInHeaderDigest() public view { Verification.DigestItem[] memory digestItems = new Verification.DigestItem[](4); - digestItems[0] = Verification.DigestItem({kind: 6, consensusEngineID: 0x61757261, data: hex"c1f05e0800000000"}); + digestItems[0] = Verification.DigestItem({ + kind: 6, + consensusEngineID: 0x61757261, + data: hex"c1f05e0800000000" + }); digestItems[1] = Verification.DigestItem({ kind: 4, consensusEngineID: 0x52505352, @@ -98,19 +109,25 @@ contract VerificationTest is Test { Verification.ParachainHeader memory header = Verification.ParachainHeader({ parentHash: 0x1df01d40273b074708115135fd7f76801ad4e4f1266a771a037962ee3a03259d, - number: 866538, + number: 866_538, stateRoot: 0x7b2d59d4de7c629b55a9bc9b76d932616f2011a26f09b52da36e070d6a7eee0d, extrinsicsRoot: 0x9d1c5d256003f68dda03dc33810a88a61f73791dc7ff92b04232a6b1b4f4b3c0, digestItems: digestItems }); // Digest item at index 2 contains the commitment - assert(v.isCommitmentInHeaderDigest(0xb5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c, header)); + assert( + v.isCommitmentInHeaderDigest( + 0xb5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c, header + ) + ); // Now remove the commitment from the parachain header header.digestItems[2] = header.digestItems[3]; assert( - !v.isCommitmentInHeaderDigest(0xb5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c, header) + !v.isCommitmentInHeaderDigest( + 0xb5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c, header + ) ); } } diff --git a/contracts/test/mocks/BeefyClientMock.sol b/contracts/test/mocks/BeefyClientMock.sol index 40caee279b..149d15a83d 100644 --- a/contracts/test/mocks/BeefyClientMock.sol +++ b/contracts/test/mocks/BeefyClientMock.sol @@ -1,12 +1,16 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {BeefyClient} from "../../src/BeefyClient.sol"; import {Uint16Array, createUint16Array} from "../../src/utils/Uint16Array.sol"; import "forge-std/console.sol"; contract BeefyClientMock is BeefyClient { - constructor(uint256 randaoCommitDelay, uint256 randaoCommitExpiration, uint256 minNumRequiredSignatures) + constructor( + uint256 randaoCommitDelay, + uint256 randaoCommitExpiration, + uint256 minNumRequiredSignatures + ) BeefyClient( randaoCommitDelay, randaoCommitExpiration, @@ -17,7 +21,11 @@ contract BeefyClientMock is BeefyClient { ) {} - function encodeCommitment_public(Commitment calldata commitment) external pure returns (bytes memory) { + function encodeCommitment_public(Commitment calldata commitment) + external + pure + returns (bytes memory) + { return encodeCommitment(commitment); } @@ -60,7 +68,10 @@ contract BeefyClientMock is BeefyClient { // Perform the copy currentValidatorSet = nextValidatorSet; - assert(currentValidatorSet.usageCounters.data.length == nextValidatorSet.usageCounters.data.length); + assert( + currentValidatorSet.usageCounters.data.length + == nextValidatorSet.usageCounters.data.length + ); assert(currentValidatorSet.usageCounters.get(799) == 7); } diff --git a/contracts/test/mocks/BitfieldWrapper.sol b/contracts/test/mocks/BitfieldWrapper.sol index 3ae5e839e7..523b2edae2 100644 --- a/contracts/test/mocks/BitfieldWrapper.sol +++ b/contracts/test/mocks/BitfieldWrapper.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {Bitfield} from "../../src/utils/Bitfield.sol"; diff --git a/contracts/test/mocks/MMRProofWrapper.sol b/contracts/test/mocks/MMRProofWrapper.sol index 3584edc7f1..24e55c47bd 100644 --- a/contracts/test/mocks/MMRProofWrapper.sol +++ b/contracts/test/mocks/MMRProofWrapper.sol @@ -1,14 +1,15 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {MMRProof} from "../../src/utils/MMRProof.sol"; contract MMRProofWrapper { - function verifyLeafProof(bytes32 root, bytes32 leafHash, bytes32[] calldata proof, uint256 proofOrder) - external - pure - returns (bool) - { + function verifyLeafProof( + bytes32 root, + bytes32 leafHash, + bytes32[] calldata proof, + uint256 proofOrder + ) external pure returns (bool) { return MMRProof.verifyLeafProof(root, leafHash, proof, proofOrder); } } diff --git a/contracts/test/mocks/MockGateway.sol b/contracts/test/mocks/MockGateway.sol index 4356bb9876..f2ef4163ad 100644 --- a/contracts/test/mocks/MockGateway.sol +++ b/contracts/test/mocks/MockGateway.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {Gateway} from "../../src/Gateway.sol"; import {ParaID, OperatingMode} from "../../src/Types.sol"; @@ -20,7 +20,14 @@ contract MockGateway is Gateway { uint8 foreignTokenDecimals, uint128 maxDestinationFee ) - Gateway(beefyClient, agentExecutor, bridgeHubParaID, bridgeHubHubAgentID, foreignTokenDecimals, maxDestinationFee) + Gateway( + beefyClient, + agentExecutor, + bridgeHubParaID, + bridgeHubHubAgentID, + foreignTokenDecimals, + maxDestinationFee + ) {} function agentExecutePublic(bytes calldata params) external { diff --git a/contracts/test/mocks/MockGatewayV2.sol b/contracts/test/mocks/MockGatewayV2.sol index d994c909a5..2d5fbdb037 100644 --- a/contracts/test/mocks/MockGatewayV2.sol +++ b/contracts/test/mocks/MockGatewayV2.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {IInitializable} from "../../src/interfaces/IInitializable.sol"; diff --git a/contracts/test/mocks/VerificationWrapper.sol b/contracts/test/mocks/VerificationWrapper.sol index 7618bb78c8..8cd817b4b2 100644 --- a/contracts/test/mocks/VerificationWrapper.sol +++ b/contracts/test/mocks/VerificationWrapper.sol @@ -1,22 +1,20 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {Verification} from "../../src/Verification.sol"; contract VerificationWrapper { - function createParachainHeaderMerkleLeaf(bytes4 encodedParachainID, Verification.ParachainHeader calldata header) - external - pure - returns (bytes32) - { + function createParachainHeaderMerkleLeaf( + bytes4 encodedParachainID, + Verification.ParachainHeader calldata header + ) external pure returns (bytes32) { return Verification.createParachainHeaderMerkleLeaf(encodedParachainID, header); } - function isCommitmentInHeaderDigest(bytes32 commitment, Verification.ParachainHeader calldata header) - external - pure - returns (bool) - { + function isCommitmentInHeaderDigest( + bytes32 commitment, + Verification.ParachainHeader calldata header + ) external pure returns (bool) { return Verification.isCommitmentInHeaderDigest(commitment, header); } } From 1f10c83049357985cbb38227670803e750806f42 Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Tue, 24 Dec 2024 21:49:29 +0200 Subject: [PATCH 02/11] undo format --- contracts/foundry.toml | 4 - contracts/scripts/DeployLocal.sol | 5 +- contracts/scripts/UpgradeShell.sol | 6 +- contracts/scripts/westend/UpgradeShell.sol | 6 +- contracts/src/Assets.sol | 51 ++-- contracts/src/BeefyClient.sol | 80 ++---- contracts/src/MultiAddress.sol | 9 +- contracts/src/Shell.sol | 4 +- contracts/src/SubstrateTypes.sol | 22 +- contracts/src/Token.sol | 17 +- contracts/src/TokenLib.sol | 39 +-- contracts/src/Types.sol | 5 +- contracts/src/Upgrade.sol | 4 +- contracts/src/Verification.sol | 36 +-- contracts/src/interfaces/IERC20.sol | 4 +- contracts/src/interfaces/IERC20Permit.sol | 11 +- contracts/src/interfaces/IGateway.sol | 8 +- contracts/src/interfaces/IShell.sol | 3 +- contracts/src/utils/Bitfield.sol | 30 +- contracts/src/utils/Bits.sol | 6 +- contracts/src/utils/Call.sol | 6 +- contracts/src/utils/ERC1967.sol | 3 +- contracts/src/utils/MMRProof.sol | 17 +- contracts/src/utils/SafeTransfer.sol | 3 +- contracts/src/utils/ScaleCodec.sol | 9 +- contracts/src/utils/SubstrateMerkleProof.sol | 12 +- contracts/test/Agent.t.sol | 6 +- contracts/test/BeefyClient.t.sol | 187 +++---------- contracts/test/Bitfield.t.sol | 3 +- contracts/test/ForkUpgrade.t.sol | 61 +--- contracts/test/Gateway.t.sol | 280 ++++--------------- contracts/test/MMRProof.t.sol | 10 +- contracts/test/Verification.t.sol | 29 +- contracts/test/mocks/BeefyClientMock.sol | 17 +- contracts/test/mocks/MMRProofWrapper.sol | 11 +- contracts/test/mocks/MockGateway.sol | 9 +- contracts/test/mocks/VerificationWrapper.sol | 18 +- 37 files changed, 261 insertions(+), 770 deletions(-) diff --git a/contracts/foundry.toml b/contracts/foundry.toml index fda03816ca..0f8b081f56 100644 --- a/contracts/foundry.toml +++ b/contracts/foundry.toml @@ -24,7 +24,3 @@ via_ir = true [profile.production.etherscan] mainnet = { key = "${ETHERSCAN_API_KEY}" } - -[fmt] -number_underscore = "thousands" -line_length = 99 diff --git a/contracts/scripts/DeployLocal.sol b/contracts/scripts/DeployLocal.sol index 711c513f85..4fd6be19ee 100644 --- a/contracts/scripts/DeployLocal.sol +++ b/contracts/scripts/DeployLocal.sol @@ -49,9 +49,8 @@ contract DeployLocal is Script { uint256 randaoCommitDelay = vm.envUint("RANDAO_COMMIT_DELAY"); uint256 randaoCommitExpiration = vm.envUint("RANDAO_COMMIT_EXP"); uint256 minimumSignatures = vm.envUint("MINIMUM_REQUIRED_SIGNATURES"); - BeefyClient beefyClient = new BeefyClient( - randaoCommitDelay, randaoCommitExpiration, minimumSignatures, startBlock, current, next - ); + BeefyClient beefyClient = + new BeefyClient(randaoCommitDelay, randaoCommitExpiration, minimumSignatures, startBlock, current, next); ParaID bridgeHubParaID = ParaID.wrap(uint32(vm.envUint("BRIDGE_HUB_PARAID"))); bytes32 bridgeHubAgentID = vm.envBytes32("BRIDGE_HUB_AGENT_ID"); diff --git a/contracts/scripts/UpgradeShell.sol b/contracts/scripts/UpgradeShell.sol index cac0499753..22d961cfe8 100644 --- a/contracts/scripts/UpgradeShell.sol +++ b/contracts/scripts/UpgradeShell.sol @@ -84,11 +84,7 @@ contract UpgradeShell is Script { IShell shell = IShell(config.gatewayProxy); - shell.upgrade( - address(gatewayLogic), - address(gatewayLogic).codehash, - abi.encode(config.initializerParams) - ); + shell.upgrade(address(gatewayLogic), address(gatewayLogic).codehash, abi.encode(config.initializerParams)); vm.stopBroadcast(); } diff --git a/contracts/scripts/westend/UpgradeShell.sol b/contracts/scripts/westend/UpgradeShell.sol index 80b7a59638..6a668d4e4a 100644 --- a/contracts/scripts/westend/UpgradeShell.sol +++ b/contracts/scripts/westend/UpgradeShell.sol @@ -75,11 +75,7 @@ contract UpgradeShell is Script { IShell shell = IShell(config.gatewayProxy); - shell.upgrade( - address(gatewayLogic), - address(gatewayLogic).codehash, - abi.encode(config.initializerParams) - ); + shell.upgrade(address(gatewayLogic), address(gatewayLogic).codehash, abi.encode(config.initializerParams)); vm.stopBroadcast(); } diff --git a/contracts/src/Assets.sol b/contracts/src/Assets.sol index 4f8b9fdc30..55a44bef39 100644 --- a/contracts/src/Assets.sol +++ b/contracts/src/Assets.sol @@ -40,9 +40,7 @@ library Assets { } /// @dev transfer tokens from the sender to the specified agent - function _transferToAgent(address agent, address token, address sender, uint128 amount) - internal - { + function _transferToAgent(address agent, address token, address sender, uint128 amount) internal { if (!token.isContract()) { revert InvalidToken(); } @@ -69,11 +67,11 @@ library Assets { return _sendTokenCosts(destinationChain, destinationChainFee, maxDestinationChainFee); } - function _sendTokenCosts( - ParaID destinationChain, - uint128 destinationChainFee, - uint128 maxDestinationChainFee - ) internal view returns (Costs memory costs) { + function _sendTokenCosts(ParaID destinationChain, uint128 destinationChainFee, uint128 maxDestinationChainFee) + internal + view + returns (Costs memory costs) + { AssetsStorage.Layout storage $ = AssetsStorage.layout(); if ($.assetHubParaID == destinationChain) { costs.foreign = $.assetHubReserveTransferFee; @@ -118,13 +116,7 @@ library Assets { if (info.foreignID == bytes32(0)) { return _sendNativeToken( - token, - sender, - destinationChain, - destinationAddress, - destinationChainFee, - maxDestinationChainFee, - amount + token, sender, destinationChain, destinationAddress, destinationChainFee, maxDestinationChainFee, amount ); } else { return _sendForeignToken( @@ -155,8 +147,7 @@ library Assets { _transferToAgent($.assetHubAgent, token, sender, amount); ticket.dest = $.assetHubParaID; - ticket.costs = - _sendTokenCosts(destinationChain, destinationChainFee, maxDestinationChainFee); + ticket.costs = _sendTokenCosts(destinationChain, destinationChainFee, maxDestinationChainFee); // Construct a message payload if (destinationChain == $.assetHubParaID) { @@ -219,8 +210,7 @@ library Assets { Token(token).burn(sender, amount); ticket.dest = $.assetHubParaID; - ticket.costs = - _sendTokenCosts(destinationChain, destinationChainFee, maxDestinationChainFee); + ticket.costs = _sendTokenCosts(destinationChain, destinationChainFee, maxDestinationChainFee); // Construct a message payload if (destinationChain == $.assetHubParaID && destinationAddress.isAddress32()) { @@ -277,12 +267,9 @@ library Assets { } // @dev Register a new fungible Polkadot token for an agent - function registerForeignToken( - bytes32 foreignTokenID, - string memory name, - string memory symbol, - uint8 decimals - ) external { + function registerForeignToken(bytes32 foreignTokenID, string memory name, string memory symbol, uint8 decimals) + external + { AssetsStorage.Layout storage $ = AssetsStorage.layout(); if ($.tokenAddressOf[foreignTokenID] != address(0)) { revert TokenAlreadyRegistered(); @@ -297,21 +284,15 @@ library Assets { } // @dev Mint foreign token from Polkadot - function mintForeignToken(bytes32 foreignTokenID, address recipient, uint256 amount) - external - { + function mintForeignToken(bytes32 foreignTokenID, address recipient, uint256 amount) external { address token = _ensureTokenAddressOf(foreignTokenID); Token(token).mint(recipient, amount); } // @dev Transfer ERC20 to `recipient` - function transferNativeToken( - address executor, - address agent, - address token, - address recipient, - uint128 amount - ) external { + function transferNativeToken(address executor, address agent, address token, address recipient, uint128 amount) + external + { bytes memory call = abi.encodeCall(AgentExecutor.transferToken, (token, recipient, amount)); (bool success,) = Agent(payable(agent)).invoke(executor, call); if (!success) { diff --git a/contracts/src/BeefyClient.sol b/contracts/src/BeefyClient.sol index eed2cb166c..a8632b26a1 100644 --- a/contracts/src/BeefyClient.sol +++ b/contracts/src/BeefyClient.sol @@ -247,11 +247,9 @@ contract BeefyClient { * @param bitfield a bitfield claiming which validators have signed the commitment * @param proof a proof that a single validator from currentValidatorSet has signed the commitment */ - function submitInitial( - Commitment calldata commitment, - uint256[] calldata bitfield, - ValidatorProof calldata proof - ) external { + function submitInitial(Commitment calldata commitment, uint256[] calldata bitfield, ValidatorProof calldata proof) + external + { if (commitment.blockNumber <= latestBeefyBlock) { revert StaleCommitment(); } @@ -260,9 +258,7 @@ contract BeefyClient { uint16 signatureUsageCount; if (commitment.validatorSetID == currentValidatorSet.id) { signatureUsageCount = currentValidatorSet.usageCounters.get(proof.index); - currentValidatorSet.usageCounters.set( - proof.index, signatureUsageCount.saturatingAdd(1) - ); + currentValidatorSet.usageCounters.set(proof.index, signatureUsageCount.saturatingAdd(1)); vset = currentValidatorSet; } else if (commitment.validatorSetID == nextValidatorSet.id) { signatureUsageCount = nextValidatorSet.usageCounters.get(proof.index); @@ -273,10 +269,8 @@ contract BeefyClient { } // Check if merkle proof is valid based on the validatorSetRoot and if proof is included in bitfield - if ( - !isValidatorInSet(vset, proof.account, proof.index, proof.proof) - || !Bitfield.isSet(bitfield, proof.index) - ) { + if (!isValidatorInSet(vset, proof.account, proof.index, proof.proof) || !Bitfield.isSet(bitfield, proof.index)) + { revert InvalidValidatorProof(); } @@ -297,9 +291,7 @@ contract BeefyClient { blockNumber: uint64(block.number), validatorSetLen: uint32(vset.length), numRequiredSignatures: uint32( - computeNumRequiredSignatures( - vset.length, signatureUsageCount, minNumRequiredSignatures - ) + computeNumRequiredSignatures(vset.length, signatureUsageCount, minNumRequiredSignatures) ), prevRandao: 0, bitfieldHash: keccak256(abi.encodePacked(bitfield)) @@ -379,9 +371,8 @@ contract BeefyClient { if (leaf.nextAuthoritySetID != nextValidatorSet.id + 1) { revert InvalidMMRLeaf(); } - bool leafIsValid = MMRProof.verifyLeafProof( - newMMRRoot, keccak256(encodeMMRLeaf(leaf)), leafProof, leafProofOrder - ); + bool leafIsValid = + MMRProof.verifyLeafProof(newMMRRoot, keccak256(encodeMMRLeaf(leaf)), leafProof, leafProofOrder); if (!leafIsValid) { revert InvalidMMRLeafProof(); } @@ -443,19 +434,13 @@ contract BeefyClient { if (ticket.bitfieldHash != keccak256(abi.encodePacked(bitfield))) { revert InvalidBitfield(); } - return Bitfield.subsample( - ticket.prevRandao, bitfield, ticket.numRequiredSignatures, ticket.validatorSetLen - ); + return Bitfield.subsample(ticket.prevRandao, bitfield, ticket.numRequiredSignatures, ticket.validatorSetLen); } /* Internal Functions */ // Creates a unique ticket ID for a new interactive prover-verifier session - function createTicketID(address account, bytes32 commitmentHash) - internal - pure - returns (bytes32 value) - { + function createTicketID(address account, bytes32 commitmentHash) internal pure returns (bytes32 value) { assembly { mstore(0x00, account) mstore(0x20, commitmentHash) @@ -540,11 +525,7 @@ contract BeefyClient { } // Ensure that the commitment provides a new MMR root - function ensureProvidesMMRRoot(Commitment calldata commitment) - internal - pure - returns (bytes32) - { + function ensureProvidesMMRRoot(Commitment calldata commitment) internal pure returns (bytes32) { for (uint256 i = 0; i < commitment.payload.length; i++) { if (commitment.payload[i].payloadID == MMR_ROOT_ID) { if (commitment.payload[i].data.length != 32) { @@ -557,11 +538,7 @@ contract BeefyClient { revert CommitmentNotRelevant(); } - function encodeCommitment(Commitment calldata commitment) - internal - pure - returns (bytes memory) - { + function encodeCommitment(Commitment calldata commitment) internal pure returns (bytes memory) { return bytes.concat( encodeCommitmentPayload(commitment.payload), ScaleCodec.encodeU32(commitment.blockNumber), @@ -569,18 +546,11 @@ contract BeefyClient { ); } - function encodeCommitmentPayload(PayloadItem[] calldata items) - internal - pure - returns (bytes memory) - { + function encodeCommitmentPayload(PayloadItem[] calldata items) internal pure returns (bytes memory) { bytes memory payload = ScaleCodec.checkedEncodeCompactU32(items.length); for (uint256 i = 0; i < items.length; i++) { payload = bytes.concat( - payload, - items[i].payloadID, - ScaleCodec.checkedEncodeCompactU32(items[i].data.length), - items[i].data + payload, items[i].payloadID, ScaleCodec.checkedEncodeCompactU32(items[i].data.length), items[i].data ); } @@ -607,12 +577,11 @@ contract BeefyClient { * @param proof Merkle proof required for validation of the address * @return true if the validator is in the set */ - function isValidatorInSet( - ValidatorSetState storage vset, - address account, - uint256 index, - bytes32[] calldata proof - ) internal view returns (bool) { + function isValidatorInSet(ValidatorSetState storage vset, address account, uint256 index, bytes32[] calldata proof) + internal + view + returns (bool) + { bytes32 hashedLeaf = keccak256(abi.encodePacked(account)); return SubstrateMerkleProof.verify(vset.root, hashedLeaf, index, vset.length, proof); } @@ -620,11 +589,10 @@ contract BeefyClient { /** * @dev Basic validation of a ticket for submitFinal */ - function validateTicket( - bytes32 ticketID, - Commitment calldata commitment, - uint256[] calldata bitfield - ) internal view { + function validateTicket(bytes32 ticketID, Commitment calldata commitment, uint256[] calldata bitfield) + internal + view + { Ticket storage ticket = tickets[ticketID]; if (ticket.blockNumber == 0) { diff --git a/contracts/src/MultiAddress.sol b/contracts/src/MultiAddress.sol index 97c3fd9c8b..83b4c45ab7 100644 --- a/contracts/src/MultiAddress.sol +++ b/contracts/src/MultiAddress.sol @@ -2,14 +2,7 @@ // SPDX-FileCopyrightText: 2023 Snowfork pragma solidity 0.8.28; -using { - isIndex, - asIndex, - isAddress32, - asAddress32, - isAddress20, - asAddress20 -} for MultiAddress global; +using {isIndex, asIndex, isAddress32, asAddress32, isAddress20, asAddress20} for MultiAddress global; /// @dev An address for an on-chain account struct MultiAddress { diff --git a/contracts/src/Shell.sol b/contracts/src/Shell.sol index 0b614b5c40..21d108fed6 100644 --- a/contracts/src/Shell.sol +++ b/contracts/src/Shell.sol @@ -22,9 +22,7 @@ contract Shell is IShell, IUpgradable, IInitializable { OPERATOR = _operator; } - function upgrade(address impl, bytes32 implCodeHash, bytes calldata initializerParams) - external - { + function upgrade(address impl, bytes32 implCodeHash, bytes calldata initializerParams) external { if (msg.sender != OPERATOR) { revert Unauthorized(); } diff --git a/contracts/src/SubstrateTypes.sol b/contracts/src/SubstrateTypes.sol index 9cf576d360..37033a94af 100644 --- a/contracts/src/SubstrateTypes.sol +++ b/contracts/src/SubstrateTypes.sol @@ -71,12 +71,11 @@ library SubstrateTypes { * `NativeTokensMessage::Mint` */ // destination is AccountID32 address on AssetHub - function SendTokenToAssetHubAddress32( - address token, - bytes32 recipient, - uint128 xcmFee, - uint128 amount - ) internal view returns (bytes memory) { + function SendTokenToAssetHubAddress32(address token, bytes32 recipient, uint128 xcmFee, uint128 amount) + internal + view + returns (bytes memory) + { return bytes.concat( bytes1(0x00), ScaleCodec.encodeU64(uint64(block.chainid)), @@ -135,12 +134,11 @@ library SubstrateTypes { ); } - function SendForeignTokenToAssetHubAddress32( - bytes32 tokenID, - bytes32 recipient, - uint128 xcmFee, - uint128 amount - ) internal view returns (bytes memory) { + function SendForeignTokenToAssetHubAddress32(bytes32 tokenID, bytes32 recipient, uint128 xcmFee, uint128 amount) + internal + view + returns (bytes memory) + { return bytes.concat( bytes1(0x00), ScaleCodec.encodeU64(uint64(block.chainid)), diff --git a/contracts/src/Token.sol b/contracts/src/Token.sol index c73e1c4329..5fd5d22003 100644 --- a/contracts/src/Token.sol +++ b/contracts/src/Token.sol @@ -132,10 +132,7 @@ contract Token is IERC20, IERC20Permit { * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ - function transferFrom(address sender, address recipient, uint256 amount) - external - returns (bool) - { + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) { return token.transferFrom(sender, recipient, amount); } @@ -173,15 +170,9 @@ contract Token is IERC20, IERC20Permit { return token.decreaseAllowance(spender, subtractedValue); } - function permit( - address issuer, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) external { + function permit(address issuer, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) + external + { token.permit(DOMAIN_SEPARATOR, issuer, spender, value, deadline, v, r, s); } diff --git a/contracts/src/TokenLib.sol b/contracts/src/TokenLib.sol index db0f4d85ce..060993a895 100644 --- a/contracts/src/TokenLib.sol +++ b/contracts/src/TokenLib.sol @@ -33,10 +33,7 @@ library TokenLib { * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ - function transfer(Token storage token, address sender, address recipient, uint256 amount) - external - returns (bool) - { + function transfer(Token storage token, address sender, address recipient, uint256 amount) external returns (bool) { _transfer(token, sender, recipient, amount); return true; } @@ -93,10 +90,7 @@ library TokenLib { * * - `spender` cannot be the zero address. */ - function approve(Token storage token, address owner, address spender, uint256 amount) - external - returns (bool) - { + function approve(Token storage token, address owner, address spender, uint256 amount) external returns (bool) { _approve(token, owner, spender, amount); return true; } @@ -146,10 +140,7 @@ library TokenLib { * * - `spender` cannot be the zero address. */ - function increaseAllowance(Token storage token, address spender, uint256 addedValue) - external - returns (bool) - { + function increaseAllowance(Token storage token, address spender, uint256 addedValue) external returns (bool) { uint256 _allowance = token.allowance[msg.sender][spender]; if (_allowance != type(uint256).max) { _approve(token, msg.sender, spender, _allowance + addedValue); @@ -171,10 +162,7 @@ library TokenLib { * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ - function decreaseAllowance(Token storage token, address spender, uint256 subtractedValue) - external - returns (bool) - { + function decreaseAllowance(Token storage token, address spender, uint256 subtractedValue) external returns (bool) { uint256 _allowance = token.allowance[msg.sender][spender]; if (_allowance != type(uint256).max) { if (_allowance < subtractedValue) { @@ -210,16 +198,7 @@ library TokenLib { abi.encodePacked( EIP191_PREFIX_FOR_EIP712_STRUCTURED_DATA, domainSeparator, - keccak256( - abi.encode( - PERMIT_SIGNATURE_HASH, - issuer, - spender, - value, - token.nonces[issuer]++, - deadline - ) - ) + keccak256(abi.encode(PERMIT_SIGNATURE_HASH, issuer, spender, value, token.nonces[issuer]++, deadline)) ) ); @@ -245,9 +224,7 @@ library TokenLib { * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ - function _transfer(Token storage token, address sender, address recipient, uint256 amount) - internal - { + function _transfer(Token storage token, address sender, address recipient, uint256 amount) internal { if (sender == address(0) || recipient == address(0)) { revert IERC20.InvalidAccount(); } @@ -268,9 +245,7 @@ library TokenLib { * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ - function _approve(Token storage token, address owner, address spender, uint256 amount) - internal - { + function _approve(Token storage token, address owner, address spender, uint256 amount) internal { if (owner == address(0) || spender == address(0)) { revert IERC20.InvalidAccount(); } diff --git a/contracts/src/Types.sol b/contracts/src/Types.sol index 665b2b7ed9..6d7ab930a6 100644 --- a/contracts/src/Types.sol +++ b/contracts/src/Types.sol @@ -3,10 +3,7 @@ pragma solidity 0.8.28; import { - MultiAddress, - multiAddressFromUint32, - multiAddressFromBytes32, - multiAddressFromBytes20 + MultiAddress, multiAddressFromUint32, multiAddressFromBytes32, multiAddressFromBytes20 } from "./MultiAddress.sol"; import {UD60x18} from "prb/math/src/UD60x18.sol"; diff --git a/contracts/src/Upgrade.sol b/contracts/src/Upgrade.sol index 8753e02c6b..8be1ebeb79 100644 --- a/contracts/src/Upgrade.sol +++ b/contracts/src/Upgrade.sol @@ -12,9 +12,7 @@ import {IUpgradable} from "./interfaces/IUpgradable.sol"; library Upgrade { using Address for address; - function upgrade(address impl, bytes32 implCodeHash, bytes memory initializerParams) - internal - { + function upgrade(address impl, bytes32 implCodeHash, bytes memory initializerParams) internal { // Verify that the implementation is actually a contract if (!impl.isContract()) { revert IUpgradable.InvalidContract(); diff --git a/contracts/src/Verification.sol b/contracts/src/Verification.sol index d2dbb17e3b..6ee500eba8 100644 --- a/contracts/src/Verification.sol +++ b/contracts/src/Verification.sol @@ -100,12 +100,11 @@ library Verification { /// @param commitment The message commitment root expected to be contained within the /// digest of BridgeHub parachain header. /// @param proof The chain of proofs described above - function verifyCommitment( - address beefyClient, - bytes4 encodedParaID, - bytes32 commitment, - Proof calldata proof - ) external view returns (bool) { + function verifyCommitment(address beefyClient, bytes4 encodedParaID, bytes32 commitment, Proof calldata proof) + external + view + returns (bool) + { // Verify that parachain header contains the commitment if (!isCommitmentInHeaderDigest(commitment, proof.header)) { return false; @@ -126,9 +125,7 @@ library Verification { bytes32 leafHash = createMMRLeaf(proof.leafPartial, parachainHeadsRoot); // Verify that the MMR leaf is part of the MMR maintained by the BEEFY light client - return BeefyClient(beefyClient).verifyMMRLeafProof( - leafHash, proof.leafProof, proof.leafProofOrder - ); + return BeefyClient(beefyClient).verifyMMRLeafProof(leafHash, proof.leafProof, proof.leafProofOrder); } // Verify that a message commitment is in the header digest @@ -139,8 +136,7 @@ library Verification { { for (uint256 i = 0; i < header.digestItems.length; i++) { if ( - header.digestItems[i].kind == DIGEST_ITEM_OTHER - && header.digestItems[i].data.length == 33 + header.digestItems[i].kind == DIGEST_ITEM_OTHER && header.digestItems[i].data.length == 33 && header.digestItems[i].data[0] == DIGEST_ITEM_OTHER_SNOWBRIDGE && commitment == bytes32(header.digestItems[i].data[1:]) ) { @@ -152,11 +148,7 @@ library Verification { // SCALE-Encodes: Vec // Reference: https://github.com/paritytech/substrate/blob/14e0a0b628f9154c5a2c870062c3aac7df8983ed/primitives/runtime/src/generic/digest.rs#L40 - function encodeDigestItems(DigestItem[] calldata digestItems) - internal - pure - returns (bytes memory) - { + function encodeDigestItems(DigestItem[] calldata digestItems) internal pure returns (bytes memory) { // encode all digest items into a buffer bytes memory accum = hex""; for (uint256 i = 0; i < digestItems.length; i++) { @@ -166,11 +158,7 @@ library Verification { return bytes.concat(ScaleCodec.checkedEncodeCompactU32(digestItems.length), accum); } - function encodeDigestItem(DigestItem calldata digestItem) - internal - pure - returns (bytes memory) - { + function encodeDigestItem(DigestItem calldata digestItem) internal pure returns (bytes memory) { if ( digestItem.kind == DIGEST_ITEM_PRERUNTIME || digestItem.kind == DIGEST_ITEM_CONSENSUS || digestItem.kind == DIGEST_ITEM_SEAL @@ -233,11 +221,7 @@ library Verification { // SCALE-encode: MMRLeaf // Reference: https://github.com/paritytech/substrate/blob/14e0a0b628f9154c5a2c870062c3aac7df8983ed/primitives/consensus/beefy/src/mmr.rs#L52 - function createMMRLeaf(MMRLeafPartial memory leaf, bytes32 parachainHeadsRoot) - internal - pure - returns (bytes32) - { + function createMMRLeaf(MMRLeafPartial memory leaf, bytes32 parachainHeadsRoot) internal pure returns (bytes32) { bytes memory encodedLeaf = bytes.concat( ScaleCodec.encodeU8(leaf.version), ScaleCodec.encodeU32(leaf.parentNumber), diff --git a/contracts/src/interfaces/IERC20.sol b/contracts/src/interfaces/IERC20.sol index 0dac92ada4..86ef990992 100644 --- a/contracts/src/interfaces/IERC20.sol +++ b/contracts/src/interfaces/IERC20.sol @@ -65,9 +65,7 @@ interface IERC20 { * * Emits a {Transfer} event. */ - function transferFrom(address sender, address recipient, uint256 amount) - external - returns (bool); + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to diff --git a/contracts/src/interfaces/IERC20Permit.sol b/contracts/src/interfaces/IERC20Permit.sol index bc8f4b7bdc..fb0a7ae9ce 100644 --- a/contracts/src/interfaces/IERC20Permit.sol +++ b/contracts/src/interfaces/IERC20Permit.sol @@ -14,13 +14,6 @@ interface IERC20Permit { function nonces(address account) external view returns (uint256); - function permit( - address issuer, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) external; + function permit(address issuer, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) + external; } diff --git a/contracts/src/interfaces/IGateway.sol b/contracts/src/interfaces/IGateway.sol index c5b8ce9075..b2703d3144 100644 --- a/contracts/src/interfaces/IGateway.sol +++ b/contracts/src/interfaces/IGateway.sol @@ -12,14 +12,10 @@ interface IGateway { */ // Emitted when inbound message has been dispatched - event InboundMessageDispatched( - ChannelID indexed channelID, uint64 nonce, bytes32 indexed messageID, bool success - ); + event InboundMessageDispatched(ChannelID indexed channelID, uint64 nonce, bytes32 indexed messageID, bool success); // Emitted when an outbound message has been accepted for delivery to a Polkadot parachain - event OutboundMessageAccepted( - ChannelID indexed channelID, uint64 nonce, bytes32 indexed messageID, bytes payload - ); + event OutboundMessageAccepted(ChannelID indexed channelID, uint64 nonce, bytes32 indexed messageID, bytes payload); // Emitted when an agent has been created for a consensus system on Polkadot event AgentCreated(bytes32 agentID, address agent); diff --git a/contracts/src/interfaces/IShell.sol b/contracts/src/interfaces/IShell.sol index 7794a9cde8..da338ca3fd 100644 --- a/contracts/src/interfaces/IShell.sol +++ b/contracts/src/interfaces/IShell.sol @@ -6,8 +6,7 @@ interface IShell { error Unauthorized(); // Upgrade gateway shell to a new implementation - function upgrade(address impl, bytes32 implCodeHash, bytes calldata initializerParams) - external; + function upgrade(address impl, bytes32 implCodeHash, bytes calldata initializerParams) external; // Retrieve address of trusted operator function operator() external returns (address); diff --git a/contracts/src/utils/Bitfield.sol b/contracts/src/utils/Bitfield.sol index 457f7320f9..acb2cbe082 100644 --- a/contracts/src/utils/Bitfield.sol +++ b/contracts/src/utils/Bitfield.sol @@ -11,22 +11,14 @@ library Bitfield { * @dev Constants used to efficiently calculate the hamming weight of a bitfield. See * https://en.wikipedia.org/wiki/Hamming_weight#Efficient_implementation for an explanation of those constants. */ - uint256 internal constant M1 = - 0x5555555555555555555555555555555555555555555555555555555555555555; - uint256 internal constant M2 = - 0x3333333333333333333333333333333333333333333333333333333333333333; - uint256 internal constant M4 = - 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f; - uint256 internal constant M8 = - 0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff; - uint256 internal constant M16 = - 0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff; - uint256 internal constant M32 = - 0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff; - uint256 internal constant M64 = - 0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff; - uint256 internal constant M128 = - 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff; + uint256 internal constant M1 = 0x5555555555555555555555555555555555555555555555555555555555555555; + uint256 internal constant M2 = 0x3333333333333333333333333333333333333333333333333333333333333333; + uint256 internal constant M4 = 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f; + uint256 internal constant M8 = 0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff; + uint256 internal constant M16 = 0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff; + uint256 internal constant M32 = 0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff; + uint256 internal constant M64 = 0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff; + uint256 internal constant M128 = 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff; uint256 internal constant ONE = uint256(1); @@ -127,11 +119,7 @@ library Bitfield { self[element] = self[element].clearBit(uint8(index)); } - function makeIndex(uint256 seed, uint256 iteration, uint256 length) - internal - pure - returns (uint256 index) - { + function makeIndex(uint256 seed, uint256 iteration, uint256 length) internal pure returns (uint256 index) { assembly { mstore(0x00, seed) mstore(0x20, iteration) diff --git a/contracts/src/utils/Bits.sol b/contracts/src/utils/Bits.sol index 1f21a532d9..1b85366ef4 100644 --- a/contracts/src/utils/Bits.sol +++ b/contracts/src/utils/Bits.sol @@ -78,11 +78,7 @@ library Bits { // - '0 < numBits <= 256' // - 'startIndex < 256' // - 'numBits + startIndex <= 256' - function bits(uint256 self, uint8 startIndex, uint16 numBits) - internal - pure - returns (uint256) - { + function bits(uint256 self, uint8 startIndex, uint16 numBits) internal pure returns (uint256) { require(0 < numBits && startIndex < 256 && startIndex + numBits <= 256, "out of bounds"); return (self >> startIndex) & (ONES >> (256 - numBits)); } diff --git a/contracts/src/utils/Call.sol b/contracts/src/utils/Call.sol index 51fb033081..101fe317c0 100644 --- a/contracts/src/utils/Call.sol +++ b/contracts/src/utils/Call.sol @@ -5,11 +5,7 @@ pragma solidity 0.8.28; // Derived from OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) library Call { - function verifyResult(bool success, bytes memory returndata) - internal - pure - returns (bytes memory) - { + function verifyResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (success) { return returndata; } else { diff --git a/contracts/src/utils/ERC1967.sol b/contracts/src/utils/ERC1967.sol index 234efcad4e..da35daac79 100644 --- a/contracts/src/utils/ERC1967.sol +++ b/contracts/src/utils/ERC1967.sol @@ -5,8 +5,7 @@ pragma solidity 0.8.28; /// @title Minimal implementation of ERC1967 storage slot library ERC1967 { // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) - bytes32 public constant _IMPLEMENTATION_SLOT = - 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + bytes32 public constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; function load() internal view returns (address implementation) { assembly { diff --git a/contracts/src/utils/MMRProof.sol b/contracts/src/utils/MMRProof.sol index 63e883e29c..9f6259be6b 100644 --- a/contracts/src/utils/MMRProof.sol +++ b/contracts/src/utils/MMRProof.sol @@ -14,12 +14,11 @@ library MMRProof { * @param proof an array of hashes * @param proofOrder a bitfield describing the order of each item (left vs right) */ - function verifyLeafProof( - bytes32 root, - bytes32 leafHash, - bytes32[] calldata proof, - uint256 proofOrder - ) internal pure returns (bool) { + function verifyLeafProof(bytes32 root, bytes32 leafHash, bytes32[] calldata proof, uint256 proofOrder) + internal + pure + returns (bool) + { // Size of the proof is bounded, since `proofOrder` can only contain `MAXIMUM_PROOF_SIZE` orderings. if (proof.length > MAXIMUM_PROOF_SIZE) { revert ProofSizeExceeded(); @@ -32,11 +31,7 @@ library MMRProof { return root == acc; } - function hashPairs(bytes32 x, bytes32 y, uint256 order) - internal - pure - returns (bytes32 value) - { + function hashPairs(bytes32 x, bytes32 y, uint256 order) internal pure returns (bytes32 value) { assembly { switch order case 0 { diff --git a/contracts/src/utils/SafeTransfer.sol b/contracts/src/utils/SafeTransfer.sol index bbbd597614..25f8544788 100644 --- a/contracts/src/utils/SafeTransfer.sol +++ b/contracts/src/utils/SafeTransfer.sol @@ -12,8 +12,7 @@ error NativeTransferFailed(); library SafeTokenCall { function safeCall(IERC20 token, bytes memory callData) internal { (bool success, bytes memory returnData) = address(token).call(callData); - bool transferred = - success && (returnData.length == uint256(0) || abi.decode(returnData, (bool))); + bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool))); if (!transferred || address(token).code.length == 0) { revert TokenTransferFailed(); } diff --git a/contracts/src/utils/ScaleCodec.sol b/contracts/src/utils/ScaleCodec.sol index 7305d80521..1198580232 100644 --- a/contracts/src/utils/ScaleCodec.sol +++ b/contracts/src/utils/ScaleCodec.sol @@ -38,16 +38,13 @@ library ScaleCodec { v = input; // swap bytes - v = ((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00) >> 8) - | ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF) << 8); + v = ((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00) >> 8) | ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF) << 8); // swap 2-byte long pairs - v = ((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000) >> 16) - | ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF) << 16); + v = ((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000) >> 16) | ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF) << 16); // swap 4-byte long pairs - v = ((v & 0xFFFFFFFF00000000FFFFFFFF00000000) >> 32) - | ((v & 0x00000000FFFFFFFF00000000FFFFFFFF) << 32); + v = ((v & 0xFFFFFFFF00000000FFFFFFFF00000000) >> 32) | ((v & 0x00000000FFFFFFFF00000000FFFFFFFF) << 32); // swap 8-byte long pairs v = (v >> 64) | (v << 64); diff --git a/contracts/src/utils/SubstrateMerkleProof.sol b/contracts/src/utils/SubstrateMerkleProof.sol index 37050ba926..762eec3351 100644 --- a/contracts/src/utils/SubstrateMerkleProof.sol +++ b/contracts/src/utils/SubstrateMerkleProof.sol @@ -20,13 +20,11 @@ library SubstrateMerkleProof { * @param proof the array of proofs to help verify the leaf's membership, ordered from leaf to root * @return a boolean value representing the success or failure of the operation */ - function verify( - bytes32 root, - bytes32 leaf, - uint256 position, - uint256 width, - bytes32[] calldata proof - ) internal pure returns (bool) { + function verify(bytes32 root, bytes32 leaf, uint256 position, uint256 width, bytes32[] calldata proof) + internal + pure + returns (bool) + { if (position >= width) { return false; } diff --git a/contracts/test/Agent.t.sol b/contracts/test/Agent.t.sol index 160a97c9ff..a33cca6dcd 100644 --- a/contracts/test/Agent.t.sol +++ b/contracts/test/Agent.t.sol @@ -29,8 +29,7 @@ contract AgentTest is Test { } function testInvoke() public { - (bool success, bytes memory result) = - agent.invoke(executor, abi.encodeCall(Executor.foo, ())); + (bool success, bytes memory result) = agent.invoke(executor, abi.encodeCall(Executor.foo, ())); assertEq(success, true); assertEq(result, abi.encode(true)); } @@ -45,8 +44,7 @@ contract AgentTest is Test { } function testInvokeFail() public { - (bool success, bytes memory result) = - agent.invoke(executor, abi.encodeCall(Executor.fail, ())); + (bool success, bytes memory result) = agent.invoke(executor, abi.encodeCall(Executor.fail, ())); assertEq(success, false); assertEq(result, bytes.concat(Executor.Failure.selector)); } diff --git a/contracts/test/BeefyClient.t.sol b/contracts/test/BeefyClient.t.sol index d377e2202b..d6028009a7 100644 --- a/contracts/test/BeefyClient.t.sol +++ b/contracts/test/BeefyClient.t.sol @@ -50,15 +50,12 @@ contract BeefyClientTest is Test { minNumRequiredSignatures = uint8(vm.envOr("MINIMUM_REQUIRED_SIGNATURES", uint256(16))); prevRandao = uint32(vm.envOr("PREV_RANDAO", uint256(377))); - string memory beefyCommitmentFile = - string.concat(vm.projectRoot(), "/test/data/beefy-commitment.json"); + string memory beefyCommitmentFile = string.concat(vm.projectRoot(), "/test/data/beefy-commitment.json"); string memory beefyCommitmentRaw = vm.readFile(beefyCommitmentFile); - bitFieldFile0SignatureCount = - string.concat(vm.projectRoot(), "/test/data/beefy-final-bitfield-0.json"); - bitFieldFile3SignatureCount = - string.concat(vm.projectRoot(), "/test/data/beefy-final-bitfield-3.json"); + bitFieldFile0SignatureCount = string.concat(vm.projectRoot(), "/test/data/beefy-final-bitfield-0.json"); + bitFieldFile3SignatureCount = string.concat(vm.projectRoot(), "/test/data/beefy-final-bitfield-3.json"); blockNumber = uint32(beefyCommitmentRaw.readUint(".params.commitment.blockNumber")); setId = uint32(beefyCommitmentRaw.readUint(".params.commitment.validatorSetID")); @@ -68,21 +65,16 @@ contract BeefyClientTest is Test { leafProofOrder = beefyCommitmentRaw.readUint(".params.leafProofOrder"); decodeMMRLeaf(beefyCommitmentRaw); - string memory beefyValidatorSetFile = - string.concat(vm.projectRoot(), "/test/data/beefy-validator-set.json"); + string memory beefyValidatorSetFile = string.concat(vm.projectRoot(), "/test/data/beefy-validator-set.json"); string memory beefyValidatorSetRaw = vm.readFile(beefyValidatorSetFile); setSize = uint32(beefyValidatorSetRaw.readUint(".validatorSetSize")); root = beefyValidatorSetRaw.readBytes32(".validatorRoot"); bitSetArray = beefyValidatorSetRaw.readUintArray(".participants"); absentBitSetArray = beefyValidatorSetRaw.readUintArray(".absentees"); - console.log( - "current validator's merkle root is: %s", Strings.toHexString(uint256(root), 32) - ); + console.log("current validator's merkle root is: %s", Strings.toHexString(uint256(root), 32)); - beefyClient = new BeefyClientMock( - randaoCommitDelay, randaoCommitExpiration, minNumRequiredSignatures - ); + beefyClient = new BeefyClientMock(randaoCommitDelay, randaoCommitExpiration, minNumRequiredSignatures); bitfield = beefyClient.createInitialBitfield(bitSetArray, setSize); absentBitfield = beefyClient.createInitialBitfield(absentBitSetArray, setSize); @@ -101,10 +93,8 @@ contract BeefyClientTest is Test { function initialize(uint32 _setId) public returns (BeefyClient.Commitment memory) { currentSetId = _setId; nextSetId = _setId + 1; - BeefyClient.ValidatorSet memory vset = - BeefyClient.ValidatorSet(currentSetId, setSize, root); - BeefyClient.ValidatorSet memory nextvset = - BeefyClient.ValidatorSet(nextSetId, setSize, root); + BeefyClient.ValidatorSet memory vset = BeefyClient.ValidatorSet(currentSetId, setSize, root); + BeefyClient.ValidatorSet memory nextvset = BeefyClient.ValidatorSet(nextSetId, setSize, root); beefyClient.initialize_public(0, vset, nextvset); BeefyClient.PayloadItem[] memory payload = new BeefyClient.PayloadItem[](1); payload[0] = BeefyClient.PayloadItem(mmrRootID, abi.encodePacked(mmrRoot)); @@ -117,13 +107,9 @@ contract BeefyClientTest is Test { } } - function loadFinalProofs( - string memory finalProofRaw, - BeefyClient.ValidatorProof[] storage finalProofs - ) internal { + function loadFinalProofs(string memory finalProofRaw, BeefyClient.ValidatorProof[] storage finalProofs) internal { bytes memory proofRaw = finalProofRaw.readBytes(".finalValidatorsProofRaw"); - BeefyClient.ValidatorProof[] memory proofs = - abi.decode(proofRaw, (BeefyClient.ValidatorProof[])); + BeefyClient.ValidatorProof[] memory proofs = abi.decode(proofRaw, (BeefyClient.ValidatorProof[])); for (uint256 i = 0; i < proofs.length; i++) { finalProofs.push(proofs[i]); } @@ -142,9 +128,7 @@ contract BeefyClientTest is Test { } // Regenerate bitField file - function regenerateBitField(string memory bitfieldFile, uint256 numRequiredSignatures) - internal - { + function regenerateBitField(string memory bitfieldFile, uint256 numRequiredSignatures) internal { console.log("print initialBitField"); printBitArray(bitfield); prevRandao = uint32(vm.envOr("PREV_RANDAO", prevRandao)); @@ -153,8 +137,7 @@ contract BeefyClientTest is Test { printBitArray(finalBitfield); string memory finalBitFieldRaw = ""; - finalBitFieldRaw = - finalBitFieldRaw.serialize("finalBitFieldRaw", abi.encode(finalBitfield)); + finalBitFieldRaw = finalBitFieldRaw.serialize("finalBitFieldRaw", abi.encode(finalBitfield)); string memory finaliBitFieldStr = ""; finaliBitFieldStr = finaliBitFieldStr.serialize("finalBitField", finalBitfield); @@ -168,14 +151,10 @@ contract BeefyClientTest is Test { uint8 version = uint8(beefyCommitmentRaw.readUint(".params.leaf.version")); uint32 parentNumber = uint32(beefyCommitmentRaw.readUint(".params.leaf.parentNumber")); bytes32 parentHash = beefyCommitmentRaw.readBytes32(".params.leaf.parentHash"); - uint64 nextAuthoritySetID = - uint64(beefyCommitmentRaw.readUint(".params.leaf.nextAuthoritySetID")); - uint32 nextAuthoritySetLen = - uint32(beefyCommitmentRaw.readUint(".params.leaf.nextAuthoritySetLen")); - bytes32 nextAuthoritySetRoot = - beefyCommitmentRaw.readBytes32(".params.leaf.nextAuthoritySetRoot"); - bytes32 parachainHeadsRoot = - beefyCommitmentRaw.readBytes32(".params.leaf.parachainHeadsRoot"); + uint64 nextAuthoritySetID = uint64(beefyCommitmentRaw.readUint(".params.leaf.nextAuthoritySetID")); + uint32 nextAuthoritySetLen = uint32(beefyCommitmentRaw.readUint(".params.leaf.nextAuthoritySetLen")); + bytes32 nextAuthoritySetRoot = beefyCommitmentRaw.readBytes32(".params.leaf.nextAuthoritySetRoot"); + bytes32 parachainHeadsRoot = beefyCommitmentRaw.readBytes32(".params.leaf.parachainHeadsRoot"); mmrLeaf = BeefyClient.MMRLeaf( version, parentNumber, @@ -202,12 +181,7 @@ contract BeefyClientTest is Test { createFinalProofs(); beefyClient.submitFinal( - commitment, - bitfield, - finalValidatorProofs, - emptyLeaf, - emptyLeafProofs, - emptyLeafProofOrder + commitment, bitfield, finalValidatorProofs, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder ); assertEq(beefyClient.latestBeefyBlock(), blockNumber); @@ -262,12 +236,7 @@ contract BeefyClientTest is Test { createFinalProofs(); beefyClient.submitFinal( - commitment, - bitfield, - finalValidatorProofs3SignatureCount, - emptyLeaf, - emptyLeafProofs, - emptyLeafProofOrder + commitment, bitfield, finalValidatorProofs3SignatureCount, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder ); assertEq(beefyClient.latestBeefyBlock(), blockNumber); @@ -299,9 +268,7 @@ contract BeefyClientTest is Test { // make an invalid signature vm.expectRevert(BeefyClient.InvalidValidatorProofLength.selector); - beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder - ); + beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); } function testSubmitFailInvalidSignature() public { @@ -317,16 +284,10 @@ contract BeefyClientTest is Test { createFinalProofs(); // make an invalid signature - finalValidatorProofs[0].r = - 0xb5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c; + finalValidatorProofs[0].r = 0xb5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c; vm.expectRevert(BeefyClient.InvalidSignature.selector); beefyClient.submitFinal( - commitment, - bitfield, - finalValidatorProofs, - emptyLeaf, - emptyLeafProofs, - emptyLeafProofOrder + commitment, bitfield, finalValidatorProofs, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder ); } @@ -346,12 +307,7 @@ contract BeefyClientTest is Test { finalValidatorProofs[0].index = 0; vm.expectRevert(BeefyClient.InvalidValidatorProof.selector); beefyClient.submitFinal( - commitment, - bitfield, - finalValidatorProofs, - emptyLeaf, - emptyLeafProofs, - emptyLeafProofOrder + commitment, bitfield, finalValidatorProofs, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder ); } @@ -372,12 +328,7 @@ contract BeefyClientTest is Test { vm.expectRevert(BeefyClient.StaleCommitment.selector); beefyClient.submitFinal( - commitment, - bitfield, - finalValidatorProofs, - emptyLeaf, - emptyLeafProofs, - emptyLeafProofOrder + commitment, bitfield, finalValidatorProofs, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder ); } @@ -396,12 +347,7 @@ contract BeefyClientTest is Test { bitfield[0] = 0; vm.expectRevert(BeefyClient.InvalidBitfield.selector); beefyClient.submitFinal( - commitment, - bitfield, - finalValidatorProofs, - emptyLeaf, - emptyLeafProofs, - emptyLeafProofOrder + commitment, bitfield, finalValidatorProofs, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder ); } @@ -413,12 +359,7 @@ contract BeefyClientTest is Test { // reverted without commit PrevRandao vm.expectRevert(BeefyClient.PrevRandaoNotCaptured.selector); beefyClient.submitFinal( - commitment, - bitfield, - finalValidatorProofs, - emptyLeaf, - emptyLeafProofs, - emptyLeafProofOrder + commitment, bitfield, finalValidatorProofs, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder ); } @@ -463,9 +404,7 @@ contract BeefyClientTest is Test { createFinalProofs(); - beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder - ); + beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); assertEq(beefyClient.latestBeefyBlock(), blockNumber); assertEq(beefyClient.getValidatorCounter(false, finalValidatorProofs[0].index), 1); assertEq(beefyClient.getValidatorCounter(true, finalValidatorProofs[0].index), 0); @@ -490,9 +429,7 @@ contract BeefyClientTest is Test { createFinalProofs(); - beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder - ); + beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); assertEq(beefyClient.latestBeefyBlock(), blockNumber); assertEq(beefyClient.getValidatorCounter(false, finalValidatorProofs[0].index), 1); assertEq(beefyClient.getValidatorCounter(true, finalValidatorProofs[0].index), 0); @@ -537,12 +474,7 @@ contract BeefyClientTest is Test { createFinalProofs(); beefyClient.submitFinal( - commitment, - bitfield, - finalValidatorProofs3SignatureCount, - mmrLeaf, - mmrLeafProofs, - leafProofOrder + commitment, bitfield, finalValidatorProofs3SignatureCount, mmrLeaf, mmrLeafProofs, leafProofOrder ); assertEq(beefyClient.latestBeefyBlock(), blockNumber); assertEq(beefyClient.getValidatorCounter(false, finalValidatorProofs[0].index), 4); @@ -551,9 +483,7 @@ contract BeefyClientTest is Test { assertEq(beefyClient.getValidatorCounter(true, finalValidatorProofs[1].index), 0); } - function testSubmitWithHandoverFailWithInvalidValidatorProofWhenNotProvidingSignatureCount() - public - { + function testSubmitWithHandoverFailWithInvalidValidatorProofWhenNotProvidingSignatureCount() public { //initialize with previous set BeefyClient.Commitment memory commitment = initialize(setId - 1); @@ -573,9 +503,7 @@ contract BeefyClientTest is Test { createFinalProofs(); vm.expectRevert(BeefyClient.InvalidValidatorProofLength.selector); - beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder - ); + beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); } function testSubmitWithHandoverFailWithoutPrevRandao() public { @@ -585,9 +513,7 @@ contract BeefyClientTest is Test { beefyClient.submitInitial(commitment, bitfield, finalValidatorProofs[0]); vm.expectRevert(BeefyClient.PrevRandaoNotCaptured.selector); - beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder - ); + beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); } function testSubmitWithHandoverFailStaleCommitment() public { @@ -607,21 +533,15 @@ contract BeefyClientTest is Test { vm.expectRevert(BeefyClient.StaleCommitment.selector); beefyClient.submitFinal( - commitment, - bitfield, - finalValidatorProofs, - emptyLeaf, - emptyLeafProofs, - emptyLeafProofOrder + commitment, bitfield, finalValidatorProofs, emptyLeaf, emptyLeafProofs, emptyLeafProofOrder ); } function testScaleEncodeCommit() public { BeefyClient.PayloadItem[] memory _payload = new BeefyClient.PayloadItem[](2); _payload[0] = BeefyClient.PayloadItem(bytes2("ab"), hex"000102"); - _payload[1] = BeefyClient.PayloadItem( - mmrRootID, hex"3ac49cd24778522203e8bf40a4712ea3f07c3803bbd638cb53ebb3564ec13e8c" - ); + _payload[1] = + BeefyClient.PayloadItem(mmrRootID, hex"3ac49cd24778522203e8bf40a4712ea3f07c3803bbd638cb53ebb3564ec13e8c"); BeefyClient.Commitment memory _commitment = BeefyClient.Commitment(5, 7, _payload); @@ -681,9 +601,7 @@ contract BeefyClientTest is Test { initialize(setId + 1); //submit will be reverted with InvalidCommitment vm.expectRevert(BeefyClient.InvalidCommitment.selector); - beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder - ); + beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); } function testSubmitWithHandoverFailWithInvalidValidatorSet() public { @@ -701,9 +619,7 @@ contract BeefyClientTest is Test { initialize(setId + 1); //submit will be reverted with InvalidCommitment vm.expectRevert(BeefyClient.InvalidCommitment.selector); - beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder - ); + beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); } function testSubmitFailWithInvalidTicket() public { @@ -717,13 +633,10 @@ contract BeefyClientTest is Test { // Changing the commitment changes its hash, so the ticket can't be found. // A zero value ticket is returned in this case, because submitInitial hasn't run for this commitment. - BeefyClient.Commitment memory _commitment = - BeefyClient.Commitment(blockNumber, setId + 1, commitment.payload); + BeefyClient.Commitment memory _commitment = BeefyClient.Commitment(blockNumber, setId + 1, commitment.payload); //submit will be reverted with InvalidTicket vm.expectRevert(BeefyClient.InvalidTicket.selector); - beefyClient.submitFinal( - _commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder - ); + beefyClient.submitFinal(_commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); } function testSubmitFailWithInvalidMMRLeaf() public { @@ -744,9 +657,7 @@ contract BeefyClientTest is Test { mmrLeaf.nextAuthoritySetID = setId; //submit will be reverted with InvalidMMRLeaf vm.expectRevert(BeefyClient.InvalidMMRLeaf.selector); - beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder - ); + beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); } function testSubmitFailWithInvalidMMRLeafProof() public { @@ -765,9 +676,7 @@ contract BeefyClientTest is Test { mmrLeaf.parentNumber = 1; //submit will be reverted with InvalidMMRLeafProof vm.expectRevert(BeefyClient.InvalidMMRLeafProof.selector); - beefyClient.submitFinal( - commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder - ); + beefyClient.submitFinal(commitment, bitfield, finalValidatorProofs, mmrLeaf, mmrLeafProofs, leafProofOrder); } function testSubmitFailWithNotEnoughClaims() public { @@ -785,8 +694,7 @@ contract BeefyClientTest is Test { beefyClient.computeNumRequiredSignatures_public(setSize, 0, minNumRequiredSignatures); regenerateBitField(bitFieldFile0SignatureCount, numRequiredSignatures); // Generate a bitfield for signature count 3. - numRequiredSignatures = - beefyClient.computeNumRequiredSignatures_public(setSize, 3, minNumRequiredSignatures); + numRequiredSignatures = beefyClient.computeNumRequiredSignatures_public(setSize, 3, minNumRequiredSignatures); regenerateBitField(bitFieldFile3SignatureCount, numRequiredSignatures); } @@ -801,19 +709,16 @@ contract BeefyClientTest is Test { assertGt(result, 0, "result is greater than zero."); } - function testFuzzSignatureSamplingRanges( - uint128 validatorSetLen, - uint16 signatureUsageCount, - uint16 minSignatures - ) public { + function testFuzzSignatureSamplingRanges(uint128 validatorSetLen, uint16 signatureUsageCount, uint16 minSignatures) + public + { // There must be atleast 1 validator. vm.assume(validatorSetLen > 0); // Min signatures must be less than the amount of validators. vm.assume(beefyClient.computeQuorum_public(validatorSetLen) > minSignatures); - uint256 result = beefyClient.computeNumRequiredSignatures_public( - validatorSetLen, signatureUsageCount, minSignatures - ); + uint256 result = + beefyClient.computeNumRequiredSignatures_public(validatorSetLen, signatureUsageCount, minSignatures); // Calculator 2/3 with flooring due to integer division plus 1. uint256 twoThirdsMajority = uint256(validatorSetLen) * 2 / 3 + 1; diff --git a/contracts/test/Bitfield.t.sol b/contracts/test/Bitfield.t.sol index 3fe6f3e4f9..d0713a3c81 100644 --- a/contracts/test/Bitfield.t.sol +++ b/contracts/test/Bitfield.t.sol @@ -14,8 +14,7 @@ contract BitfieldTest is Test { function testBitfieldSubsampling() public { BitfieldWrapper bw = new BitfieldWrapper(); - string memory json = - vm.readFile(string.concat(vm.projectRoot(), "/test/data/beefy-validator-set.json")); + string memory json = vm.readFile(string.concat(vm.projectRoot(), "/test/data/beefy-validator-set.json")); uint32 setSize = uint32(json.readUint(".validatorSetSize")); bytes32 root = json.readBytes32(".validatorRoot"); uint256[] memory bitSetArray = json.readUintArray(".participants"); diff --git a/contracts/test/ForkUpgrade.t.sol b/contracts/test/ForkUpgrade.t.sol index dece813a1e..b46b8a9560 100644 --- a/contracts/test/ForkUpgrade.t.sol +++ b/contracts/test/ForkUpgrade.t.sol @@ -9,24 +9,16 @@ import {IGateway} from "../src/interfaces/IGateway.sol"; import {Gateway} from "../src/Gateway.sol"; import {Gateway202410} from "../src/upgrades/Gateway202410.sol"; import {AgentExecutor} from "../src/AgentExecutor.sol"; -import { - UpgradeParams, - SetOperatingModeParams, - OperatingMode, - RegisterForeignTokenParams -} from "../src/Params.sol"; +import {UpgradeParams, SetOperatingModeParams, OperatingMode, RegisterForeignTokenParams} from "../src/Params.sol"; import {ChannelID, ParaID, OperatingMode, TokenInfo} from "../src/Types.sol"; contract ForkUpgradeTest is Test { address private constant GatewayProxy = 0x27ca963C279c93801941e1eB8799c23f407d68e7; address private constant BeefyClient = 0x6eD05bAa904df3DE117EcFa638d4CB84e1B8A00C; - bytes32 private constant BridgeHubAgent = - 0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314; + bytes32 private constant BridgeHubAgent = 0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314; function setUp() public { - vm.createSelectFork( - "https://rpc.tenderly.co/fork/b77e07b8-ad6d-4e83-b5be-30a2001964aa", 20_645_700 - ); + vm.createSelectFork("https://rpc.tenderly.co/fork/b77e07b8-ad6d-4e83-b5be-30a2001964aa", 20_645_700); vm.allowCheatcodes(GatewayProxy); vm.startPrank(GatewayProxy); forkUpgrade(); @@ -35,15 +27,11 @@ contract ForkUpgradeTest is Test { function forkUpgrade() public { AgentExecutor executor = new AgentExecutor(); - Gateway202410 newLogic = new Gateway202410( - BeefyClient, address(executor), ParaID.wrap(1002), BridgeHubAgent, 10, 20_000_000_000 - ); + Gateway202410 newLogic = + new Gateway202410(BeefyClient, address(executor), ParaID.wrap(1002), BridgeHubAgent, 10, 20_000_000_000); - UpgradeParams memory params = UpgradeParams({ - impl: address(newLogic), - implCodeHash: address(newLogic).codehash, - initParams: bytes("") - }); + UpgradeParams memory params = + UpgradeParams({impl: address(newLogic), implCodeHash: address(newLogic).codehash, initParams: bytes("")}); vm.expectEmit(true, false, false, false); emit IUpgradable.Upgraded(address(newLogic)); @@ -52,42 +40,23 @@ contract ForkUpgradeTest is Test { } function checkLegacyToken() public { - assert( - IGateway(GatewayProxy).isTokenRegistered(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2) - ); - assertEq( - IGateway(GatewayProxy).queryForeignTokenID(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2), - bytes32("") - ); - assert( - IGateway(GatewayProxy).isTokenRegistered(0xBA41Ddf06B7fFD89D1267b5A93BFeF2424eb2003) - ); - assertEq( - IGateway(GatewayProxy).queryForeignTokenID(0xBA41Ddf06B7fFD89D1267b5A93BFeF2424eb2003), - bytes32("") - ); + assert(IGateway(GatewayProxy).isTokenRegistered(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)); + assertEq(IGateway(GatewayProxy).queryForeignTokenID(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2), bytes32("")); + assert(IGateway(GatewayProxy).isTokenRegistered(0xBA41Ddf06B7fFD89D1267b5A93BFeF2424eb2003)); + assertEq(IGateway(GatewayProxy).queryForeignTokenID(0xBA41Ddf06B7fFD89D1267b5A93BFeF2424eb2003), bytes32("")); } function registerForeignToken() public { bytes32 dotId = 0xa8f2ec5bdd7a07d844ee3bce83f9ba3881f495d96f07cacbeeb77d9e031db4f0; - RegisterForeignTokenParams memory params = RegisterForeignTokenParams({ - foreignTokenID: dotId, - name: "DOT", - symbol: "DOT", - decimals: 10 - }); + RegisterForeignTokenParams memory params = + RegisterForeignTokenParams({foreignTokenID: dotId, name: "DOT", symbol: "DOT", decimals: 10}); vm.expectEmit(true, true, false, false); emit IGateway.ForeignTokenRegistered(dotId, address(0x0)); Gateway202410(GatewayProxy).registerForeignToken(abi.encode(params)); - assert( - IGateway(GatewayProxy).isTokenRegistered(0x70D9d338A6b17957B16836a90192BD8CDAe0b53d) - ); - assertEq( - IGateway(GatewayProxy).queryForeignTokenID(0x70D9d338A6b17957B16836a90192BD8CDAe0b53d), - dotId - ); + assert(IGateway(GatewayProxy).isTokenRegistered(0x70D9d338A6b17957B16836a90192BD8CDAe0b53d)); + assertEq(IGateway(GatewayProxy).queryForeignTokenID(0x70D9d338A6b17957B16836a90192BD8CDAe0b53d), dotId); } function testSanityCheck() public { diff --git a/contracts/test/Gateway.t.sol b/contracts/test/Gateway.t.sol index d8022f619f..587a8556e7 100644 --- a/contracts/test/Gateway.t.sol +++ b/contracts/test/Gateway.t.sol @@ -21,15 +21,7 @@ import {Verification} from "../src/Verification.sol"; import {Assets} from "../src/Assets.sol"; import {SubstrateTypes} from "./../src/SubstrateTypes.sol"; import {MultiAddress} from "../src/MultiAddress.sol"; -import { - Channel, - InboundMessage, - OperatingMode, - ParaID, - Command, - ChannelID, - MultiAddress -} from "../src/Types.sol"; +import {Channel, InboundMessage, OperatingMode, ParaID, Command, ChannelID, MultiAddress} from "../src/Types.sol"; import {NativeTransferFailed} from "../src/utils/SafeTransfer.sol"; import {PricingStorage} from "../src/storage/PricingStorage.sol"; @@ -70,19 +62,16 @@ contract GatewayTest is Test { event Transfer(address indexed from, address indexed to, uint256 value); ParaID public bridgeHubParaID = ParaID.wrap(1013); - bytes32 public bridgeHubAgentID = - 0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314; + bytes32 public bridgeHubAgentID = 0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314; address public bridgeHubAgent; ParaID public assetHubParaID = ParaID.wrap(1000); - bytes32 public assetHubAgentID = - 0x81c5ab2571199e3188135178f3c2c8e2d268be1313d029b30f534fa579b69b79; + bytes32 public assetHubAgentID = 0x81c5ab2571199e3188135178f3c2c8e2d268be1313d029b30f534fa579b69b79; address public assetHubAgent; address public relayer; - bytes32[] public proof = - [bytes32(0x2f9ee6cfdf244060dc28aa46347c5219e303fc95062dd672b4e406ca5c29764b)]; + bytes32[] public proof = [bytes32(0x2f9ee6cfdf244060dc28aa46347c5219e303fc95062dd672b4e406ca5c29764b)]; bytes public parachainHeaderProof = bytes("validProof"); MockGateway public gatewayLogic; @@ -121,12 +110,7 @@ contract GatewayTest is Test { function setUp() public { AgentExecutor executor = new AgentExecutor(); gatewayLogic = new MockGateway( - address(0), - address(executor), - bridgeHubParaID, - bridgeHubAgentID, - foreignTokenDecimals, - maxDestinationFee + address(0), address(executor), bridgeHubParaID, bridgeHubAgentID, foreignTokenDecimals, maxDestinationFee ); Gateway.Config memory config = Gateway.Config({ mode: OperatingMode.Normal, @@ -217,16 +201,7 @@ contract GatewayTest is Test { hoax(relayer, 1 ether); IGateway(address(gateway)).submitV1( - InboundMessage( - assetHubParaID.into(), - 1, - command, - params, - maxDispatchGas, - maxRefund, - reward, - messageID - ), + InboundMessage(assetHubParaID.into(), 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -239,16 +214,7 @@ contract GatewayTest is Test { hoax(relayer, 1 ether); IGateway(address(gateway)).submitV1( - InboundMessage( - assetHubParaID.into(), - 1, - command, - params, - maxDispatchGas, - maxRefund, - reward, - messageID - ), + InboundMessage(assetHubParaID.into(), 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -257,16 +223,7 @@ contract GatewayTest is Test { vm.expectRevert(Gateway.InvalidNonce.selector); hoax(relayer, 1 ether); IGateway(address(gateway)).submitV1( - InboundMessage( - assetHubParaID.into(), - 1, - command, - params, - maxDispatchGas, - maxRefund, - reward, - messageID - ), + InboundMessage(assetHubParaID.into(), 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -278,16 +235,7 @@ contract GatewayTest is Test { vm.expectRevert(Gateway.ChannelDoesNotExist.selector); hoax(relayer); IGateway(address(gateway)).submitV1( - InboundMessage( - ParaID.wrap(42).into(), - 1, - command, - "", - maxDispatchGas, - maxRefund, - reward, - messageID - ), + InboundMessage(ParaID.wrap(42).into(), 1, command, "", maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -303,16 +251,7 @@ contract GatewayTest is Test { hoax(relayer, 1 ether); IGateway(address(gateway)).submitV1( - InboundMessage( - assetHubParaID.into(), - 1, - command, - params, - maxDispatchGas, - maxRefund, - reward, - messageID - ), + InboundMessage(assetHubParaID.into(), 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -335,16 +274,7 @@ contract GatewayTest is Test { uint256 startGas = gasleft(); IGateway(address(gateway)).submitV1( - InboundMessage( - assetHubParaID.into(), - 1, - command, - params, - maxDispatchGas, - maxRefund, - reward, - messageID - ), + InboundMessage(assetHubParaID.into(), 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -370,16 +300,7 @@ contract GatewayTest is Test { hoax(relayer, 1 ether); IGateway(address(gateway)).submitV1( - InboundMessage( - assetHubParaID.into(), - 1, - command, - params, - maxDispatchGas, - maxRefund, - reward, - messageID - ), + InboundMessage(assetHubParaID.into(), 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -405,9 +326,7 @@ contract GatewayTest is Test { token.approve(address(gateway), 1); hoax(user, fee); - IGateway(address(gateway)).sendToken{value: fee}( - address(token), ParaID.wrap(0), recipientAddress32, 1, 1 - ); + IGateway(address(gateway)).sendToken{value: fee}(address(token), ParaID.wrap(0), recipientAddress32, 1, 1); assertEq(user.balance, 0); } @@ -453,19 +372,15 @@ contract GatewayTest is Test { } function testAgentExecutionBadOrigin() public { - TransferNativeFromAgentParams memory params = TransferNativeFromAgentParams({ - agentID: bytes32(0), - recipient: address(this), - amount: 1 - }); + TransferNativeFromAgentParams memory params = + TransferNativeFromAgentParams({agentID: bytes32(0), recipient: address(this), amount: 1}); vm.expectRevert(Gateway.AgentDoesNotExist.selector); MockGateway(address(gateway)).transferNativeFromAgentPublic(abi.encode(params)); } function testAgentExecutionBadPayload() public { - AgentExecuteParams memory params = - AgentExecuteParams({agentID: assetHubAgentID, payload: ""}); + AgentExecuteParams memory params = AgentExecuteParams({agentID: assetHubAgentID, payload: ""}); vm.expectRevert(Gateway.InvalidAgentExecutionPayload.selector); MockGateway(address(gateway)).agentExecutePublic(abi.encode(params)); @@ -495,15 +410,10 @@ contract GatewayTest is Test { ParaID paraID = ParaID.wrap(3042); bytes32 agentID = keccak256("3042"); - MockGateway(address(gateway)).createAgentPublic( - abi.encode(CreateAgentParams({agentID: agentID})) - ); + MockGateway(address(gateway)).createAgentPublic(abi.encode(CreateAgentParams({agentID: agentID}))); - CreateChannelParams memory params = CreateChannelParams({ - channelID: paraID.into(), - agentID: agentID, - mode: OperatingMode.Normal - }); + CreateChannelParams memory params = + CreateChannelParams({channelID: paraID.into(), agentID: agentID, mode: OperatingMode.Normal}); vm.expectEmit(true, false, false, true); emit IGateway.ChannelCreated(paraID.into()); @@ -514,11 +424,8 @@ contract GatewayTest is Test { ParaID paraID = ParaID.wrap(3042); bytes32 agentID = keccak256("3042"); - CreateChannelParams memory params = CreateChannelParams({ - channelID: paraID.into(), - mode: OperatingMode.Normal, - agentID: agentID - }); + CreateChannelParams memory params = + CreateChannelParams({channelID: paraID.into(), mode: OperatingMode.Normal, agentID: agentID}); vm.expectRevert(Gateway.AgentDoesNotExist.selector); MockGateway(address(gateway)).createChannelPublic(abi.encode(params)); @@ -528,15 +435,10 @@ contract GatewayTest is Test { ParaID paraID = ParaID.wrap(3042); bytes32 agentID = keccak256("3042"); - MockGateway(address(gateway)).createAgentPublic( - abi.encode(CreateAgentParams({agentID: agentID})) - ); + MockGateway(address(gateway)).createAgentPublic(abi.encode(CreateAgentParams({agentID: agentID}))); - CreateChannelParams memory params = CreateChannelParams({ - channelID: paraID.into(), - agentID: agentID, - mode: OperatingMode.Normal - }); + CreateChannelParams memory params = + CreateChannelParams({channelID: paraID.into(), agentID: agentID, mode: OperatingMode.Normal}); MockGateway(address(gateway)).createChannelPublic(abi.encode(params)); @@ -550,10 +452,7 @@ contract GatewayTest is Test { uint256 fee = pricing.deliveryCost; bytes memory params = abi.encode( - UpdateChannelParams({ - channelID: assetHubParaID.into(), - mode: OperatingMode.RejectingOutboundMessages - }) + UpdateChannelParams({channelID: assetHubParaID.into(), mode: OperatingMode.RejectingOutboundMessages}) ); vm.expectEmit(true, false, false, true); @@ -567,10 +466,7 @@ contract GatewayTest is Test { function testUpdateChannelFailDoesNotExist() public { bytes memory params = abi.encode( - UpdateChannelParams({ - channelID: ParaID.wrap(5956).into(), - mode: OperatingMode.RejectingOutboundMessages - }) + UpdateChannelParams({channelID: ParaID.wrap(5956).into(), mode: OperatingMode.RejectingOutboundMessages}) ); vm.expectRevert(Gateway.ChannelDoesNotExist.selector); @@ -625,19 +521,15 @@ contract GatewayTest is Test { function testUpgradeFailCodeHashMismatch() public { MockGatewayV2 newLogic = new MockGatewayV2(); - UpgradeParams memory params = UpgradeParams({ - impl: address(newLogic), - implCodeHash: bytes32(0), - initParams: abi.encode(42) - }); + UpgradeParams memory params = + UpgradeParams({impl: address(newLogic), implCodeHash: bytes32(0), initParams: abi.encode(42)}); vm.expectRevert(IUpgradable.InvalidCodeHash.selector); MockGateway(address(gateway)).upgradePublic(abi.encode(params)); } function testSetOperatingMode() public { - SetOperatingModeParams memory params = - SetOperatingModeParams({mode: OperatingMode.RejectingOutboundMessages}); + SetOperatingModeParams memory params = SetOperatingModeParams({mode: OperatingMode.RejectingOutboundMessages}); OperatingMode mode = IGateway(address(gateway)).operatingMode(); assertEq(uint256(mode), 0); @@ -653,13 +545,8 @@ contract GatewayTest is Test { address recipient = makeAddr("recipient"); - bytes memory params = abi.encode( - TransferNativeFromAgentParams({ - agentID: assetHubAgentID, - recipient: recipient, - amount: 3 ether - }) - ); + bytes memory params = + abi.encode(TransferNativeFromAgentParams({agentID: assetHubAgentID, recipient: recipient, amount: 3 ether})); MockGateway(address(gateway)).transferNativeFromAgentPublic(params); @@ -719,9 +606,7 @@ contract GatewayTest is Test { vm.expectEmit(true, false, false, false); emit IGateway.OutboundMessageAccepted(assetHubParaID.into(), 1, messageID, bytes("")); - IGateway(address(gateway)).sendToken{value: fee}( - address(token), destPara, recipientAddress32, 1, 1 - ); + IGateway(address(gateway)).sendToken{value: fee}(address(token), destPara, recipientAddress32, 1, 1); } function testSendTokenAddress32ToAssetHub() public { @@ -744,9 +629,7 @@ contract GatewayTest is Test { vm.expectEmit(true, false, false, false); emit IGateway.OutboundMessageAccepted(assetHubParaID.into(), 1, messageID, bytes("")); - IGateway(address(gateway)).sendToken{value: fee}( - address(token), destPara, recipientAddress32, 1, 1 - ); + IGateway(address(gateway)).sendToken{value: fee}(address(token), destPara, recipientAddress32, 1, 1); } function testSendTokenAddress20() public { @@ -769,9 +652,7 @@ contract GatewayTest is Test { vm.expectEmit(true, false, false, false); emit IGateway.OutboundMessageAccepted(assetHubParaID.into(), 1, messageID, bytes("")); - IGateway(address(gateway)).sendToken{value: fee}( - address(token), destPara, recipientAddress20, 1, 1 - ); + IGateway(address(gateway)).sendToken{value: fee}(address(token), destPara, recipientAddress20, 1, 1); } function testSendTokenAddress20FailsInvalidDestination() public { @@ -786,9 +667,7 @@ contract GatewayTest is Test { // Should fail to send tokens to AssetHub vm.expectRevert(Assets.Unsupported.selector); - IGateway(address(gateway)).sendToken{value: 2 ether}( - address(token), destPara, recipientAddress20, 1, 1 - ); + IGateway(address(gateway)).sendToken{value: 2 ether}(address(token), destPara, recipientAddress20, 1, 1); } /** @@ -819,15 +698,11 @@ contract GatewayTest is Test { IGateway(address(gateway)).registerToken{value: fee}(address(token)); bytes memory params = abi.encode( - UpdateChannelParams({ - channelID: assetHubParaID.into(), - mode: OperatingMode.RejectingOutboundMessages - }) + UpdateChannelParams({channelID: assetHubParaID.into(), mode: OperatingMode.RejectingOutboundMessages}) ); MockGateway(address(gateway)).updateChannelPublic(params); - OperatingMode mode = - IGateway(address(gateway)).channelOperatingModeOf(assetHubParaID.into()); + OperatingMode mode = IGateway(address(gateway)).channelOperatingModeOf(assetHubParaID.into()); assertEq(uint256(mode), 1); // Now all outbound messaging should be disabled @@ -836,9 +711,7 @@ contract GatewayTest is Test { IGateway(address(gateway)).registerToken{value: 1 ether}(address(token)); vm.expectRevert(Gateway.Disabled.selector); - IGateway(address(gateway)).sendToken{value: 1 ether}( - address(token), ParaID.wrap(0), recipientAddress32, 1, 1 - ); + IGateway(address(gateway)).sendToken{value: 1 ether}(address(token), ParaID.wrap(0), recipientAddress32, 1, 1); } /** @@ -910,9 +783,7 @@ contract GatewayTest is Test { emit IGateway.InboundMessageDispatched(assetHubParaID.into(), 1, messageID, false); // maxDispatchGas as 1 for `create_agent` is definitely not enough IGateway(address(gateway)).submitV1( - InboundMessage( - assetHubParaID.into(), 1, command, params, 1, maxRefund, reward, messageID - ), + InboundMessage(assetHubParaID.into(), 1, command, params, 1, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -936,8 +807,7 @@ contract GatewayTest is Test { assertEq(fee, 7_500_000_000_000_000); } - bytes32 public expectChannelIDBytes = - bytes32(0xc173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539); + bytes32 public expectChannelIDBytes = bytes32(0xc173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539); function testDeriveChannelID() public { ParaID para_id = ParaID.wrap(1000); @@ -976,9 +846,7 @@ contract GatewayTest is Test { fee = IGateway(address(gateway)).quoteSendTokenFee(address(token), destPara, 0); vm.expectRevert(Assets.InvalidDestinationFee.selector); - IGateway(address(gateway)).sendToken{value: fee}( - address(token), destPara, recipientAddress32, 0, 1 - ); + IGateway(address(gateway)).sendToken{value: fee}(address(token), destPara, recipientAddress32, 0, 1); } function testSendTokenWithLargeDestinationFee() public { @@ -993,9 +861,7 @@ contract GatewayTest is Test { IGateway(address(gateway)).registerToken{value: fee}(address(token)); vm.expectRevert(Assets.InvalidDestinationFee.selector); - IGateway(address(gateway)).quoteSendTokenFee( - address(token), destPara, maxDestinationFee + 1 - ); + IGateway(address(gateway)).quoteSendTokenFee(address(token), destPara, maxDestinationFee + 1); vm.expectRevert(Assets.InvalidDestinationFee.selector); IGateway(address(gateway)).sendToken{value: fee}( @@ -1004,12 +870,8 @@ contract GatewayTest is Test { } function testRegisterForeignToken() public { - RegisterForeignTokenParams memory params = RegisterForeignTokenParams({ - foreignTokenID: dotTokenID, - name: "DOT", - symbol: "DOT", - decimals: 10 - }); + RegisterForeignTokenParams memory params = + RegisterForeignTokenParams({foreignTokenID: dotTokenID, name: "DOT", symbol: "DOT", decimals: 10}); vm.expectEmit(true, true, false, false); emit IGateway.ForeignTokenRegistered(bytes32(uint256(1)), address(0)); @@ -1020,12 +882,8 @@ contract GatewayTest is Test { function testRegisterForeignTokenDuplicateFail() public { testRegisterForeignToken(); - RegisterForeignTokenParams memory params = RegisterForeignTokenParams({ - foreignTokenID: dotTokenID, - name: "DOT", - symbol: "DOT", - decimals: 10 - }); + RegisterForeignTokenParams memory params = + RegisterForeignTokenParams({foreignTokenID: dotTokenID, name: "DOT", symbol: "DOT", decimals: 10}); vm.expectRevert(Assets.TokenAlreadyRegistered.selector); @@ -1037,11 +895,8 @@ contract GatewayTest is Test { uint256 amount = 1000; - MintForeignTokenParams memory params = MintForeignTokenParams({ - foreignTokenID: bytes32(uint256(1)), - recipient: account1, - amount: amount - }); + MintForeignTokenParams memory params = + MintForeignTokenParams({foreignTokenID: bytes32(uint256(1)), recipient: account1, amount: amount}); vm.expectEmit(true, true, false, false); emit Transfer(address(0), account1, 1000); @@ -1056,11 +911,8 @@ contract GatewayTest is Test { } function testMintNotRegisteredTokenWillFail() public { - MintForeignTokenParams memory params = MintForeignTokenParams({ - foreignTokenID: bytes32(uint256(1)), - recipient: account1, - amount: 1000 - }); + MintForeignTokenParams memory params = + MintForeignTokenParams({foreignTokenID: bytes32(uint256(1)), recipient: account1, amount: 1000}); vm.expectRevert(Assets.TokenNotRegistered.selector); @@ -1084,9 +936,7 @@ contract GatewayTest is Test { vm.expectEmit(true, false, false, false); emit IGateway.OutboundMessageAccepted(assetHubParaID.into(), 1, messageID, bytes("")); - IGateway(address(gateway)).sendToken{value: 0.1 ether}( - address(dotToken), destPara, recipientAddress32, 1, 1 - ); + IGateway(address(gateway)).sendToken{value: 0.1 ether}(address(dotToken), destPara, recipientAddress32, 1, 1); } function testSendRelayTokenToAssetHubWithAddress20() public { @@ -1100,9 +950,7 @@ contract GatewayTest is Test { vm.prank(account1); vm.expectRevert(Assets.Unsupported.selector); - IGateway(address(gateway)).sendToken{value: 0.1 ether}( - address(dotToken), destPara, recipientAddress20, 1, 1 - ); + IGateway(address(gateway)).sendToken{value: 0.1 ether}(address(dotToken), destPara, recipientAddress20, 1, 1); } function testSendRelayTokenToDestinationChainWithAddress32() public { @@ -1116,9 +964,7 @@ contract GatewayTest is Test { vm.prank(account1); vm.expectRevert(Assets.Unsupported.selector); - IGateway(address(gateway)).sendToken{value: 0.1 ether}( - address(dotToken), destPara, recipientAddress32, 1, 1 - ); + IGateway(address(gateway)).sendToken{value: 0.1 ether}(address(dotToken), destPara, recipientAddress32, 1, 1); } function testSendRelayTokenToDestinationChainWithAddress20() public { @@ -1132,9 +978,7 @@ contract GatewayTest is Test { vm.prank(account1); vm.expectRevert(Assets.Unsupported.selector); - IGateway(address(gateway)).sendToken{value: 0.1 ether}( - address(dotToken), destPara, recipientAddress20, 1, 1 - ); + IGateway(address(gateway)).sendToken{value: 0.1 ether}(address(dotToken), destPara, recipientAddress20, 1, 1); } function testSendNotRegisteredTokenWillFail() public { @@ -1142,9 +986,7 @@ contract GatewayTest is Test { vm.expectRevert(Assets.TokenNotRegistered.selector); - IGateway(address(gateway)).sendToken{value: 0.1 ether}( - address(0x0), destPara, recipientAddress32, 1, 1 - ); + IGateway(address(gateway)).sendToken{value: 0.1 ether}(address(0x0), destPara, recipientAddress32, 1, 1); } function testSendTokenFromNotMintedAccountWillFail() public { @@ -1156,13 +998,9 @@ contract GatewayTest is Test { vm.prank(account1); - vm.expectRevert( - abi.encodeWithSelector(IERC20.InsufficientBalance.selector, account1, 0, 1) - ); + vm.expectRevert(abi.encodeWithSelector(IERC20.InsufficientBalance.selector, account1, 0, 1)); - IGateway(address(gateway)).sendToken{value: 0.1 ether}( - address(dotToken), destPara, recipientAddress32, 1, 1 - ); + IGateway(address(gateway)).sendToken{value: 0.1 ether}(address(dotToken), destPara, recipientAddress32, 1, 1); } function testLegacyAgentExecutionForCompatibility() public { @@ -1170,9 +1008,7 @@ contract GatewayTest is Test { AgentExecuteParams memory params = AgentExecuteParams({ agentID: assetHubAgentID, - payload: abi.encode( - AgentExecuteCommand.TransferToken, abi.encode(address(token), address(account2), 10) - ) + payload: abi.encode(AgentExecuteCommand.TransferToken, abi.encode(address(token), address(account2), 10)) }); bytes memory encodedParams = abi.encode(params); diff --git a/contracts/test/MMRProof.t.sol b/contracts/test/MMRProof.t.sol index f8fe51b241..967abacfd4 100644 --- a/contracts/test/MMRProof.t.sol +++ b/contracts/test/MMRProof.t.sol @@ -43,11 +43,7 @@ contract MMRProofTest is Test { Fixture memory fix = fixture(); for (uint256 i = 0; i < fix.leaves.length; i++) { - assertTrue( - wrapper.verifyLeafProof( - fix.rootHash, fix.leaves[i], fix.proofs[i].items, fix.proofs[i].order - ) - ); + assertTrue(wrapper.verifyLeafProof(fix.rootHash, fix.leaves[i], fix.proofs[i].items, fix.proofs[i].order)); } } @@ -55,8 +51,6 @@ contract MMRProofTest is Test { Fixture memory fix = fixture(); vm.expectRevert(MMRProof.ProofSizeExceeded.selector); - wrapper.verifyLeafProof( - fix.rootHash, fix.leaves[0], new bytes32[](257), fix.proofs[0].order - ); + wrapper.verifyLeafProof(fix.rootHash, fix.leaves[0], new bytes32[](257), fix.proofs[0].order); } } diff --git a/contracts/test/Verification.t.sol b/contracts/test/Verification.t.sol index 747319bdad..ef3f7a9bf2 100644 --- a/contracts/test/Verification.t.sol +++ b/contracts/test/Verification.t.sol @@ -24,11 +24,7 @@ contract VerificationTest is Test { function testCreateParachainHeaderMerkleLeaf() public { Verification.DigestItem[] memory digestItems = new Verification.DigestItem[](3); - digestItems[0] = Verification.DigestItem({ - kind: 6, - consensusEngineID: 0x61757261, - data: hex"c1f05e0800000000" - }); + digestItems[0] = Verification.DigestItem({kind: 6, consensusEngineID: 0x61757261, data: hex"c1f05e0800000000"}); digestItems[1] = Verification.DigestItem({ kind: 4, consensusEngineID: 0x52505352, @@ -66,11 +62,8 @@ contract VerificationTest is Test { function testCreateParachainHeaderMerkleFailInvalidHeader() public { Verification.DigestItem[] memory digestItems = new Verification.DigestItem[](1); // Create an invalid digest item - digestItems[0] = Verification.DigestItem({ - kind: 666, - consensusEngineID: 0x61757261, - data: hex"c1f05e0800000000" - }); + digestItems[0] = + Verification.DigestItem({kind: 666, consensusEngineID: 0x61757261, data: hex"c1f05e0800000000"}); Verification.ParachainHeader memory header = Verification.ParachainHeader({ parentHash: 0x1df01d40273b074708115135fd7f76801ad4e4f1266a771a037962ee3a03259d, @@ -86,11 +79,7 @@ contract VerificationTest is Test { function testIsCommitmentInHeaderDigest() public view { Verification.DigestItem[] memory digestItems = new Verification.DigestItem[](4); - digestItems[0] = Verification.DigestItem({ - kind: 6, - consensusEngineID: 0x61757261, - data: hex"c1f05e0800000000" - }); + digestItems[0] = Verification.DigestItem({kind: 6, consensusEngineID: 0x61757261, data: hex"c1f05e0800000000"}); digestItems[1] = Verification.DigestItem({ kind: 4, consensusEngineID: 0x52505352, @@ -116,18 +105,12 @@ contract VerificationTest is Test { }); // Digest item at index 2 contains the commitment - assert( - v.isCommitmentInHeaderDigest( - 0xb5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c, header - ) - ); + assert(v.isCommitmentInHeaderDigest(0xb5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c, header)); // Now remove the commitment from the parachain header header.digestItems[2] = header.digestItems[3]; assert( - !v.isCommitmentInHeaderDigest( - 0xb5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c, header - ) + !v.isCommitmentInHeaderDigest(0xb5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c, header) ); } } diff --git a/contracts/test/mocks/BeefyClientMock.sol b/contracts/test/mocks/BeefyClientMock.sol index 149d15a83d..3e34f75063 100644 --- a/contracts/test/mocks/BeefyClientMock.sol +++ b/contracts/test/mocks/BeefyClientMock.sol @@ -6,11 +6,7 @@ import {Uint16Array, createUint16Array} from "../../src/utils/Uint16Array.sol"; import "forge-std/console.sol"; contract BeefyClientMock is BeefyClient { - constructor( - uint256 randaoCommitDelay, - uint256 randaoCommitExpiration, - uint256 minNumRequiredSignatures - ) + constructor(uint256 randaoCommitDelay, uint256 randaoCommitExpiration, uint256 minNumRequiredSignatures) BeefyClient( randaoCommitDelay, randaoCommitExpiration, @@ -21,11 +17,7 @@ contract BeefyClientMock is BeefyClient { ) {} - function encodeCommitment_public(Commitment calldata commitment) - external - pure - returns (bytes memory) - { + function encodeCommitment_public(Commitment calldata commitment) external pure returns (bytes memory) { return encodeCommitment(commitment); } @@ -68,10 +60,7 @@ contract BeefyClientMock is BeefyClient { // Perform the copy currentValidatorSet = nextValidatorSet; - assert( - currentValidatorSet.usageCounters.data.length - == nextValidatorSet.usageCounters.data.length - ); + assert(currentValidatorSet.usageCounters.data.length == nextValidatorSet.usageCounters.data.length); assert(currentValidatorSet.usageCounters.get(799) == 7); } diff --git a/contracts/test/mocks/MMRProofWrapper.sol b/contracts/test/mocks/MMRProofWrapper.sol index 24e55c47bd..25efcff74d 100644 --- a/contracts/test/mocks/MMRProofWrapper.sol +++ b/contracts/test/mocks/MMRProofWrapper.sol @@ -4,12 +4,11 @@ pragma solidity 0.8.28; import {MMRProof} from "../../src/utils/MMRProof.sol"; contract MMRProofWrapper { - function verifyLeafProof( - bytes32 root, - bytes32 leafHash, - bytes32[] calldata proof, - uint256 proofOrder - ) external pure returns (bool) { + function verifyLeafProof(bytes32 root, bytes32 leafHash, bytes32[] calldata proof, uint256 proofOrder) + external + pure + returns (bool) + { return MMRProof.verifyLeafProof(root, leafHash, proof, proofOrder); } } diff --git a/contracts/test/mocks/MockGateway.sol b/contracts/test/mocks/MockGateway.sol index f2ef4163ad..03c28db968 100644 --- a/contracts/test/mocks/MockGateway.sol +++ b/contracts/test/mocks/MockGateway.sol @@ -20,14 +20,7 @@ contract MockGateway is Gateway { uint8 foreignTokenDecimals, uint128 maxDestinationFee ) - Gateway( - beefyClient, - agentExecutor, - bridgeHubParaID, - bridgeHubHubAgentID, - foreignTokenDecimals, - maxDestinationFee - ) + Gateway(beefyClient, agentExecutor, bridgeHubParaID, bridgeHubHubAgentID, foreignTokenDecimals, maxDestinationFee) {} function agentExecutePublic(bytes calldata params) external { diff --git a/contracts/test/mocks/VerificationWrapper.sol b/contracts/test/mocks/VerificationWrapper.sol index 8cd817b4b2..b86f2a268e 100644 --- a/contracts/test/mocks/VerificationWrapper.sol +++ b/contracts/test/mocks/VerificationWrapper.sol @@ -4,17 +4,19 @@ pragma solidity 0.8.28; import {Verification} from "../../src/Verification.sol"; contract VerificationWrapper { - function createParachainHeaderMerkleLeaf( - bytes4 encodedParachainID, - Verification.ParachainHeader calldata header - ) external pure returns (bytes32) { + function createParachainHeaderMerkleLeaf(bytes4 encodedParachainID, Verification.ParachainHeader calldata header) + external + pure + returns (bytes32) + { return Verification.createParachainHeaderMerkleLeaf(encodedParachainID, header); } - function isCommitmentInHeaderDigest( - bytes32 commitment, - Verification.ParachainHeader calldata header - ) external pure returns (bool) { + function isCommitmentInHeaderDigest(bytes32 commitment, Verification.ParachainHeader calldata header) + external + pure + returns (bool) + { return Verification.isCommitmentInHeaderDigest(commitment, header); } } From 0c4f32cd28c9be491484878a503cdbfa182b90f6 Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Tue, 24 Dec 2024 21:54:49 +0200 Subject: [PATCH 03/11] undo number fmt --- contracts/src/Assets.sol | 2 +- contracts/test/ForkUpgrade.t.sol | 4 ++-- contracts/test/Gateway.t.sol | 10 +++++----- contracts/test/Math.t.sol | 16 ++++++++-------- contracts/test/ScaleCodec.t.sol | 21 ++++++++------------- contracts/test/Verification.t.sol | 6 +++--- 6 files changed, 27 insertions(+), 32 deletions(-) diff --git a/contracts/src/Assets.sol b/contracts/src/Assets.sol index 55a44bef39..eb0412dc08 100644 --- a/contracts/src/Assets.sol +++ b/contracts/src/Assets.sol @@ -254,7 +254,7 @@ library Assets { // It means that registration can be retried. // But register a PNA here is not allowed TokenInfo storage info = $.tokenRegistry[token]; - if (info.foreignID != bytes32(0)) { + if(info.foreignID != bytes32(0)) { revert TokenAlreadyRegistered(); } info.isRegistered = true; diff --git a/contracts/test/ForkUpgrade.t.sol b/contracts/test/ForkUpgrade.t.sol index b46b8a9560..226d7f0621 100644 --- a/contracts/test/ForkUpgrade.t.sol +++ b/contracts/test/ForkUpgrade.t.sol @@ -18,7 +18,7 @@ contract ForkUpgradeTest is Test { bytes32 private constant BridgeHubAgent = 0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314; function setUp() public { - vm.createSelectFork("https://rpc.tenderly.co/fork/b77e07b8-ad6d-4e83-b5be-30a2001964aa", 20_645_700); + vm.createSelectFork("https://rpc.tenderly.co/fork/b77e07b8-ad6d-4e83-b5be-30a2001964aa", 20645700); vm.allowCheatcodes(GatewayProxy); vm.startPrank(GatewayProxy); forkUpgrade(); @@ -28,7 +28,7 @@ contract ForkUpgradeTest is Test { AgentExecutor executor = new AgentExecutor(); Gateway202410 newLogic = - new Gateway202410(BeefyClient, address(executor), ParaID.wrap(1002), BridgeHubAgent, 10, 20_000_000_000); + new Gateway202410(BeefyClient, address(executor), ParaID.wrap(1002), BridgeHubAgent, 10, 20000000000); UpgradeParams memory params = UpgradeParams({impl: address(newLogic), implCodeHash: address(newLogic).codehash, initParams: bytes("")}); diff --git a/contracts/test/Gateway.t.sol b/contracts/test/Gateway.t.sol index 587a8556e7..951723d465 100644 --- a/contracts/test/Gateway.t.sol +++ b/contracts/test/Gateway.t.sol @@ -758,7 +758,7 @@ contract GatewayTest is Test { assertEq(uint256(channelMode), 0); (, uint128 fee) = gw.pricingParameters(); - assertEq(fee, 10_000_000_000); + assertEq(fee, 10000000000); (uint64 inbound, uint64 outbound) = gw.channelNoncesOf(assetHubParaID.into()); assertEq(inbound, 0); @@ -791,7 +791,7 @@ contract GatewayTest is Test { function testSetTokenFees() public { uint256 fee = IGateway(address(gateway)).quoteRegisterTokenFee(); - assertEq(fee, 5_000_000_000_000_000); + assertEq(fee, 5000000000000000); // Double the assetHubCreateAssetFee MockGateway(address(gateway)).setTokenTransferFeesPublic( abi.encode( @@ -804,7 +804,7 @@ contract GatewayTest is Test { ); fee = IGateway(address(gateway)).quoteRegisterTokenFee(); // since deliveryCost not changed, so the total fee increased only by 50% - assertEq(fee, 7_500_000_000_000_000); + assertEq(fee, 7500000000000000); } bytes32 public expectChannelIDBytes = bytes32(0xc173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539); @@ -817,7 +817,7 @@ contract GatewayTest is Test { function testSetPricingParameters() public { uint256 fee = IGateway(address(gateway)).quoteRegisterTokenFee(); - assertEq(fee, 5_000_000_000_000_000); + assertEq(fee, 5000000000000000); // Double both the exchangeRate and multiplier. Should lead to an 4x fee increase MockGateway(address(gateway)).setPricingParametersPublic( abi.encode( @@ -830,7 +830,7 @@ contract GatewayTest is Test { ); // Should expect 4x fee increase fee = IGateway(address(gateway)).quoteRegisterTokenFee(); - assertEq(fee, 20_000_000_000_000_001); + assertEq(fee, 20000000000000001); } function testSendTokenWithZeroDestinationFee() public { diff --git a/contracts/test/Math.t.sol b/contracts/test/Math.t.sol index d5a830de4e..8f955e3e39 100644 --- a/contracts/test/Math.t.sol +++ b/contracts/test/Math.t.sol @@ -56,14 +56,14 @@ contract MathTest is Test { Log2Test(13, 6144), Log2Test(13, 8192), Log2Test(14, 8193), - Log2Test(14, 12_288), - Log2Test(14, 16_384), - Log2Test(15, 16_385), - Log2Test(15, 24_576), - Log2Test(15, 32_768), - Log2Test(16, 32_769), - Log2Test(16, 49_152), - Log2Test(16, 65_535) + Log2Test(14, 12288), + Log2Test(14, 16384), + Log2Test(15, 16385), + Log2Test(15, 24576), + Log2Test(15, 32768), + Log2Test(16, 32769), + Log2Test(16, 49152), + Log2Test(16, 65535) ]; for (uint256 t = 0; t < tests.length; ++t) { diff --git a/contracts/test/ScaleCodec.t.sol b/contracts/test/ScaleCodec.t.sol index 27c2026699..87e1c31627 100644 --- a/contracts/test/ScaleCodec.t.sol +++ b/contracts/test/ScaleCodec.t.sol @@ -9,26 +9,21 @@ import {ScaleCodec} from "../src/utils/ScaleCodec.sol"; contract ScaleCodecTest is Test { function testEncodeU256() public { assertEq( - ScaleCodec.encodeU256( - 12_063_978_950_259_949_786_323_707_366_460_749_298_097_791_896_371_638_493_358_994_162_204_017_315_152 - ), + ScaleCodec.encodeU256(12063978950259949786323707366460749298097791896371638493358994162204017315152), hex"504d8a21dd3868465c8c9f2898b7f014036935fa9a1488629b109d3d59f8ab1a" ); } function testEncodeU128() public { - assertEq( - ScaleCodec.encodeU128(35_452_847_761_173_902_980_759_433_963_665_451_267), - hex"036935fa9a1488629b109d3d59f8ab1a" - ); + assertEq(ScaleCodec.encodeU128(35452847761173902980759433963665451267), hex"036935fa9a1488629b109d3d59f8ab1a"); } function testEncodeU64() public { - assertEq(ScaleCodec.encodeU64(1_921_902_728_173_129_883), hex"9b109d3d59f8ab1a"); + assertEq(ScaleCodec.encodeU64(1921902728173129883), hex"9b109d3d59f8ab1a"); } function testEncodeU32() public { - assertEq(ScaleCodec.encodeU32(447_477_849), hex"59f8ab1a"); + assertEq(ScaleCodec.encodeU32(447477849), hex"59f8ab1a"); } function testEncodeU16() public { @@ -39,10 +34,10 @@ contract ScaleCodecTest is Test { assertEq(ScaleCodec.encodeCompactU32(0), hex"00"); assertEq(ScaleCodec.encodeCompactU32(63), hex"fc"); assertEq(ScaleCodec.encodeCompactU32(64), hex"0101"); - assertEq(ScaleCodec.encodeCompactU32(16_383), hex"fdff"); - assertEq(ScaleCodec.encodeCompactU32(16_384), hex"02000100"); - assertEq(ScaleCodec.encodeCompactU32(1_073_741_823), hex"feffffff"); - assertEq(ScaleCodec.encodeCompactU32(1_073_741_824), hex"0300000040"); + assertEq(ScaleCodec.encodeCompactU32(16383), hex"fdff"); + assertEq(ScaleCodec.encodeCompactU32(16384), hex"02000100"); + assertEq(ScaleCodec.encodeCompactU32(1073741823), hex"feffffff"); + assertEq(ScaleCodec.encodeCompactU32(1073741824), hex"0300000040"); assertEq(ScaleCodec.encodeCompactU32(type(uint32).max), hex"03ffffffff"); } diff --git a/contracts/test/Verification.t.sol b/contracts/test/Verification.t.sol index ef3f7a9bf2..667837623b 100644 --- a/contracts/test/Verification.t.sol +++ b/contracts/test/Verification.t.sol @@ -38,7 +38,7 @@ contract VerificationTest is Test { Verification.ParachainHeader memory header = Verification.ParachainHeader({ parentHash: 0x1df01d40273b074708115135fd7f76801ad4e4f1266a771a037962ee3a03259d, - number: 866_538, + number: 866538, stateRoot: 0x7b2d59d4de7c629b55a9bc9b76d932616f2011a26f09b52da36e070d6a7eee0d, extrinsicsRoot: 0x9d1c5d256003f68dda03dc33810a88a61f73791dc7ff92b04232a6b1b4f4b3c0, digestItems: digestItems @@ -67,7 +67,7 @@ contract VerificationTest is Test { Verification.ParachainHeader memory header = Verification.ParachainHeader({ parentHash: 0x1df01d40273b074708115135fd7f76801ad4e4f1266a771a037962ee3a03259d, - number: 866_538, + number: 866538, stateRoot: 0x7b2d59d4de7c629b55a9bc9b76d932616f2011a26f09b52da36e070d6a7eee0d, extrinsicsRoot: 0x9d1c5d256003f68dda03dc33810a88a61f73791dc7ff92b04232a6b1b4f4b3c0, digestItems: digestItems @@ -98,7 +98,7 @@ contract VerificationTest is Test { Verification.ParachainHeader memory header = Verification.ParachainHeader({ parentHash: 0x1df01d40273b074708115135fd7f76801ad4e4f1266a771a037962ee3a03259d, - number: 866_538, + number: 866538, stateRoot: 0x7b2d59d4de7c629b55a9bc9b76d932616f2011a26f09b52da36e070d6a7eee0d, extrinsicsRoot: 0x9d1c5d256003f68dda03dc33810a88a61f73791dc7ff92b04232a6b1b4f4b3c0, digestItems: digestItems From e1182b9f0b5b0b80627add22d3fbb60e1dc32616 Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Tue, 24 Dec 2024 21:57:06 +0200 Subject: [PATCH 04/11] undo number fmt --- contracts/scripts/DeployBeefyClient.sol | 2 +- contracts/scripts/westend/UpgradeShell.sol | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/scripts/DeployBeefyClient.sol b/contracts/scripts/DeployBeefyClient.sol index 40ca588f5a..423be27602 100644 --- a/contracts/scripts/DeployBeefyClient.sol +++ b/contracts/scripts/DeployBeefyClient.sol @@ -18,7 +18,7 @@ contract DeployBeefyClient is Script { function readConfig() internal pure returns (Config memory config) { // Checkpoint generated using the script `./beefy-checkpoint.js` script in Polkadot-JS. config = Config({ - startBlock: 21_087_413, + startBlock: 21087413, current: BeefyClient.ValidatorSet({ id: 644, length: 297, diff --git a/contracts/scripts/westend/UpgradeShell.sol b/contracts/scripts/westend/UpgradeShell.sol index 6a668d4e4a..7abe08546c 100644 --- a/contracts/scripts/westend/UpgradeShell.sol +++ b/contracts/scripts/westend/UpgradeShell.sol @@ -39,17 +39,17 @@ contract UpgradeShell is Script { bridgeHubParaID: ParaID.wrap(1002), bridgeHubAgentID: 0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314, foreignTokenDecimals: 12, - maxDestinationFee: 2_000_000_000_000, + maxDestinationFee: 2000000000000, initializerParams: Gateway.Config({ mode: OperatingMode.Normal, - deliveryCost: 200_000_000_000, // 0.2 Wnd + deliveryCost: 200000000000, // 0.2 Wnd registerTokenFee: 0.002 ether, assetHubParaID: ParaID.wrap(1000), assetHubAgentID: 0x81c5ab2571199e3188135178f3c2c8e2d268be1313d029b30f534fa579b69b79, - assetHubCreateAssetFee: 200_000_000_000, // 0.2 Wnd - assetHubReserveTransferFee: 200_000_000_000, // 0.2 Wnd - exchangeRate: ud60x18(2_400_000_000_000_000), - multiplier: ud60x18(1_330_000_000_000_000_000), + assetHubCreateAssetFee: 200000000000, // 0.2 Wnd + assetHubReserveTransferFee: 200000000000, // 0.2 Wnd + exchangeRate: ud60x18(2400000000000000), + multiplier: ud60x18(1330000000000000000), rescueOperator: 0x302F0B71B8aD3CF6dD90aDb668E49b2168d652fd }) }); From 3bf2b15e5d805b0e8898725d05f3e93b9f47738d Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Tue, 24 Dec 2024 21:57:21 +0200 Subject: [PATCH 05/11] undo fmt --- contracts/src/Assets.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/src/Assets.sol b/contracts/src/Assets.sol index eb0412dc08..55a44bef39 100644 --- a/contracts/src/Assets.sol +++ b/contracts/src/Assets.sol @@ -254,7 +254,7 @@ library Assets { // It means that registration can be retried. // But register a PNA here is not allowed TokenInfo storage info = $.tokenRegistry[token]; - if(info.foreignID != bytes32(0)) { + if (info.foreignID != bytes32(0)) { revert TokenAlreadyRegistered(); } info.isRegistered = true; From 32c8dda50a9c7623e347ed168ac564669273c17f Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Tue, 24 Dec 2024 22:09:44 +0200 Subject: [PATCH 06/11] reset flag after execution --- contracts/src/Gateway.sol | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/contracts/src/Gateway.sol b/contracts/src/Gateway.sol index 69dc4e6576..fdd3445a4c 100644 --- a/contracts/src/Gateway.sol +++ b/contracts/src/Gateway.sol @@ -110,10 +110,20 @@ contract Gateway is IGateway, IInitializable, IUpgradable { modifier nonreentrant() { assembly { + // Check if flag is set and if true revert because it means the function is currently executing. if tload(0) { revert(0, 0) } + + // Set the flag to mark the the function is currently executing. tstore(0, 1) } + + // Execute the function here _; + + assembly { + // Reset the flag as the function has completed executing. + tstore(0, 0) + } } constructor( From e3a45632485f6d52fdc243b2f705851c4a648d80 Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Tue, 24 Dec 2024 22:11:52 +0200 Subject: [PATCH 07/11] better comments --- contracts/src/Gateway.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/src/Gateway.sol b/contracts/src/Gateway.sol index fdd3445a4c..6357550640 100644 --- a/contracts/src/Gateway.sol +++ b/contracts/src/Gateway.sol @@ -117,11 +117,11 @@ contract Gateway is IGateway, IInitializable, IUpgradable { tstore(0, 1) } - // Execute the function here + // Execute the function here. _; assembly { - // Reset the flag as the function has completed executing. + // Clear the flag as the function has completed execution. tstore(0, 0) } } From 36383afef36e655f39bc6ccde3957da090efbbd2 Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Tue, 24 Dec 2024 22:44:15 +0200 Subject: [PATCH 08/11] add reantrancy test --- contracts/test/Gateway.t.sol | 26 +++++++++++++++ contracts/test/mocks/ReantrantAttacker.sol | 39 ++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 contracts/test/mocks/ReantrantAttacker.sol diff --git a/contracts/test/Gateway.t.sol b/contracts/test/Gateway.t.sol index 951723d465..9af9ca7637 100644 --- a/contracts/test/Gateway.t.sol +++ b/contracts/test/Gateway.t.sol @@ -13,6 +13,7 @@ import {IUpgradable} from "../src/interfaces/IUpgradable.sol"; import {Gateway} from "../src/Gateway.sol"; import {MockGateway} from "./mocks/MockGateway.sol"; import {MockGatewayV2} from "./mocks/MockGatewayV2.sol"; +import {ReantrantAttacker} from "./mocks/ReantrantAttacker.sol"; import {GatewayProxy} from "../src/GatewayProxy.sol"; import {AgentExecutor} from "../src/AgentExecutor.sol"; @@ -1022,4 +1023,29 @@ contract GatewayTest is Test { vm.expectRevert(Assets.TokenAlreadyRegistered.selector); IGateway(address(gateway)).registerToken{value: fee}(dotToken); } + + function testReantrancyGuardReverts() public { + testRegisterToken(); + + ReantrantAttacker attacker = new ReantrantAttacker(address(gateway), address(token)); + // Fund attacker + deal(address(attacker), 1 ether); + deal(address(token), address(attacker), 1); + + uint128 amount = 1; + uint128 extra = 1; + uint128 destinationFee = 1; + ParaID paraID = ParaID.wrap(1000); + + uint128 fee = uint128(IGateway(address(gateway)).quoteSendTokenFee(address(token), paraID, 0)); + + hoax(address(attacker)); + token.approve(address(gateway), 1); + + vm.expectRevert(NativeTransferFailed.selector); + hoax(address(attacker)); + IGateway(address(gateway)).sendToken{value: fee + extra}( + address(token), paraID, recipientAddress32, destinationFee, amount + ); + } } diff --git a/contracts/test/mocks/ReantrantAttacker.sol b/contracts/test/mocks/ReantrantAttacker.sol new file mode 100644 index 0000000000..3adbea953c --- /dev/null +++ b/contracts/test/mocks/ReantrantAttacker.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.28; + +import {IGateway} from "../../src/interfaces/IGateway.sol"; +import {ParaID, MultiAddress, multiAddressFromBytes32} from "../../src/Types.sol"; +import {console} from "forge-std/console.sol"; + +contract ReantrantAttacker { + address public owner; + IGateway targetContract; + uint256 targetValue = 0.9 ether; + uint256 fee; + ParaID assetHub = ParaID.wrap(1000); + uint128 amount = 1; + uint128 extra = 1; + MultiAddress recipientAddress32 = multiAddressFromBytes32(keccak256("recipient")); + + constructor(address _targetAddr, address token) { + targetContract = IGateway(_targetAddr); + owner = msg.sender; + fee = targetContract.quoteSendTokenFee(token, assetHub, 0); + } + + function balance() public view returns (uint256) { + return address(this).balance; + } + + function withdrawAll() public returns (bool) { + require(msg.sender == owner, "my money!!"); + uint256 totalBalance = address(this).balance; + (bool sent,) = msg.sender.call{value: totalBalance}(""); + require(sent, "Failed to send Ether"); + return sent; + } + + receive() external payable { + targetContract.sendToken{value: amount + fee + extra}(address(0), assetHub, recipientAddress32, 1, amount); + } +} From 61481164a24ff79947decbf794b636b49f1fddab Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Wed, 8 Jan 2025 00:54:02 +0200 Subject: [PATCH 09/11] make DISPATCH_OVERHEAD_GAS constant --- contracts/src/Gateway.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/src/Gateway.sol b/contracts/src/Gateway.sol index 6357550640..c55dee2932 100644 --- a/contracts/src/Gateway.sol +++ b/contracts/src/Gateway.sol @@ -74,7 +74,7 @@ contract Gateway is IGateway, IInitializable, IUpgradable { // Gas used for: // 1. Mapping a command id to an implementation function // 2. Calling implementation function - uint256 DISPATCH_OVERHEAD_GAS = 10_000; + uint256 constant DISPATCH_OVERHEAD_GAS = 10_000; // The maximum fee that can be sent to a destination parachain to pay for execution (DOT). // Has two functions: From 266a35025b2e609af67fdcf81e01c15df43fce6c Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Wed, 8 Jan 2025 01:39:50 +0200 Subject: [PATCH 10/11] Add separate storage slot and library --- contracts/src/Gateway.sol | 18 ++++----------- contracts/src/utils/ReentrantGuard.sol | 26 ++++++++++++++++++++++ contracts/test/Gateway.t.sol | 4 ++-- contracts/test/mocks/ReantrantAttacker.sol | 8 ++++--- 4 files changed, 37 insertions(+), 19 deletions(-) create mode 100644 contracts/src/utils/ReentrantGuard.sol diff --git a/contracts/src/Gateway.sol b/contracts/src/Gateway.sol index c55dee2932..82724152e5 100644 --- a/contracts/src/Gateway.sol +++ b/contracts/src/Gateway.sol @@ -30,6 +30,7 @@ import {SafeNativeTransfer} from "./utils/SafeTransfer.sol"; import {Call} from "./utils/Call.sol"; import {Math} from "./utils/Math.sol"; import {ScaleCodec} from "./utils/ScaleCodec.sol"; +import {ReentrantGuard} from "./utils/ReentrantGuard.sol"; import { AgentExecuteParams, @@ -108,22 +109,11 @@ contract Gateway is IGateway, IInitializable, IUpgradable { _; } + // Makes sure that a method is non reentrant. modifier nonreentrant() { - assembly { - // Check if flag is set and if true revert because it means the function is currently executing. - if tload(0) { revert(0, 0) } - - // Set the flag to mark the the function is currently executing. - tstore(0, 1) - } - - // Execute the function here. + ReentrantGuard.checkAndSet(); _; - - assembly { - // Clear the flag as the function has completed execution. - tstore(0, 0) - } + ReentrantGuard.clear(); } constructor( diff --git a/contracts/src/utils/ReentrantGuard.sol b/contracts/src/utils/ReentrantGuard.sol new file mode 100644 index 0000000000..7683a1f644 --- /dev/null +++ b/contracts/src/utils/ReentrantGuard.sol @@ -0,0 +1,26 @@ +/// @title Library for implementing reantrancy guards. +library ReentrantGuard { + // Storage slot for the reantrancy guard derived by: + // keccak256(abi.encode(uint256(keccak256("snowbridge.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 private constant REENTRANCY_GUARD_STORAGE = + 0x2ba401b34c12923a4850086f5807d30f124be8a0a38cff4286ca87f38422f200; + + /// @dev checks if the reentrancy guard is set and reverts if so, else sets the guard. + function checkAndSet() internal { + assembly { + // Check if flag is set and if true revert because it means the function is currently executing. + if tload(REENTRANCY_GUARD_STORAGE) { revert(0, 0) } + + // Set the flag to mark the the function is currently executing. + tstore(REENTRANCY_GUARD_STORAGE, 1) + } + } + + /// @dev clears the reentrancy guard. + function clear() internal { + assembly { + // Clear the flag as the function has completed execution. + tstore(REENTRANCY_GUARD_STORAGE, 0) + } + } +} diff --git a/contracts/test/Gateway.t.sol b/contracts/test/Gateway.t.sol index 9af9ca7637..dbb36561bf 100644 --- a/contracts/test/Gateway.t.sol +++ b/contracts/test/Gateway.t.sol @@ -1030,7 +1030,7 @@ contract GatewayTest is Test { ReantrantAttacker attacker = new ReantrantAttacker(address(gateway), address(token)); // Fund attacker deal(address(attacker), 1 ether); - deal(address(token), address(attacker), 1); + deal(address(token), address(attacker), 5); uint128 amount = 1; uint128 extra = 1; @@ -1040,7 +1040,7 @@ contract GatewayTest is Test { uint128 fee = uint128(IGateway(address(gateway)).quoteSendTokenFee(address(token), paraID, 0)); hoax(address(attacker)); - token.approve(address(gateway), 1); + token.approve(address(gateway), 5); vm.expectRevert(NativeTransferFailed.selector); hoax(address(attacker)); diff --git a/contracts/test/mocks/ReantrantAttacker.sol b/contracts/test/mocks/ReantrantAttacker.sol index 3adbea953c..83f8aad8b5 100644 --- a/contracts/test/mocks/ReantrantAttacker.sol +++ b/contracts/test/mocks/ReantrantAttacker.sol @@ -7,6 +7,7 @@ import {console} from "forge-std/console.sol"; contract ReantrantAttacker { address public owner; + address token; IGateway targetContract; uint256 targetValue = 0.9 ether; uint256 fee; @@ -15,10 +16,11 @@ contract ReantrantAttacker { uint128 extra = 1; MultiAddress recipientAddress32 = multiAddressFromBytes32(keccak256("recipient")); - constructor(address _targetAddr, address token) { + constructor(address _targetAddr, address _token) { targetContract = IGateway(_targetAddr); owner = msg.sender; - fee = targetContract.quoteSendTokenFee(token, assetHub, 0); + token = _token; + fee = targetContract.quoteSendTokenFee(_token, assetHub, 0); } function balance() public view returns (uint256) { @@ -34,6 +36,6 @@ contract ReantrantAttacker { } receive() external payable { - targetContract.sendToken{value: amount + fee + extra}(address(0), assetHub, recipientAddress32, 1, amount); + targetContract.sendToken{value: amount + fee + extra}(token, assetHub, recipientAddress32, 1, amount); } } From 4ec8b973912ec1e8f26843655726d4e969ef7a5b Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Thu, 9 Jan 2025 13:59:54 +0200 Subject: [PATCH 11/11] revert custom storage slot --- contracts/src/Gateway.sol | 18 ++++++++++++++---- contracts/src/utils/ReentrantGuard.sol | 26 -------------------------- 2 files changed, 14 insertions(+), 30 deletions(-) delete mode 100644 contracts/src/utils/ReentrantGuard.sol diff --git a/contracts/src/Gateway.sol b/contracts/src/Gateway.sol index 82724152e5..c55dee2932 100644 --- a/contracts/src/Gateway.sol +++ b/contracts/src/Gateway.sol @@ -30,7 +30,6 @@ import {SafeNativeTransfer} from "./utils/SafeTransfer.sol"; import {Call} from "./utils/Call.sol"; import {Math} from "./utils/Math.sol"; import {ScaleCodec} from "./utils/ScaleCodec.sol"; -import {ReentrantGuard} from "./utils/ReentrantGuard.sol"; import { AgentExecuteParams, @@ -109,11 +108,22 @@ contract Gateway is IGateway, IInitializable, IUpgradable { _; } - // Makes sure that a method is non reentrant. modifier nonreentrant() { - ReentrantGuard.checkAndSet(); + assembly { + // Check if flag is set and if true revert because it means the function is currently executing. + if tload(0) { revert(0, 0) } + + // Set the flag to mark the the function is currently executing. + tstore(0, 1) + } + + // Execute the function here. _; - ReentrantGuard.clear(); + + assembly { + // Clear the flag as the function has completed execution. + tstore(0, 0) + } } constructor( diff --git a/contracts/src/utils/ReentrantGuard.sol b/contracts/src/utils/ReentrantGuard.sol deleted file mode 100644 index 7683a1f644..0000000000 --- a/contracts/src/utils/ReentrantGuard.sol +++ /dev/null @@ -1,26 +0,0 @@ -/// @title Library for implementing reantrancy guards. -library ReentrantGuard { - // Storage slot for the reantrancy guard derived by: - // keccak256(abi.encode(uint256(keccak256("snowbridge.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff)) - bytes32 private constant REENTRANCY_GUARD_STORAGE = - 0x2ba401b34c12923a4850086f5807d30f124be8a0a38cff4286ca87f38422f200; - - /// @dev checks if the reentrancy guard is set and reverts if so, else sets the guard. - function checkAndSet() internal { - assembly { - // Check if flag is set and if true revert because it means the function is currently executing. - if tload(REENTRANCY_GUARD_STORAGE) { revert(0, 0) } - - // Set the flag to mark the the function is currently executing. - tstore(REENTRANCY_GUARD_STORAGE, 1) - } - } - - /// @dev clears the reentrancy guard. - function clear() internal { - assembly { - // Clear the flag as the function has completed execution. - tstore(REENTRANCY_GUARD_STORAGE, 0) - } - } -}