diff --git a/contracts/foundry.toml b/contracts/foundry.toml index 639d0e08be..0f8b081f56 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,8 +13,12 @@ fs_permissions = [ ignored_error_codes = [ # DeployLocal.sol is never deployed 5574, + # tstore + 2394, ] +evm_version = 'Cancun' + [profile.production] via_ir = true 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..423be27602 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"; diff --git a/contracts/scripts/DeployLocal.sol b/contracts/scripts/DeployLocal.sol index 441ab9926c..4fd6be19ee 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"; 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..22d961cfe8 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"; diff --git a/contracts/scripts/westend/UpgradeShell.sol b/contracts/scripts/westend/UpgradeShell.sol index 01b9cc0cf4..7abe08546c 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"; 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..55a44bef39 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"; @@ -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/src/BeefyClient.sol b/contracts/src/BeefyClient.sol index adde28830b..a8632b26a1 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"; diff --git a/contracts/src/Gateway.sol b/contracts/src/Gateway.sol index 685627fe34..c55dee2932 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"; @@ -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: @@ -108,6 +108,24 @@ 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 { + // Clear the flag as the function has completed execution. + tstore(0, 0) + } + } + constructor( address beefyClient, address agentExecutor, @@ -137,7 +155,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 +455,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 +475,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..83b4c45ab7 100644 --- a/contracts/src/MultiAddress.sol +++ b/contracts/src/MultiAddress.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; using {isIndex, asIndex, isAddress32, asAddress32, isAddress20, asAddress20} for MultiAddress global; 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..21d108fed6 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"; diff --git a/contracts/src/SubstrateTypes.sol b/contracts/src/SubstrateTypes.sol index 296f32ce57..37033a94af 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"; diff --git a/contracts/src/Token.sol b/contracts/src/Token.sol index f66a9e34be..5fd5d22003 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"; diff --git a/contracts/src/TokenLib.sol b/contracts/src/TokenLib.sol index de21ea679f..060993a895 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"; diff --git a/contracts/src/Types.sol b/contracts/src/Types.sol index 02e8bd0acc..6d7ab930a6 100644 --- a/contracts/src/Types.sol +++ b/contracts/src/Types.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 { MultiAddress, multiAddressFromUint32, multiAddressFromBytes32, multiAddressFromBytes20 diff --git a/contracts/src/Upgrade.sol b/contracts/src/Upgrade.sol index 49e30702ee..8be1ebeb79 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"; diff --git a/contracts/src/Verification.sol b/contracts/src/Verification.sol index 186f7e5c8b..6ee500eba8 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"; diff --git a/contracts/src/interfaces/IERC20.sol b/contracts/src/interfaces/IERC20.sol index 5e921d62db..86ef990992 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. diff --git a/contracts/src/interfaces/IERC20Permit.sol b/contracts/src/interfaces/IERC20Permit.sol index bcd8163669..fb0a7ae9ce 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(); diff --git a/contracts/src/interfaces/IGateway.sol b/contracts/src/interfaces/IGateway.sol index 1657b73577..b2703d3144 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"; 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..da338ca3fd 100644 --- a/contracts/src/interfaces/IShell.sol +++ b/contracts/src/interfaces/IShell.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 IShell { error Unauthorized(); 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..acb2cbe082 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"; diff --git a/contracts/src/utils/Bits.sol b/contracts/src/utils/Bits.sol index 570a0b947c..1b85366ef4 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); diff --git a/contracts/src/utils/Call.sol b/contracts/src/utils/Call.sol index f4e78f667b..101fe317c0 100644 --- a/contracts/src/utils/Call.sol +++ b/contracts/src/utils/Call.sol @@ -1,7 +1,7 @@ // 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 { diff --git a/contracts/src/utils/ERC1967.sol b/contracts/src/utils/ERC1967.sol index 1bb2a349ba..da35daac79 100644 --- a/contracts/src/utils/ERC1967.sol +++ b/contracts/src/utils/ERC1967.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 Minimal implementation of ERC1967 storage slot library ERC1967 { diff --git a/contracts/src/utils/MMRProof.sol b/contracts/src/utils/MMRProof.sol index c3e0a89858..9f6259be6b 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(); 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..25f8544788 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"; diff --git a/contracts/src/utils/ScaleCodec.sol b/contracts/src/utils/ScaleCodec.sol index df9d19fc7e..1198580232 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(); diff --git a/contracts/src/utils/SubstrateMerkleProof.sol b/contracts/src/utils/SubstrateMerkleProof.sol index 2de609110f..762eec3351 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 { 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..a33cca6dcd 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"; diff --git a/contracts/test/BeefyClient.t.sol b/contracts/test/BeefyClient.t.sol index 42566ca4ec..d6028009a7 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"; diff --git a/contracts/test/Bitfield.t.sol b/contracts/test/Bitfield.t.sol index 2334e399a4..d0713a3c81 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"; diff --git a/contracts/test/ForkUpgrade.t.sol b/contracts/test/ForkUpgrade.t.sol index 5b1a6069dd..226d7f0621 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"; diff --git a/contracts/test/Gateway.t.sol b/contracts/test/Gateway.t.sol index 96705c5c9f..dbb36561bf 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"; @@ -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), 5); + + 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), 5); + + 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/MMRProof.t.sol b/contracts/test/MMRProof.t.sol index 61492b3b84..967abacfd4 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"; diff --git a/contracts/test/Math.t.sol b/contracts/test/Math.t.sol index 4506998a02..8f955e3e39 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"; diff --git a/contracts/test/ScaleCodec.t.sol b/contracts/test/ScaleCodec.t.sol index ebe1a94856..87e1c31627 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"; 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..667837623b 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"; diff --git a/contracts/test/mocks/BeefyClientMock.sol b/contracts/test/mocks/BeefyClientMock.sol index 40caee279b..3e34f75063 100644 --- a/contracts/test/mocks/BeefyClientMock.sol +++ b/contracts/test/mocks/BeefyClientMock.sol @@ -1,5 +1,5 @@ // 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"; 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..25efcff74d 100644 --- a/contracts/test/mocks/MMRProofWrapper.sol +++ b/contracts/test/mocks/MMRProofWrapper.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {MMRProof} from "../../src/utils/MMRProof.sol"; diff --git a/contracts/test/mocks/MockGateway.sol b/contracts/test/mocks/MockGateway.sol index 4356bb9876..03c28db968 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"; 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/ReantrantAttacker.sol b/contracts/test/mocks/ReantrantAttacker.sol new file mode 100644 index 0000000000..83f8aad8b5 --- /dev/null +++ b/contracts/test/mocks/ReantrantAttacker.sol @@ -0,0 +1,41 @@ +// 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; + address token; + 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; + token = _token; + 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}(token, assetHub, recipientAddress32, 1, amount); + } +} diff --git a/contracts/test/mocks/VerificationWrapper.sol b/contracts/test/mocks/VerificationWrapper.sol index 7618bb78c8..b86f2a268e 100644 --- a/contracts/test/mocks/VerificationWrapper.sol +++ b/contracts/test/mocks/VerificationWrapper.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.25; +pragma solidity 0.8.28; import {Verification} from "../../src/Verification.sol";