├── .gitmodules ├── remappings.txt ├── .gitignore ├── contracts ├── IVotable.sol ├── IAllo.sol ├── IDAIPermit.sol ├── mocks │ ├── MockERC20Permit.sol │ ├── MockVotingStrategy.sol │ ├── MockRoundImplementationETH.sol │ ├── SigUtils.sol │ ├── MockRoundImplementationERC20.sol │ └── MockRoundImplementationDAI.sol ├── tokens │ ├── TestERC20.sol │ └── TestDAI.sol ├── utils │ ├── SigUtils.sol │ └── SigUtilsDAI.sol └── beta-rounds │ ├── IBetaRoundsRoundImplementation.sol │ └── IBetaRoundsVotingStrategy.sol ├── tsconfig.json ├── zksync.md ├── test ├── MRC.t.sol ├── MRCVote.t.sol ├── MRCVoteERC20Permit.t.sol └── MRCVoteDAIPermit.t.sol ├── package.json ├── lib └── utils.ts ├── era.hardhat.config.ts ├── scripts ├── deploy │ ├── upgrade.ts │ ├── init.ts │ ├── deploy.ts │ └── transferOwnership.ts └── benchmarks │ └── deploy-bench.ts ├── deploy └── deployZkSync.ts ├── .env.example ├── README.md ├── .openzeppelin ├── unknown-424.json ├── arbitrum-goerli.json ├── unknown-58008.json ├── unknown-84531.json ├── unknown-534351.json ├── celo.json ├── kovan.json ├── celo-alfajores.json ├── unknown-100.json ├── unknown-1088.json ├── unknown-1329.json ├── unknown-295.json ├── unknown-4201.json ├── unknown-713715.json ├── unknown-314159.json ├── mainnet.json ├── optimism.json ├── polygon.json ├── arbitrum-one.json ├── avalanche.json ├── unknown-250.json └── unknown-4002.json ├── .upgradable ├── zkSync-testnet.json └── zkSync-testnet-sepolia.json └── hardhat.config.ts /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/forge-std"] 2 | path = lib/forge-std 3 | url = https://github.com/foundry-rs/forge-std 4 | -------------------------------------------------------------------------------- /remappings.txt: -------------------------------------------------------------------------------- 1 | @openzeppelin/contracts=node_modules/@openzeppelin/contracts 2 | @openzeppelin/contracts-upgradeable=node_modules/@openzeppelin/contracts-upgradeable 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | coverage 4 | coverage.json 5 | typechain 6 | typechain-types 7 | 8 | # Hardhat files 9 | cache 10 | cache-zk 11 | artifacts 12 | artifacts-zk 13 | 14 | /out/ 15 | 16 | fork-beta-rounds.sh 17 | -------------------------------------------------------------------------------- /contracts/IVotable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: AGPL-3.0-only 2 | pragma solidity ^0.8.17; 3 | 4 | abstract contract IVotable { 5 | address public votingStrategy; 6 | 7 | function vote(bytes[] memory data) external payable virtual; 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "skipLibCheck": true, 9 | "resolveJsonModule": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /contracts/IAllo.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: AGPL-3.0-only 2 | pragma solidity ^0.8.17; 3 | 4 | abstract contract IAllo { 5 | function getStrategy(uint256 _poolId) external view virtual returns (address); 6 | function allocate(uint256 _poolId, bytes memory _data) external payable virtual; 7 | } 8 | -------------------------------------------------------------------------------- /contracts/IDAIPermit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: AGPL-3.0-only 2 | pragma solidity ^0.8.17; 3 | 4 | interface IDAIPermit { 5 | function permit( 6 | address holder, 7 | address spender, 8 | uint256 nonce, 9 | uint256 expiry, 10 | bool allowed, 11 | uint8 v, 12 | bytes32 r, 13 | bytes32 s 14 | ) external; 15 | } 16 | -------------------------------------------------------------------------------- /contracts/mocks/MockERC20Permit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.17; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; 5 | 6 | contract MockERC20Permit is ERC20, ERC20Permit { 7 | constructor(string memory name, string memory symbol) ERC20(name, symbol) ERC20Permit(name) {} 8 | 9 | function mint(address to, uint256 amount) public { 10 | _mint(to, amount); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /contracts/tokens/TestERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.17; 3 | 4 | import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; 5 | 6 | contract TestERC20 is ERC20PermitUpgradeable { 7 | function initialize(string memory name, string memory symbol) public initializer { 8 | __ERC20_init(name, symbol); 9 | } 10 | 11 | function mint(address to, uint256 amount) public { 12 | _mint(to, amount); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /contracts/mocks/MockVotingStrategy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.17; 3 | 4 | import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; 5 | 6 | contract MockVotingStrategy { 7 | function vote(bytes[] memory _votes, address _voterAddress) external payable { 8 | for (uint256 i = 0; i < _votes.length; i++) { 9 | (address _token, uint256 _amount) = abi.decode(_votes[i], (address, uint256)); 10 | IERC20Upgradeable(_token).transferFrom(_voterAddress, address(this), _amount); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /zksync.md: -------------------------------------------------------------------------------- 1 | ## Deployment on zkSync Era Testnet 2 | 3 | **Compile** 4 | `npx hardhat compile --network zkSyncTestnet --config era.hardhat.config.ts ` 5 | 6 | **Deploy** 7 | `npx hardhat deploy-zksync --network zkSyncTestnet --config era.hardhat.config.ts --script deployZkSync.ts` 8 | 9 | **Verify** 10 | `npx hardhat verify --network zkSyncTestnet --config era.hardhat.config.ts 0x..` 11 | 12 | ## Deployment on zkSync Era Mainnet 13 | 14 | **Compile** 15 | `npx hardhat compile --network zkSyncMainnet --config era.hardhat.config.ts ` 16 | 17 | **Deploy** 18 | `npx hardhat deploy-zksync --network zkSyncMainnet --config era.hardhat.config.ts --script deployZkSync.ts` 19 | 20 | **Verify** 21 | `npx hardhat verify --network zkSyncMainnet --config era.hardhat.config.ts 0x..` -------------------------------------------------------------------------------- /test/MRC.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.17; 3 | 4 | import "forge-std/Test.sol"; 5 | import "../contracts/MultiRoundCheckout.sol"; 6 | 7 | contract MrcTestVote is Test { 8 | MultiRoundCheckout private mrc; 9 | 10 | function setUp() public { 11 | mrc = new MultiRoundCheckout(); 12 | mrc.initialize(address(1)); 13 | } 14 | 15 | function testOwnership() public { 16 | assertEq(mrc.owner(), address(this)); 17 | } 18 | 19 | function testPauseOnlyOwner() public { 20 | vm.prank(address(0x0)); 21 | vm.expectRevert(bytes("Ownable: caller is not the owner")); 22 | mrc.pause(); 23 | } 24 | 25 | function testUnpauseOnlyOwner() public { 26 | vm.prank(address(0x0)); 27 | vm.expectRevert(bytes("Ownable: caller is not the owner")); 28 | mrc.unpause(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "y", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "@matterlabs/hardhat-zksync-deploy": "^1.2.1", 13 | "@matterlabs/hardhat-zksync-solc": "^1.1.4", 14 | "@matterlabs/hardhat-zksync-upgradable": "^1.3.1", 15 | "@matterlabs/hardhat-zksync-verify": "^1.4.1", 16 | "@nomicfoundation/hardhat-foundry": "^1.0.2", 17 | "@nomicfoundation/hardhat-ledger": "^1.0.1", 18 | "@nomicfoundation/hardhat-toolbox": "^3.0.0", 19 | "@openzeppelin/hardhat-upgrades": "^2.0.1", 20 | "@xyrusworx/hardhat-solidity-json": "^1.0.2", 21 | "ethers": "^6.8.1", 22 | "hardhat": "^2.16.1", 23 | "zksync-ethers": "^6.7.1" 24 | }, 25 | "dependencies": { 26 | "@openzeppelin/contracts": "^4.9.2", 27 | "@openzeppelin/contracts-upgradeable": "^4.9.2", 28 | "dotenv": "^16.3.1" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /contracts/mocks/MockRoundImplementationETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.17; 3 | 4 | import "../MultiRoundCheckout.sol"; 5 | 6 | contract MockRoundImplementationETH is IVotable { 7 | bytes[] public receivedVotes; 8 | bool public tryReentrancy; 9 | 10 | function setReentrant(bool _tryReentrancy) public { 11 | tryReentrancy = _tryReentrancy; 12 | } 13 | 14 | function vote(bytes[] memory data) external payable override { 15 | if (tryReentrancy) { 16 | address[] memory rounds = new address[](1); 17 | bytes[][] memory votes = new bytes[][](1); 18 | uint256[] memory amounts = new uint256[](1); 19 | rounds[0] = address(this); 20 | votes[0] = data; 21 | amounts[0] = msg.value; 22 | MultiRoundCheckout(msg.sender).vote{value: msg.value}(votes, rounds, amounts); 23 | } 24 | receivedVotes = data; 25 | } 26 | 27 | function getReceivedVotes() public view returns (bytes[] memory) { 28 | return receivedVotes; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/utils.ts: -------------------------------------------------------------------------------- 1 | const rl = require("readline"); 2 | const { BigNumber } = require("@ethersproject/bignumber"); 3 | 4 | const BN = (n: any) => BigNumber.from(n.toString()); 5 | 6 | export const prompt = async (question: string) => { 7 | const r = rl.createInterface({ 8 | input: process.stdin, 9 | output: process.stdout, 10 | terminal: false, 11 | }); 12 | 13 | const answer = await new Promise((resolve, error) => { 14 | r.question(`${question} [y/n]: `, (answer: string) => { 15 | r.close(); 16 | resolve(answer); 17 | }); 18 | }); 19 | 20 | if (answer !== "y" && answer !== "yes") { 21 | console.log("exiting..."); 22 | process.exit(1); 23 | } 24 | 25 | console.log(); 26 | }; 27 | 28 | // pretty number 29 | export const pn = (n: bigint | string) => 30 | n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, "_"); 31 | 32 | export const getEnv = (name: string, defaultValue?: string) => { 33 | const value = process.env[name]; 34 | 35 | if (value === undefined || value === "") { 36 | if (defaultValue !== undefined) { 37 | return defaultValue; 38 | } 39 | 40 | throw new Error(`envrionment variable ${name} is not set`); 41 | } 42 | 43 | return value; 44 | }; 45 | -------------------------------------------------------------------------------- /contracts/mocks/SigUtils.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.17; 3 | 4 | contract SigUtils { 5 | bytes32 internal DOMAIN_SEPARATOR; 6 | 7 | constructor(bytes32 _DOMAIN_SEPARATOR) { 8 | DOMAIN_SEPARATOR = _DOMAIN_SEPARATOR; 9 | } 10 | 11 | // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); 12 | bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; 13 | 14 | struct Permit { 15 | address owner; 16 | address spender; 17 | uint256 value; 18 | uint256 nonce; 19 | uint256 deadline; 20 | } 21 | 22 | // computes the hash of a permit 23 | function getStructHash(Permit memory _permit) internal pure returns (bytes32) { 24 | return keccak256( 25 | abi.encode(PERMIT_TYPEHASH, _permit.owner, _permit.spender, _permit.value, _permit.nonce, _permit.deadline) 26 | ); 27 | } 28 | 29 | // computes the hash of the fully encoded EIP-712 message for the domain, which can be used to recover the signer 30 | function getTypedDataHash(Permit memory _permit) public view returns (bytes32) { 31 | return keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, getStructHash(_permit))); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/utils/SigUtils.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.17; 3 | 4 | contract SigUtils { 5 | bytes32 internal DOMAIN_SEPARATOR; 6 | 7 | constructor(bytes32 _DOMAIN_SEPARATOR) { 8 | DOMAIN_SEPARATOR = _DOMAIN_SEPARATOR; 9 | } 10 | 11 | // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); 12 | bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; 13 | 14 | struct Permit { 15 | address owner; 16 | address spender; 17 | uint256 value; 18 | uint256 nonce; 19 | uint256 deadline; 20 | } 21 | 22 | // computes the hash of a permit 23 | function getStructHash(Permit memory _permit) internal pure returns (bytes32) { 24 | return keccak256( 25 | abi.encode(PERMIT_TYPEHASH, _permit.owner, _permit.spender, _permit.value, _permit.nonce, _permit.deadline) 26 | ); 27 | } 28 | 29 | // computes the hash of the fully encoded EIP-712 message for the domain, which can be used to recover the signer 30 | function getTypedDataHash(Permit memory _permit) public view returns (bytes32) { 31 | return keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, getStructHash(_permit))); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/utils/SigUtilsDAI.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.17; 3 | 4 | contract SigUtilsDAI { 5 | bytes32 internal DOMAIN_SEPARATOR; 6 | 7 | constructor(bytes32 _DOMAIN_SEPARATOR) { 8 | DOMAIN_SEPARATOR = _DOMAIN_SEPARATOR; 9 | } 10 | 11 | // bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)"); 12 | bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb; 13 | 14 | struct Permit { 15 | address holder; 16 | address spender; 17 | uint256 nonce; 18 | uint256 expiry; 19 | bool allowed; 20 | } 21 | 22 | // computes the hash of a permit 23 | function getStructHash(Permit memory _permit) internal pure returns (bytes32) { 24 | return keccak256( 25 | abi.encode(PERMIT_TYPEHASH, _permit.holder, _permit.spender, _permit.nonce, _permit.expiry, _permit.allowed) 26 | ); 27 | } 28 | 29 | // computes the hash of the fully encoded EIP-712 message for the domain, which can be used to recover the signer 30 | function getTypedDataHash(Permit memory _permit) public view returns (bytes32) { 31 | return keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, getStructHash(_permit))); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/mocks/MockRoundImplementationERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.17; 3 | 4 | import "../MultiRoundCheckout.sol"; 5 | import "./MockVotingStrategy.sol"; 6 | 7 | contract MockRoundImplementationERC20 is IVotable { 8 | bytes[] public receivedVotes; 9 | bool public tryReentrancy; 10 | 11 | constructor(address _votingStrategy) { 12 | votingStrategy = _votingStrategy; 13 | } 14 | 15 | function setReentrant(bool _tryReentrancy) public { 16 | tryReentrancy = _tryReentrancy; 17 | } 18 | 19 | function vote(bytes[] memory data) external payable override { 20 | if (tryReentrancy) { 21 | address[] memory rounds = new address[](1); 22 | bytes[][] memory votes = new bytes[][](1); 23 | uint256[] memory amounts = new uint256[](1); 24 | uint256 totalAmount = msg.value; 25 | address token = address(this); 26 | uint8 v = 0; 27 | bytes32 r = 0; 28 | bytes32 s = 0; 29 | rounds[0] = address(this); 30 | votes[0] = data; 31 | amounts[0] = msg.value; 32 | MultiRoundCheckout(msg.sender).voteERC20Permit( 33 | votes, rounds, amounts, totalAmount, token, type(uint256).max, v, r, s 34 | ); 35 | } 36 | receivedVotes = data; 37 | MockVotingStrategy(votingStrategy).vote(data, msg.sender); 38 | } 39 | 40 | function getReceivedVotes() public view returns (bytes[] memory) { 41 | return receivedVotes; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /contracts/mocks/MockRoundImplementationDAI.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.17; 3 | 4 | import "../MultiRoundCheckout.sol"; 5 | import "./MockVotingStrategy.sol"; 6 | 7 | contract MockRoundImplementationDAI is IVotable { 8 | bytes[] public receivedVotes; 9 | bool public tryReentrancy; 10 | 11 | constructor(address _votingStrategy) { 12 | votingStrategy = _votingStrategy; 13 | } 14 | 15 | function setReentrant(bool _tryReentrancy) public { 16 | tryReentrancy = _tryReentrancy; 17 | } 18 | 19 | function vote(bytes[] memory data) external payable override { 20 | if (tryReentrancy) { 21 | address[] memory rounds = new address[](1); 22 | bytes[][] memory votes = new bytes[][](1); 23 | uint256[] memory amounts = new uint256[](1); 24 | uint256 totalAmount = msg.value; 25 | address token = address(this); 26 | uint256 nonce = 0; 27 | uint8 v = 0; 28 | bytes32 r = 0; 29 | bytes32 s = 0; 30 | rounds[0] = address(this); 31 | votes[0] = data; 32 | amounts[0] = msg.value; 33 | MultiRoundCheckout(msg.sender).voteDAIPermit( 34 | votes, rounds, amounts, totalAmount, token, type(uint256).max, nonce, v, r, s 35 | ); 36 | } 37 | receivedVotes = data; 38 | MockVotingStrategy(votingStrategy).vote(data, msg.sender); 39 | } 40 | 41 | function getReceivedVotes() public view returns (bytes[] memory) { 42 | return receivedVotes; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /era.hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from "dotenv"; 2 | 3 | import "@nomicfoundation/hardhat-foundry"; 4 | import "@matterlabs/hardhat-zksync-verify"; 5 | import "@matterlabs/hardhat-zksync-deploy"; 6 | import "@matterlabs/hardhat-zksync-solc"; 7 | import "@matterlabs/hardhat-zksync-upgradable"; 8 | import "@typechain/hardhat"; 9 | import { HardhatUserConfig } from "hardhat/config"; 10 | 11 | dotenv.config(); 12 | 13 | let deployPrivateKey = process.env.PRIVATE_KEY as string; 14 | if (!deployPrivateKey) { 15 | // default first account deterministically created by local nodes like `npx hardhat node` or `anvil` 16 | throw "No deployer private key set in .env"; 17 | } 18 | 19 | 20 | /** 21 | * Generates hardhat network configuration 22 | * @type import('hardhat/config').HardhatUserConfig 23 | */ 24 | const config: HardhatUserConfig = { 25 | solidity: { 26 | version: "0.8.19", 27 | settings: { 28 | optimizer: { 29 | enabled: true, 30 | runs: 400, 31 | }, 32 | }, 33 | // @ts-ignore 34 | }, 35 | networks: { 36 | zkSyncTestnet: { 37 | url: "https://sepolia.era.zksync.dev", 38 | ethNetwork: "sepolia", 39 | zksync: true, 40 | verifyURL: "https://explorer.sepolia.era.zksync.dev/contract_verification", 41 | chainId: 300 42 | }, 43 | zkSyncMainnet: { 44 | url: "https://mainnet.era.zksync.io", 45 | ethNetwork: "mainnet", 46 | zksync: true, 47 | verifyURL: "https://zksync2-mainnet-explorer.zksync.io/contract_verification", 48 | chainId: 324 49 | }, 50 | }, 51 | paths: { 52 | sources: "./contracts", 53 | cache: "./cache_hardhat", 54 | }, 55 | zksolc: { 56 | version: "latest", 57 | settings: {}, 58 | }, 59 | }; 60 | 61 | export default config; -------------------------------------------------------------------------------- /contracts/beta-rounds/IBetaRoundsRoundImplementation.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: AGPL-3.0-only 2 | pragma solidity ^0.8.17; 3 | 4 | struct MetaPtr { 5 | uint256 protocol; 6 | string pointer; 7 | } 8 | 9 | interface IBetaRoundsRoundImplementation { 10 | struct ApplicationStatus { 11 | uint256 index; 12 | uint256 statusRow; 13 | } 14 | 15 | function initialize(bytes calldata encodedParameters, address _alloSettings) external; 16 | 17 | function votingStrategy() external view returns (address); 18 | 19 | function updateMatchAmount(uint256 newAmount) external; 20 | 21 | function updateRoundFeePercentage(uint32 newFeePercentage) external; 22 | 23 | function updateRoundFeeAddress(address payable newFeeAddress) external; 24 | 25 | function updateRoundMetaPtr(MetaPtr memory newRoundMetaPtr) external; 26 | 27 | function updateApplicationMetaPtr(MetaPtr memory newApplicationMetaPtr) external; 28 | 29 | function updateStartAndEndTimes( 30 | uint256 newApplicationsStartTime, 31 | uint256 newApplicationsEndTime, 32 | uint256 newRoundStartTime, 33 | uint256 newRoundEndTime 34 | ) external; 35 | 36 | function applyToRound(bytes32 projectID, MetaPtr calldata newApplicationMetaPtr) external; 37 | 38 | function getApplicationIndexesByProjectID(bytes32 projectID) external view returns (uint256[] memory); 39 | 40 | function setApplicationStatuses(ApplicationStatus[] memory statuses) external; 41 | 42 | function getApplicationStatus(uint256 applicationIndex) external view returns (uint256); 43 | 44 | function vote(bytes[] memory encodedVotes) external payable; 45 | 46 | function setReadyForPayout() external payable; 47 | 48 | function withdraw(address tokenAddress, address payable recipent) external; 49 | } 50 | -------------------------------------------------------------------------------- /scripts/deploy/upgrade.ts: -------------------------------------------------------------------------------- 1 | import hre, { ethers, upgrades } from "hardhat"; 2 | import { pn, prompt } from "../../lib/utils"; 3 | import { getEnv } from "../../lib/utils"; 4 | 5 | async function main() { 6 | const network = await ethers.provider.getNetwork(); 7 | const networkName = hre.network.name; 8 | const allo = "0x1133eA7Af70876e64665ecD07C0A0476d09465a1"; 9 | const MRC_PROXY_ADDRESS = ""; // TODO: Upgrade the MultiRoundCheckout contract 10 | 11 | let account; 12 | let accountAddress; 13 | 14 | if (process.env.USE_HARDWARE_WALLET === "true") { 15 | // with hardware wallet 16 | console.log("Waiting for hardware wallet to connect..."); 17 | // account = new LedgerSigner(ethers.provider); 18 | account = await ethers.getSigner(getEnv("HARDWARE_WALLET_ACCOUNT")); 19 | } else { 20 | // default without hardware wallet 21 | account = (await ethers.getSigners())[0]; 22 | } 23 | 24 | accountAddress = account.address; 25 | const balance = await ethers.provider.getBalance(accountAddress); 26 | 27 | console.log(`chainId: ${network.chainId}`); 28 | console.log(`network: ${networkName} (from ethers: ${network.name})`); 29 | console.log(`account: ${accountAddress}`); 30 | console.log(`balance: ${pn(balance.toString())}`); 31 | 32 | await prompt("do you want to upgrade the MultiRoundCheckout contract?"); 33 | 34 | console.log("Upgrading MultiRoundCheckout..."); 35 | 36 | const newMultiRoundCheckout = await ethers.getContractFactory( 37 | "MultiRoundCheckout" 38 | ); 39 | 40 | await upgrades.upgradeProxy(MRC_PROXY_ADDRESS, newMultiRoundCheckout, { 41 | unsafeAllowRenames: true, 42 | call: { fn: "initialize", args: [allo] }, 43 | }); 44 | 45 | console.log("MultiRoundCheckout upgraded"); 46 | } 47 | 48 | // We recommend this pattern to be able to use async/await everywhere 49 | // and properly handle errors. 50 | main().catch((error) => { 51 | console.error(error); 52 | process.exitCode = 1; 53 | }); 54 | -------------------------------------------------------------------------------- /deploy/deployZkSync.ts: -------------------------------------------------------------------------------- 1 | import * as hre from "hardhat"; 2 | import * as dotenv from "dotenv"; 3 | import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; 4 | import { Wallet } from "zksync-ethers"; 5 | 6 | dotenv.config(); 7 | 8 | export default async function () { 9 | const network = await hre.network.config; 10 | const networkName = await hre.network.name; 11 | const chainId = Number(network.chainId); 12 | 13 | const ALLO_ADDRESS = "0x9D1D1BF2835935C291C0f5228c86d5C4e235A249"; 14 | 15 | const deployerAddress = new Wallet( 16 | process.env.PRIVATE_KEY as string 17 | ); 18 | 19 | console.log(` 20 | //////////////////////////////////////////////////// 21 | Deploys MultiRoundCheckout.sol on ${networkName} 22 | ////////////////////////////////////////////////////` 23 | ); 24 | 25 | console.table({ 26 | contract: "MultiRoundCheckout.sol", 27 | chainId: chainId, 28 | network: networkName, 29 | allo: ALLO_ADDRESS 30 | }); 31 | 32 | console.log("Deploying MultiRoundCheckout..."); 33 | 34 | const deployer = new Deployer(hre, deployerAddress); 35 | const MultiRoundCheckout = await deployer.loadArtifact("MultiRoundCheckout"); 36 | const instance = await hre.zkUpgrades.deployProxy( 37 | deployer.zkWallet, 38 | MultiRoundCheckout, 39 | [ 40 | ALLO_ADDRESS 41 | ], 42 | { initializer: "initialize" } 43 | ); 44 | 45 | await instance.waitForDeployment(); 46 | const proxyContractAddress = await instance.getAddress(); 47 | 48 | console.log("MultiRoundCheckout deployed to:", proxyContractAddress); 49 | 50 | await hre.run("verify:verify", { 51 | address: proxyContractAddress.toString(), 52 | constructorArguments: [], 53 | noCompile: true, 54 | }); 55 | 56 | return proxyContractAddress; 57 | } 58 | 59 | 60 | // Note: Deploy script to run in terminal: 61 | // npx hardhat compile --network zkSyncTestnet --config era.hardhat.config.ts 62 | // npx hardhat deploy-zksync --network zkSyncTestnet --config era.hardhat.config.ts --script deployZkSync.ts -------------------------------------------------------------------------------- /scripts/deploy/init.ts: -------------------------------------------------------------------------------- 1 | import hre, { ethers, upgrades } from "hardhat"; 2 | import { pn, prompt } from "../../lib/utils"; 3 | import { getEnv } from "../../lib/utils"; 4 | 5 | // Script used to initialize implementation contracts to avoid 6 | // having them deployed and not initialized even if they are 7 | // not used directly. 8 | 9 | const CONTRACT_ADDRESS = ""; 10 | const allo = "0x1133eA7Af70876e64665ecD07C0A0476d09465a1"; 11 | 12 | async function main() { 13 | const network = await ethers.provider.getNetwork(); 14 | const networkName = hre.network.name; 15 | let account; 16 | let accountAddress; 17 | 18 | if (process.env.USE_HARDWARE_WALLET === "true") { 19 | // with hardware wallet 20 | console.log("Waiting for hardware wallet to connect..."); 21 | // account = new LedgerSigner(ethers.provider); 22 | account = await ethers.getSigner(getEnv("HARDWARE_WALLET_ACCOUNT")); 23 | } else { 24 | // default without hardware wallet 25 | account = (await ethers.getSigners())[0]; 26 | } 27 | 28 | accountAddress = account.address; 29 | const balance = await ethers.provider.getBalance(accountAddress); 30 | 31 | console.log(`chainId: ${network.chainId}`); 32 | console.log(`network: ${networkName} (from ethers: ${network.name})`); 33 | console.log(`account: ${accountAddress}`); 34 | console.log(`balance: ${pn(balance.toString())}`); 35 | 36 | await prompt(`do you want to initial the contract at ${CONTRACT_ADDRESS}?`); 37 | console.log("init..."); 38 | 39 | const implementation = await ethers.getContractAt( 40 | "MultiRoundCheckout", 41 | CONTRACT_ADDRESS, 42 | account, 43 | ); 44 | const tx = await implementation.initialize(allo); 45 | const rec = await tx.wait(); 46 | if (rec === null) { 47 | console.error("cannot fetch receipt"); 48 | return; 49 | } 50 | 51 | console.log("tx hash", tx.hash); 52 | const gas = pn(rec.gasUsed.toString()); 53 | console.log(`gas used: ${gas}`); 54 | } 55 | 56 | // We recommend this pattern to be able to use async/await everywhere 57 | // and properly handle errors. 58 | main().catch((error) => { 59 | console.error(error); 60 | process.exitCode = 1; 61 | }); 62 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | MNEMONIC="test test test test" 2 | PRIVATE_KEY="0x000" 3 | 4 | USE_HARDWARE_WALLET=false 5 | HARDWARE_WALLET_ACCOUNT=__ADDRESS__ 6 | 7 | ETHERSCAN_OPTIMISM_API_KEY=__API_KEY__ 8 | ETHERSCAN_ETHEREUM_API_KEY=__API_KEY__ 9 | ETHERSCAN_FANTOM_API_KEY=__API_KEY__ 10 | ETHERSCAN_POLYGON_API_KEY=__API_KEY__ 11 | ETHERSCAN_AVALANCHE_API_KEY=__API_KEY__ 12 | ETHERSCAN_BASE_API_KEY=__API_KEY__ 13 | ETHERSCAN_SCROLL_API_KEY=__API_KEY__ 14 | ETHERSCAN_ARBITRUM_API_KEY=__API_KEY__ 15 | GNOSISSCAN_API_KEY=__API_KEY__ 16 | HEDERA_API_KEY=__API_KEY__ 17 | 18 | PGN_TESTNET_RPC_URL=https://sepolia.publicgoods.network/ 19 | ARBITRUM_TESTNET_RPC_URL=https://arbitrum-goerli.publicnode.com 20 | POLYGON_MUMBAI_RPC_URL=https://rpc-mumbai.maticvigil.com 21 | AVALANCHE_FUJI_RPC_URL=https://api.avax-test.network/ext/bc/C/rpc 22 | FANTOM_TESTNET_RPC_URL=https://rpc.testnet.fantom.network/ 23 | SEPOLIA_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/__API_KEY__ 24 | BASE_SEPOLIA_RPC_URL=https://sepolia.base.org 25 | BASE_GOERLI_RPC_URL=https://goerli.base.org 26 | ZKSYNC_ERA_GOERLI_RPC_URL=https://testnet.era.zksync.dev 27 | SCROLL_SEPOLIA_RPC_URL=https://sepolia-rpc.scroll.io 28 | 29 | PGN_RPC_URL=https://rpc.publicgoods.network 30 | OPTIMISM_RPC_URL=https://mainnet.optimism.io 31 | FANTOM_RPC_URL=https://rpc.ankr.com/fantom 32 | MAINNET_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/__API_KEY__ 33 | ARBITRUM_ONE_RPC_URL=https://arb1.arbitrum.io/rpc 34 | POLYGON_RPC_URL=https://polygon-rpc.com 35 | AVALANCHE_RPC_URL=https://api.avax.network/ext/bc/C/rpc 36 | BASE_RPC_URL=https://mainnet.base.org 37 | ZKSYNC_ERA_RPC_URL=https://mainnet.era.zksync.io 38 | SCROLL_RPC_URL=https://rpc.scroll.io 39 | 40 | SEI_DEVNET_RPC_URL=https://evm-rpc-arctic-1.sei-apis.com 41 | SEI_RPC_URL=https://evm-rpc.sei-apis.com 42 | CELO_RPC_URL=https://1rpc.io/celo 43 | CELO_ALFAJORES_RPC_URL=https://alfajores-forno.celo-testnet.org 44 | FILECOIN_RPC_URL=https://filecoin.drpc.org 45 | FILECOIN_TESTNET_RPC_URL=https://rpc.ankr.com/filecoin_testnet 46 | LUKSO_RPC_URL=https://rpc.mainnet.lukso.network 47 | LUKSO_TESTNET_RPC_URL=https://rpc.testnet.lukso.network 48 | METIS_MAINNET_RPC_URL=https://andromeda.metis.io/?owner=1088 49 | GNOSIS_RPC_URL=https://rpc.gnosischain.com 50 | HEDERA_RPC_URL=https://mainnet.hashio.io/api -------------------------------------------------------------------------------- /scripts/deploy/deploy.ts: -------------------------------------------------------------------------------- 1 | import hre, { ethers, upgrades } from "hardhat"; 2 | import { pn, prompt } from "../../lib/utils"; 3 | import { getEnv } from "../../lib/utils"; 4 | 5 | async function main() { 6 | const network = await ethers.provider.getNetwork(); 7 | const networkName = hre.network.name; 8 | const allo = "0x1133eA7Af70876e64665ecD07C0A0476d09465a1"; 9 | 10 | let account; 11 | let accountAddress; 12 | 13 | if (process.env.USE_HARDWARE_WALLET === "true") { 14 | // with hardware wallet 15 | console.log("Waiting for hardware wallet to connect..."); 16 | // account = new LedgerSigner(ethers.provider); 17 | account = await ethers.getSigner(getEnv("HARDWARE_WALLET_ACCOUNT")); 18 | } else { 19 | // default without hardware wallet 20 | account = (await ethers.getSigners())[0]; 21 | } 22 | 23 | accountAddress = account.address; 24 | const balance = await ethers.provider.getBalance(accountAddress); 25 | 26 | console.log(`chainId: ${network.chainId}`); 27 | console.log(`network: ${networkName} (from ethers: ${network.name})`); 28 | console.log(`account: ${accountAddress}`); 29 | console.log(`balance: ${pn(balance.toString())}`); 30 | 31 | await prompt("do you want to deploy the MultiRoundCheckout contract?"); 32 | console.log("deploying..."); 33 | 34 | const MultiRoundCheckout = await ethers.getContractFactory( 35 | "MultiRoundCheckout", 36 | account, 37 | ); 38 | const instance = await upgrades.deployProxy(MultiRoundCheckout, [allo]); 39 | await instance.waitForDeployment(); 40 | 41 | const tx = instance.deploymentTransaction(); 42 | if (tx === null) { 43 | console.error("cannot fetch deployTransaction"); 44 | return; 45 | } 46 | 47 | const rec = await tx.wait(); 48 | if (rec === null) { 49 | console.error("cannot fetch receipt"); 50 | return; 51 | } 52 | 53 | const address = await instance.getAddress(); 54 | 55 | console.log("tx hash", tx.hash); 56 | const gas = pn(rec.gasUsed.toString()); 57 | console.log(`gas used: ${gas}`); 58 | 59 | console.log("MultiRoundCheckout to:", address); 60 | } 61 | 62 | // We recommend this pattern to be able to use async/await everywhere 63 | // and properly handle errors. 64 | main().catch((error) => { 65 | console.error(error); 66 | process.exitCode = 1; 67 | }); 68 | -------------------------------------------------------------------------------- /scripts/deploy/transferOwnership.ts: -------------------------------------------------------------------------------- 1 | import hre, { ethers, upgrades } from "hardhat"; 2 | import { pn, prompt } from "../../lib/utils"; 3 | import { getEnv } from "../../lib/utils"; 4 | 5 | // Script to transfer ownership of Ownable contracts. 6 | // It can be used both for ProxyAdmin and MultiRoundCheckout contracts. 7 | 8 | const CONTRACT_ADDRESS = "0x029dFAf686DfA0efdace5132ba422e9279D50b5b"; 9 | const NEW_OWNER_ADDRESS = "0x79427367e9Be16353336D230De3031D489b1b3c3"; 10 | 11 | async function main() { 12 | const network = await ethers.provider.getNetwork(); 13 | const networkName = hre.network.name; 14 | let account; 15 | let accountAddress; 16 | 17 | if (process.env.USE_HARDWARE_WALLET === "true") { 18 | // with hardware wallet 19 | console.log("Waiting for hardware wallet to connect..."); 20 | // account = new LedgerSigner(ethers.provider); 21 | account = await ethers.getSigner(getEnv("HARDWARE_WALLET_ACCOUNT")); 22 | } else { 23 | // default without hardware wallet 24 | account = (await ethers.getSigners())[0]; 25 | } 26 | 27 | console.log(account.address); 28 | 29 | accountAddress = account.address; 30 | const balance = await ethers.provider.getBalance(accountAddress); 31 | 32 | console.log(`chainId: ${network.chainId}`); 33 | console.log(`network: ${networkName} (from ethers: ${network.name})`); 34 | console.log(`account: ${accountAddress}`); 35 | console.log(`balance: ${pn(balance.toString())}`); 36 | 37 | await prompt( 38 | `do you want to transfer ownership of the contract at ${CONTRACT_ADDRESS} to address ${NEW_OWNER_ADDRESS}?` 39 | ); 40 | console.log("init..."); 41 | 42 | const contract = await ethers.getContractAt( 43 | "MultiRoundCheckout", 44 | CONTRACT_ADDRESS, 45 | account 46 | ); 47 | 48 | console.log("current owner ", await contract.owner()); 49 | 50 | const tx = await contract.transferOwnership(NEW_OWNER_ADDRESS); 51 | const rec = await tx.wait(); 52 | if (rec === null) { 53 | console.error("cannot fetch receipt"); 54 | return; 55 | } 56 | 57 | console.log("tx hash", tx.hash); 58 | const gas = pn(rec.gasUsed.toString()); 59 | console.log(`gas used: ${gas}`); 60 | } 61 | 62 | // We recommend this pattern to be able to use async/await everywhere 63 | // and properly handle errors. 64 | main().catch((error) => { 65 | console.error(error); 66 | process.exitCode = 1; 67 | }); 68 | -------------------------------------------------------------------------------- /contracts/beta-rounds/IBetaRoundsVotingStrategy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: AGPL-3.0-only 2 | pragma solidity ^0.8.17; 3 | 4 | /** 5 | * @notice Defines the abstract contract for voting algorithms on grants 6 | * within a round. Any new voting algorithm would be expected to 7 | * extend this abstract contract. 8 | * Every IVotingStrategy contract would be unique to RoundImplementation 9 | * and would be deployed before creating a round 10 | */ 11 | abstract contract IVotingStrategy { 12 | // voting amount 13 | // voter address 14 | // grant address 15 | // project id 16 | // application index 17 | // round address 18 | event Voted( // voting token 19 | address token, 20 | uint256 amount, 21 | address indexed voter, 22 | address grantAddress, 23 | bytes32 indexed projectId, 24 | uint256 applicationIndex, 25 | address indexed roundAddress 26 | ); 27 | 28 | // --- Data --- 29 | 30 | /// @notice Round address 31 | address public roundAddress; 32 | 33 | // --- Modifier --- 34 | 35 | /// @notice modifier to check if sender is round contract. 36 | modifier isRoundContract() { 37 | require(roundAddress != address(0), "error: voting contract not linked to a round"); 38 | require(msg.sender == roundAddress, "error: can be invoked only by round contract"); 39 | _; 40 | } 41 | 42 | // --- Core methods --- 43 | 44 | /** 45 | * @notice Invoked by RoundImplementation on creation to 46 | * set the round for which the voting contracts is to be used 47 | * 48 | */ 49 | function init() external { 50 | require(roundAddress == address(0), "init: roundAddress already set"); 51 | roundAddress = msg.sender; 52 | } 53 | 54 | /** 55 | * @notice Invoked by RoundImplementation to allow voter to case 56 | * vote for grants during a round. 57 | * 58 | * @dev 59 | * - allows contributor to do cast multiple votes which could be weighted. 60 | * - should be invoked by RoundImplementation contract 61 | * - ideally IVotingStrategy implementation should emit events after a vote is cast 62 | * - this would be triggered when a voter casts their vote via grant explorer 63 | * 64 | * @param _encodedVotes encoded votes 65 | * @param _voterAddress voter address 66 | */ 67 | function vote(bytes[] calldata _encodedVotes, address _voterAddress) external payable virtual; 68 | } 69 | -------------------------------------------------------------------------------- /scripts/benchmarks/deploy-bench.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "hardhat"; 2 | import { ContractTransactionResponse } from "ethers"; 3 | 4 | // pretty number 5 | const pn = (n: bigint) => n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, "_"); 6 | 7 | const gasBench = async ( 8 | msg: string, 9 | callback: () => Promise 10 | ) => { 11 | const tx = await callback(); 12 | if (tx === null) { 13 | throw "failed to execute transaction"; 14 | } 15 | 16 | const rec = await tx.wait(); 17 | if (rec === null) { 18 | throw "failed to retrieve transaction receipt"; 19 | } 20 | 21 | console.log(msg, "🛢️ ", pn(rec.gasUsed)); 22 | }; 23 | 24 | const bold = (s: string) => `\x1b[1m${s}\x1b[0m`; 25 | 26 | const deploy = async (contractName: string) => { 27 | const contract = await ethers.deployContract(contractName, [], {}); 28 | await gasBench(`🚀 deploy ${bold(contractName)}`, async () => { 29 | await contract.waitForDeployment(); 30 | return contract.deploymentTransaction(); 31 | }); 32 | 33 | return contract; 34 | }; 35 | 36 | async function voteWithMultiRoundCheckoutContract() { 37 | const [user] = await ethers.getSigners(); 38 | console.log( 39 | "user balance", 40 | pn(await ethers.provider.getBalance(user.address)) 41 | ); 42 | 43 | const contract = await deploy("MultiRoundCheckout"); 44 | // TODO: when the fork setup is done, use the actual rounds instead of the mocks 45 | const round1 = await deploy("MockRoundImplementation"); 46 | const round2 = await deploy("MockRoundImplementation"); 47 | const round3 = await deploy("MockRoundImplementation"); 48 | 49 | const votes = [ 50 | ["0x01", "0x02", "0x03"], 51 | ["0x01", "0x02", "0x03"], 52 | ["0x01", "0x02", "0x03"], 53 | ]; 54 | 55 | const rounds = [round1.target, round2.target, round3.target]; 56 | 57 | const amounts = [ 58 | ethers.parseEther("1"), 59 | ethers.parseEther("2"), 60 | ethers.parseEther("3"), 61 | ]; 62 | 63 | await gasBench("✅ vote", () => 64 | contract.vote(votes, rounds, amounts, { 65 | value: ethers.parseEther("6"), 66 | }) 67 | ); 68 | } 69 | 70 | async function main() { 71 | // Execute the following actions in fork from a block within the Beta rounds voting period. 72 | 73 | // await voteWithBetaRoundsContracts(); 74 | await voteWithMultiRoundCheckoutContract(); 75 | } 76 | 77 | // We recommend this pattern to be able to use async/await everywhere 78 | // and properly handle errors. 79 | main().catch((error) => { 80 | console.error(error); 81 | process.exitCode = 1; 82 | }); 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Allo MultiRoundCheck 2 | 3 | The MultiRoundCheckout contract is a smart contract designed to simplify the process of donating to multiple rounds on the Allo V1 protocol 4 | and voting with ERC20 tokens. 5 | It streamlines the donation and voting process by enabling users to perform these actions using a single transaction, 6 | eliminating the need to send multiple transactions for each round. 7 | 8 | ## Features 9 | 10 | 1. **Multiple Rounds with one transatction**: With MultiRoundCheckout, users can donate to multiple rounds on the Allo V1 protocol using just one transaction, saving time and gas fees. 11 | 12 | 2. **ERC20 permit/donate in one transaction**: Instead of executing separate transactions for token approval and donation, users can now vote with ERC20 tokens in a single transaction. 13 | The contract supports ERC20 permit-compatible tokens, specifically those implementing ERC-2612 or DAI permit. 14 | This enables users to sign a "permit" message, simplifying the token approval process, saving gas fees and reducing the number of transactions needed to donate. 15 | 16 | ## Setup 17 | 18 | ``` 19 | git clone 20 | npm i 21 | ``` 22 | 23 | ## Tests 24 | 25 | ``` 26 | forge test 27 | ``` 28 | 29 | ## Deploy 30 | 31 | ``` 32 | npx hardhat deploy --network hedera 33 | ``` 34 | 35 | ## Deployment gas benchmark 36 | 37 | ``` 38 | npx hardhat run scripts/gas-bench.ts --typecheck 39 | ``` 40 | 41 | ## Donations gas benchmarks 42 | 43 | ``` 44 | # fork mainnet during the Gitcoin Beta rounds 45 | npx hardhat node --fork https://mainnet.infura.io/v3/$INFURA_API_KEY --fork-block-number 17123359 46 | 47 | # run the benchmarks against the local fork 48 | npx hardhat run scripts/benchmarks/beta-rounds-bench.ts --network localhost 49 | ``` 50 | 51 | ## Deployments 52 | 53 | | Chain | Address | 54 | |-----------------------|--------------------------------------------| 55 | | Ethereum | 0x3bA9DF642f5e895DC76d3Aa9e4CE8291108E65b1 | 56 | | PGN | 0x03506eD3f57892C85DB20C36846e9c808aFe9ef4 | 57 | | Optimism | 0x15fa08599EB017F89c1712d0Fe76138899FdB9db | 58 | | Fantom | 0x03506eD3f57892C85DB20C36846e9c808aFe9ef4 | 59 | | Fantom Testnet | 0x62a850d7805f3Ae382C6eEf7eEB89A31f68Ce2d5 | 60 | | Arbitrum One | 0x8e1bD5Da87C14dd8e08F7ecc2aBf9D1d558ea174 | 61 | | Sepolia | 0xa54A0c7Bcd37745f7F5817e06b07E2563a07E309 | 62 | | PGN Testnet | 0x4268900E904aD87903De593AA5424406066d9ea2 | 63 | | Arbitrum Goerli | 0x8e1bD5Da87C14dd8e08F7ecc2aBf9D1d558ea174 | 64 | | Polygon Mumbai | 0x8e1bD5Da87C14dd8e08F7ecc2aBf9D1d558ea174 | 65 | | Polygon | 0xe04d9e9CcDf65EB1Db51E56C04beE4c8582edB73 | 66 | | Avalanche Fuji | 0x8e1bD5Da87C14dd8e08F7ecc2aBf9D1d558ea174 | 67 | | Avalanche | 0xe04d9e9CcDf65EB1Db51E56C04beE4c8582edB73 | 68 | | Base Goerli | 0xa63f8F7E90C538D5173c7467C228fd38422dE9e9 | 69 | | Base | 0x7C24f3494CC958CF268a92b45D7e54310d161794 | 70 | | zkSyncEra Sepolia | 0x32e93A37dc02f97b8EDe446D8e468B1a894b47e0 | 71 | | zkSyncEra | 0x9FD009C448ce9b5DD7D609BFaf7C1C8fb91fb3ff | 72 | | Scroll Sepolia | 0x8Bd6Bc246FAF14B767954997fF3966CD1c0Bf0f5 | 73 | | Scroll | 0x8Bd6Bc246FAF14B767954997fF3966CD1c0Bf0f5 | 74 | | Celo Alfajores | 0x8Ad0a1111B3d8453Ea9C444cA7d708A65BF81Def | 75 | | Celo | 0xb1481E4Bb2a018670aAbF68952F73BE45bdAD62D | 76 | | Lukso | 0x029dFAf686DfA0efdace5132ba422e9279D50b5b | 77 | | Lukso Testnet | 0xC1087157eF2aaeBcaDB913251EA5B82c678424F7 | 78 | | Filecoin Calibration | 0x2447dD8C1f4cd4361a649564Bd441787edf8c03A | 79 | | Sei Devnet | 0x313eC6CA225C40Bc670d8cd4b063734BD22ad1ab | 80 | | Sei Mainnet | 0x1E18cdce56B3754c4Dca34CB3a7439C24E8363de | 81 | | Metis Andromeda | 0x710172b2C0aCc629A3FD23D436c347807dD5C412 | 82 | | Gnosis | 0xDE915119349E817f5012fa03f88F5C784d56A1fE | 83 | | Hedera Mainnet | 0x1E18cdce56B3754c4Dca34CB3a7439C24E8363de | 84 | 85 | 86 | -------------------------------------------------------------------------------- /.openzeppelin/unknown-424.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x1139c2F5e7C7EDd6Fc62d1105eCC5650E7168bF0", 5 | "txHash": "0x8608c6a42c7f908aefdeeaa66f83affaa42b1ea867872ce963e58607cacc4ce6" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x03506eD3f57892C85DB20C36846e9c808aFe9ef4", 10 | "txHash": "0x14af6f54a9759f28ca0123ab430411f94affca89882d31066b67d5e92e2228ee", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "fc7421aad9cc9e702dfe5f50541c858cdc57337746ef1310b5ab7190098a1ede": { 16 | "address": "0x15fa08599EB017F89c1712d0Fe76138899FdB9db", 17 | "txHash": "0xf4484ac424e6ed8ccde05e77e00a16faa5ffd0c648172ec361b7f029ca7840fd", 18 | "layout": { 19 | "solcVersion": "0.8.18", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | } 94 | ], 95 | "types": { 96 | "t_address": { 97 | "label": "address", 98 | "numberOfBytes": "20" 99 | }, 100 | "t_array(t_uint256)49_storage": { 101 | "label": "uint256[49]", 102 | "numberOfBytes": "1568" 103 | }, 104 | "t_array(t_uint256)50_storage": { 105 | "label": "uint256[50]", 106 | "numberOfBytes": "1600" 107 | }, 108 | "t_bool": { 109 | "label": "bool", 110 | "numberOfBytes": "1" 111 | }, 112 | "t_uint256": { 113 | "label": "uint256", 114 | "numberOfBytes": "32" 115 | }, 116 | "t_uint8": { 117 | "label": "uint8", 118 | "numberOfBytes": "1" 119 | } 120 | } 121 | } 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /.openzeppelin/arbitrum-goerli.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0xec77FccE4f0396BaB43BC66a513157Ee59EE07c7", 5 | "txHash": "0xcda192c4e97802332fa506b35d0ce8b33e9b2205e4f9199eeb449c277d5ad0fc" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x8e1bD5Da87C14dd8e08F7ecc2aBf9D1d558ea174", 10 | "txHash": "0x68a0703321300a9050dbaf546657fcbc801e8f56e248ac6878ba895ea34367fe", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "fc7421aad9cc9e702dfe5f50541c858cdc57337746ef1310b5ab7190098a1ede": { 16 | "address": "0xbce556cf365E631fF50449211A6f2CB8936f40D1", 17 | "txHash": "0x538c92bca2ade0504fd6135ab355ae0c7357ae73ea3e898cf0f4ad8551585ba8", 18 | "layout": { 19 | "solcVersion": "0.8.18", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | } 94 | ], 95 | "types": { 96 | "t_address": { 97 | "label": "address", 98 | "numberOfBytes": "20" 99 | }, 100 | "t_array(t_uint256)49_storage": { 101 | "label": "uint256[49]", 102 | "numberOfBytes": "1568" 103 | }, 104 | "t_array(t_uint256)50_storage": { 105 | "label": "uint256[50]", 106 | "numberOfBytes": "1600" 107 | }, 108 | "t_bool": { 109 | "label": "bool", 110 | "numberOfBytes": "1" 111 | }, 112 | "t_uint256": { 113 | "label": "uint256", 114 | "numberOfBytes": "32" 115 | }, 116 | "t_uint8": { 117 | "label": "uint8", 118 | "numberOfBytes": "1" 119 | } 120 | } 121 | } 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /.openzeppelin/unknown-58008.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x39894444EC4F1D3bfFF6496048597E1aa9dcDb87", 5 | "txHash": "0xdacd518866ae6c40235276c82c5bb27adc024dd0a155245937a1dfe2f8adc2b7" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x4268900E904aD87903De593AA5424406066d9ea2", 10 | "txHash": "0xb15f9e3951ddace12c0b8653cff8b511e12cdec688812e7431bbc092e5965ce2", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "fc7421aad9cc9e702dfe5f50541c858cdc57337746ef1310b5ab7190098a1ede": { 16 | "address": "0xCA1C07d88A9102CB9B85C7d3F4B69754A213Ed5A", 17 | "txHash": "0x1ae978bf08f064c0a4fc1aeb7e861b7b8b9d24a25a37c6b50f3cc35914af9877", 18 | "layout": { 19 | "solcVersion": "0.8.18", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | } 94 | ], 95 | "types": { 96 | "t_address": { 97 | "label": "address", 98 | "numberOfBytes": "20" 99 | }, 100 | "t_array(t_uint256)49_storage": { 101 | "label": "uint256[49]", 102 | "numberOfBytes": "1568" 103 | }, 104 | "t_array(t_uint256)50_storage": { 105 | "label": "uint256[50]", 106 | "numberOfBytes": "1600" 107 | }, 108 | "t_bool": { 109 | "label": "bool", 110 | "numberOfBytes": "1" 111 | }, 112 | "t_uint256": { 113 | "label": "uint256", 114 | "numberOfBytes": "32" 115 | }, 116 | "t_uint8": { 117 | "label": "uint8", 118 | "numberOfBytes": "1" 119 | } 120 | } 121 | } 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /.openzeppelin/unknown-84531.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x0FcaFFce37d35031d81A6e161a1f47Faa2D32111", 5 | "txHash": "0xdefae8c648ca1ef52259df3fec90914fc500658d3a52e0403fae1564ccf50262" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0xa63f8F7E90C538D5173c7467C228fd38422dE9e9", 10 | "txHash": "0x0635457b1f3c0c9fa6a1936f7a08cf2f880fe4b0fe3f1962ec6c276c3d58bfc7", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "fc7421aad9cc9e702dfe5f50541c858cdc57337746ef1310b5ab7190098a1ede": { 16 | "address": "0x8656D1c5f0133545c56456c389066114F3E37BEb", 17 | "txHash": "0x3349fe41ff293cb27e31a98d790ff7d8c0b7e78ba7b1de1db763f4c4d25f551c", 18 | "layout": { 19 | "solcVersion": "0.8.18", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | } 94 | ], 95 | "types": { 96 | "t_address": { 97 | "label": "address", 98 | "numberOfBytes": "20" 99 | }, 100 | "t_array(t_uint256)49_storage": { 101 | "label": "uint256[49]", 102 | "numberOfBytes": "1568" 103 | }, 104 | "t_array(t_uint256)50_storage": { 105 | "label": "uint256[50]", 106 | "numberOfBytes": "1600" 107 | }, 108 | "t_bool": { 109 | "label": "bool", 110 | "numberOfBytes": "1" 111 | }, 112 | "t_uint256": { 113 | "label": "uint256", 114 | "numberOfBytes": "32" 115 | }, 116 | "t_uint8": { 117 | "label": "uint8", 118 | "numberOfBytes": "1" 119 | } 120 | } 121 | } 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /.openzeppelin/unknown-534351.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x8876f427C08548DaE17101bdeD1Ed6aD79Ab74EC", 5 | "txHash": "0x2cce672554df5120f76f3a001e7a47762443271b809dbd399d72f84f942f0926" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x8Bd6Bc246FAF14B767954997fF3966CD1c0Bf0f5", 10 | "txHash": "0x370e47d4a84efac1a28d6ad38b5fd4cd8f07c3f0488990509ab2b69c6fc06561", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "fc7421aad9cc9e702dfe5f50541c858cdc57337746ef1310b5ab7190098a1ede": { 16 | "address": "0xD46dA05A659db4787F1d6D564A7Ee5b09457d431", 17 | "txHash": "0xe25a6333ff27a9e0213c086510e7565ca8b9049d4f57c4cffc4743c161d31d4d", 18 | "layout": { 19 | "solcVersion": "0.8.18", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | } 94 | ], 95 | "types": { 96 | "t_address": { 97 | "label": "address", 98 | "numberOfBytes": "20" 99 | }, 100 | "t_array(t_uint256)49_storage": { 101 | "label": "uint256[49]", 102 | "numberOfBytes": "1568" 103 | }, 104 | "t_array(t_uint256)50_storage": { 105 | "label": "uint256[50]", 106 | "numberOfBytes": "1600" 107 | }, 108 | "t_bool": { 109 | "label": "bool", 110 | "numberOfBytes": "1" 111 | }, 112 | "t_uint256": { 113 | "label": "uint256", 114 | "numberOfBytes": "32" 115 | }, 116 | "t_uint8": { 117 | "label": "uint8", 118 | "numberOfBytes": "1" 119 | } 120 | }, 121 | "namespaces": {} 122 | } 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /.upgradable/zkSync-testnet.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0xDc842c17D423a9b2C9758b340F53aED89D4fF67c", 5 | "txHash": "0x3fcd40a639f065e6f1227610941a44d61d185b15a7be62b578e9dd58936a4e96" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x57819f2264Ff3f644c9a3e982EB41b4eE6F9a0aE", 10 | "txHash": "0x7f24b3b610ff406fd1ac9ccf5ad0af0942cb3b08171a0ef58dccf39e7f3068a8", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "186a20e24c15fd44697ff3400537451538a6a9bcf6c67557ea76d5aca8a9d7b7": { 16 | "address": "0x3E6D0bbd99DcB83CA1D662D206ECEF8A80f39373", 17 | "txHash": "0x28ff95818963b71ccea78f9ab54ac987925b5fca1141e8a7e43b7965b7c38152", 18 | "layout": { 19 | "solcVersion": "0.8.18", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | } 94 | ], 95 | "types": { 96 | "t_address": { 97 | "label": "address", 98 | "numberOfBytes": "20" 99 | }, 100 | "t_array(t_uint256)49_storage": { 101 | "label": "uint256[49]", 102 | "numberOfBytes": "1568" 103 | }, 104 | "t_array(t_uint256)50_storage": { 105 | "label": "uint256[50]", 106 | "numberOfBytes": "1600" 107 | }, 108 | "t_bool": { 109 | "label": "bool", 110 | "numberOfBytes": "1" 111 | }, 112 | "t_uint256": { 113 | "label": "uint256", 114 | "numberOfBytes": "32" 115 | }, 116 | "t_uint8": { 117 | "label": "uint8", 118 | "numberOfBytes": "1" 119 | } 120 | }, 121 | "namespaces": {} 122 | } 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /.openzeppelin/celo.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x82F6e34624BB66e0d330d84ef8B617dCA075649D", 5 | "txHash": "0x892f0ee54f05bcd45cf4a47d19125ffafb2d6353d3a0954a93b2aed24b33d456" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0xb1481E4Bb2a018670aAbF68952F73BE45bdAD62D", 10 | "txHash": "0x0f4bb54cf790ae2b4f02b2687ed78826464c9359e25d7d30cf446265b34ec068", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 16 | "address": "0x74667779f88399cDA5A9781818CB7D955C4f9abC", 17 | "txHash": "0x09a5fc52a2b9c56779a9d4b528fbb82b3dd1dad6c87d9287b213de7ce7eb391c", 18 | "layout": { 19 | "solcVersion": "0.8.20", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | }, 94 | { 95 | "label": "allo", 96 | "offset": 0, 97 | "slot": "201", 98 | "type": "t_contract(IAllo)1014", 99 | "contract": "MultiRoundCheckout", 100 | "src": "contracts/MultiRoundCheckout.sol:206" 101 | } 102 | ], 103 | "types": { 104 | "t_address": { 105 | "label": "address", 106 | "numberOfBytes": "20" 107 | }, 108 | "t_array(t_uint256)49_storage": { 109 | "label": "uint256[49]", 110 | "numberOfBytes": "1568" 111 | }, 112 | "t_array(t_uint256)50_storage": { 113 | "label": "uint256[50]", 114 | "numberOfBytes": "1600" 115 | }, 116 | "t_bool": { 117 | "label": "bool", 118 | "numberOfBytes": "1" 119 | }, 120 | "t_contract(IAllo)1014": { 121 | "label": "contract IAllo", 122 | "numberOfBytes": "20" 123 | }, 124 | "t_uint256": { 125 | "label": "uint256", 126 | "numberOfBytes": "32" 127 | }, 128 | "t_uint8": { 129 | "label": "uint8", 130 | "numberOfBytes": "1" 131 | } 132 | }, 133 | "namespaces": {} 134 | } 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /.openzeppelin/kovan.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x45181C4fD52d4d350380B3D42091b80065c702Ef", 5 | "txHash": "0xe6c5bd1525fc30ef76104028e2fbcc63d90ee52397ed0df5852fcc31dcda871d" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x029dFAf686DfA0efdace5132ba422e9279D50b5b", 10 | "txHash": "0xfb6a6d95e2e69302dce1a6781630bf16eba51c91ed52ffd8b81e212b18d298d5", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 16 | "address": "0x26827C474a276bb25bc414c9FF8c55962cAe3fb9", 17 | "txHash": "0xf4a8c8f7f6702755f5240e97b5793a0045c80b32d120741bdf156c737e5cc8c5", 18 | "layout": { 19 | "solcVersion": "0.8.20", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | }, 94 | { 95 | "label": "allo", 96 | "offset": 0, 97 | "slot": "201", 98 | "type": "t_contract(IAllo)1014", 99 | "contract": "MultiRoundCheckout", 100 | "src": "contracts/MultiRoundCheckout.sol:206" 101 | } 102 | ], 103 | "types": { 104 | "t_address": { 105 | "label": "address", 106 | "numberOfBytes": "20" 107 | }, 108 | "t_array(t_uint256)49_storage": { 109 | "label": "uint256[49]", 110 | "numberOfBytes": "1568" 111 | }, 112 | "t_array(t_uint256)50_storage": { 113 | "label": "uint256[50]", 114 | "numberOfBytes": "1600" 115 | }, 116 | "t_bool": { 117 | "label": "bool", 118 | "numberOfBytes": "1" 119 | }, 120 | "t_contract(IAllo)1014": { 121 | "label": "contract IAllo", 122 | "numberOfBytes": "20" 123 | }, 124 | "t_uint256": { 125 | "label": "uint256", 126 | "numberOfBytes": "32" 127 | }, 128 | "t_uint8": { 129 | "label": "uint8", 130 | "numberOfBytes": "1" 131 | } 132 | }, 133 | "namespaces": {} 134 | } 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /.openzeppelin/celo-alfajores.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x86b4329E7CB8674b015477C81356420D79c71A53", 5 | "txHash": "0x7354ed9117d5ee6a33db5b58f348571ded898b004d8fb0ba25608c4b36a7cd65" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x8Ad0a1111B3d8453Ea9C444cA7d708A65BF81Def", 10 | "txHash": "0xa1e1dcecbc16be612aef35498e1aaa24610be5656b3f3f732c9cb6948f17adff", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 16 | "address": "0x5bBFa3cE3a81645897dEeE892557f50756940d6f", 17 | "txHash": "0x5cbebc8deffb64f63f8b2aaefab3946d76508d56a2390687faaac6448d1a2773", 18 | "layout": { 19 | "solcVersion": "0.8.20", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | }, 94 | { 95 | "label": "allo", 96 | "offset": 0, 97 | "slot": "201", 98 | "type": "t_contract(IAllo)1014", 99 | "contract": "MultiRoundCheckout", 100 | "src": "contracts/MultiRoundCheckout.sol:206" 101 | } 102 | ], 103 | "types": { 104 | "t_address": { 105 | "label": "address", 106 | "numberOfBytes": "20" 107 | }, 108 | "t_array(t_uint256)49_storage": { 109 | "label": "uint256[49]", 110 | "numberOfBytes": "1568" 111 | }, 112 | "t_array(t_uint256)50_storage": { 113 | "label": "uint256[50]", 114 | "numberOfBytes": "1600" 115 | }, 116 | "t_bool": { 117 | "label": "bool", 118 | "numberOfBytes": "1" 119 | }, 120 | "t_contract(IAllo)1014": { 121 | "label": "contract IAllo", 122 | "numberOfBytes": "20" 123 | }, 124 | "t_uint256": { 125 | "label": "uint256", 126 | "numberOfBytes": "32" 127 | }, 128 | "t_uint8": { 129 | "label": "uint8", 130 | "numberOfBytes": "1" 131 | } 132 | }, 133 | "namespaces": {} 134 | } 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /.openzeppelin/unknown-100.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x05b939069163891997C879288f0BaaC3faaf4500", 5 | "txHash": "0x3e2bd9684aab75581f01894c688a415f0d5bc8d3c51339a36c4e85de79b5da56" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0xDE915119349E817f5012fa03f88F5C784d56A1fE", 10 | "txHash": "0x7e4ab1b869d8ebf08daa81794b82322d3361b3e0c503a1c691a01a082aea41c3", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 16 | "address": "0x629C94181A081a8d70F96a3D0B0c0e7C73d9e289", 17 | "txHash": "0xa3ce1b95b18298fc51fcdd869cbf12e1c60a3e927d2e09fe0108d5145695d747", 18 | "layout": { 19 | "solcVersion": "0.8.20", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | }, 94 | { 95 | "label": "allo", 96 | "offset": 0, 97 | "slot": "201", 98 | "type": "t_contract(IAllo)6906", 99 | "contract": "MultiRoundCheckout", 100 | "src": "contracts/MultiRoundCheckout.sol:206" 101 | } 102 | ], 103 | "types": { 104 | "t_address": { 105 | "label": "address", 106 | "numberOfBytes": "20" 107 | }, 108 | "t_array(t_uint256)49_storage": { 109 | "label": "uint256[49]", 110 | "numberOfBytes": "1568" 111 | }, 112 | "t_array(t_uint256)50_storage": { 113 | "label": "uint256[50]", 114 | "numberOfBytes": "1600" 115 | }, 116 | "t_bool": { 117 | "label": "bool", 118 | "numberOfBytes": "1" 119 | }, 120 | "t_contract(IAllo)6906": { 121 | "label": "contract IAllo", 122 | "numberOfBytes": "20" 123 | }, 124 | "t_uint256": { 125 | "label": "uint256", 126 | "numberOfBytes": "32" 127 | }, 128 | "t_uint8": { 129 | "label": "uint8", 130 | "numberOfBytes": "1" 131 | } 132 | }, 133 | "namespaces": {} 134 | } 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /.openzeppelin/unknown-1088.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x1E18cdce56B3754c4Dca34CB3a7439C24E8363de", 5 | "txHash": "0x383dbca74c0e9cb00c7a8823e1ea1aefff3aea8743e9d27c255b8bd036361bfb" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x710172b2C0aCc629A3FD23D436c347807dD5C412", 10 | "txHash": "0x2d3d8de8e3eaedb75c4a1f21709e51b09395ad6683e8fab8d6e6bd3820273161", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 16 | "address": "0xDE915119349E817f5012fa03f88F5C784d56A1fE", 17 | "txHash": "0xcbbaaaa05306362641612f15b3e4332f1a81371cf6f9784a1a5515f5b81441e3", 18 | "layout": { 19 | "solcVersion": "0.8.20", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | }, 94 | { 95 | "label": "allo", 96 | "offset": 0, 97 | "slot": "201", 98 | "type": "t_contract(IAllo)6906", 99 | "contract": "MultiRoundCheckout", 100 | "src": "contracts/MultiRoundCheckout.sol:206" 101 | } 102 | ], 103 | "types": { 104 | "t_address": { 105 | "label": "address", 106 | "numberOfBytes": "20" 107 | }, 108 | "t_array(t_uint256)49_storage": { 109 | "label": "uint256[49]", 110 | "numberOfBytes": "1568" 111 | }, 112 | "t_array(t_uint256)50_storage": { 113 | "label": "uint256[50]", 114 | "numberOfBytes": "1600" 115 | }, 116 | "t_bool": { 117 | "label": "bool", 118 | "numberOfBytes": "1" 119 | }, 120 | "t_contract(IAllo)6906": { 121 | "label": "contract IAllo", 122 | "numberOfBytes": "20" 123 | }, 124 | "t_uint256": { 125 | "label": "uint256", 126 | "numberOfBytes": "32" 127 | }, 128 | "t_uint8": { 129 | "label": "uint8", 130 | "numberOfBytes": "1" 131 | } 132 | }, 133 | "namespaces": {} 134 | } 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /.openzeppelin/unknown-1329.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0xDE915119349E817f5012fa03f88F5C784d56A1fE", 5 | "txHash": "0x8c8f0bcf24251b58d4591d51c3ddd77a1647ce1d30b2daaf4fbe65a70d4dc57d" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x1E18cdce56B3754c4Dca34CB3a7439C24E8363de", 10 | "txHash": "0x67ea7f946b673e0b97e9cc3dd008d1a0a547b63c50a0e13bbc9e459be3e3d6b4", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 16 | "address": "0x05b939069163891997C879288f0BaaC3faaf4500", 17 | "txHash": "0xf0509987a8ded4ca4f7db4f4c8e7839f2bc3258becd34157f171f3ea3c7ccc92", 18 | "layout": { 19 | "solcVersion": "0.8.20", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | }, 94 | { 95 | "label": "allo", 96 | "offset": 0, 97 | "slot": "201", 98 | "type": "t_contract(IAllo)6906", 99 | "contract": "MultiRoundCheckout", 100 | "src": "contracts/MultiRoundCheckout.sol:206" 101 | } 102 | ], 103 | "types": { 104 | "t_address": { 105 | "label": "address", 106 | "numberOfBytes": "20" 107 | }, 108 | "t_array(t_uint256)49_storage": { 109 | "label": "uint256[49]", 110 | "numberOfBytes": "1568" 111 | }, 112 | "t_array(t_uint256)50_storage": { 113 | "label": "uint256[50]", 114 | "numberOfBytes": "1600" 115 | }, 116 | "t_bool": { 117 | "label": "bool", 118 | "numberOfBytes": "1" 119 | }, 120 | "t_contract(IAllo)6906": { 121 | "label": "contract IAllo", 122 | "numberOfBytes": "20" 123 | }, 124 | "t_uint256": { 125 | "label": "uint256", 126 | "numberOfBytes": "32" 127 | }, 128 | "t_uint8": { 129 | "label": "uint8", 130 | "numberOfBytes": "1" 131 | } 132 | }, 133 | "namespaces": {} 134 | } 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /.openzeppelin/unknown-295.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0xDE915119349E817f5012fa03f88F5C784d56A1fE", 5 | "txHash": "0xeeda69661d7cf9f2b1dacd127f716e82b50daed2b1c7fd9bf4e3ac0c12a1f90a" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x1E18cdce56B3754c4Dca34CB3a7439C24E8363de", 10 | "txHash": "0xa7f18d7d2aa3dfb4905410e64e570b2ec3c60a58944cb463abdb4b9e00df17d3", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 16 | "address": "0x05b939069163891997C879288f0BaaC3faaf4500", 17 | "txHash": "0x433d364746677506e1063eec187ef24b3e4ac16956c7aba716c29fac1d2a52a9", 18 | "layout": { 19 | "solcVersion": "0.8.20", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | }, 94 | { 95 | "label": "allo", 96 | "offset": 0, 97 | "slot": "201", 98 | "type": "t_contract(IAllo)6906", 99 | "contract": "MultiRoundCheckout", 100 | "src": "contracts/MultiRoundCheckout.sol:206" 101 | } 102 | ], 103 | "types": { 104 | "t_address": { 105 | "label": "address", 106 | "numberOfBytes": "20" 107 | }, 108 | "t_array(t_uint256)49_storage": { 109 | "label": "uint256[49]", 110 | "numberOfBytes": "1568" 111 | }, 112 | "t_array(t_uint256)50_storage": { 113 | "label": "uint256[50]", 114 | "numberOfBytes": "1600" 115 | }, 116 | "t_bool": { 117 | "label": "bool", 118 | "numberOfBytes": "1" 119 | }, 120 | "t_contract(IAllo)6906": { 121 | "label": "contract IAllo", 122 | "numberOfBytes": "20" 123 | }, 124 | "t_uint256": { 125 | "label": "uint256", 126 | "numberOfBytes": "32" 127 | }, 128 | "t_uint8": { 129 | "label": "uint8", 130 | "numberOfBytes": "1" 131 | } 132 | }, 133 | "namespaces": {} 134 | } 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /.openzeppelin/unknown-4201.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x3a620eBbe88040bFD39E7fBE702A17aF6e3258AB", 5 | "txHash": "0x93b8e51243a14352c667d633b73e3d3694928cc2d599b7ab1a515b233f07d85b" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0xC1087157eF2aaeBcaDB913251EA5B82c678424F7", 10 | "txHash": "0xec49d671c16b09dd0daa3115b6f426056567f77fe532a1c25dd65cb6bc037984", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 16 | "address": "0x5B47c6aFE27b0F5C8319366C6b8FbC0E02104b98", 17 | "txHash": "0x9517c30b064c097e363f3f9bd5c971639c98527d80d86a027ce1fd0a1d6f79b3", 18 | "layout": { 19 | "solcVersion": "0.8.20", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | }, 94 | { 95 | "label": "allo", 96 | "offset": 0, 97 | "slot": "201", 98 | "type": "t_contract(IAllo)1014", 99 | "contract": "MultiRoundCheckout", 100 | "src": "contracts/MultiRoundCheckout.sol:206" 101 | } 102 | ], 103 | "types": { 104 | "t_address": { 105 | "label": "address", 106 | "numberOfBytes": "20" 107 | }, 108 | "t_array(t_uint256)49_storage": { 109 | "label": "uint256[49]", 110 | "numberOfBytes": "1568" 111 | }, 112 | "t_array(t_uint256)50_storage": { 113 | "label": "uint256[50]", 114 | "numberOfBytes": "1600" 115 | }, 116 | "t_bool": { 117 | "label": "bool", 118 | "numberOfBytes": "1" 119 | }, 120 | "t_contract(IAllo)1014": { 121 | "label": "contract IAllo", 122 | "numberOfBytes": "20" 123 | }, 124 | "t_uint256": { 125 | "label": "uint256", 126 | "numberOfBytes": "32" 127 | }, 128 | "t_uint8": { 129 | "label": "uint8", 130 | "numberOfBytes": "1" 131 | } 132 | }, 133 | "namespaces": {} 134 | } 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /.openzeppelin/unknown-713715.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0xf5cA96151d1a9998d234963433bfd3f6feC7aAc2", 5 | "txHash": "0x2c050b88c5a91330e53f2680ee3779b4b89ca3a7f0b2f0e0f52001532f705a6e" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x313eC6CA225C40Bc670d8cd4b063734BD22ad1ab", 10 | "txHash": "0x554972df9a6f14f8b4219830b99282c2d6f92ef757b54efbd8fe81dab3fb4afe", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 16 | "address": "0xFf4354C3Da51D1557071Ca48d0f0D046a161F0b6", 17 | "txHash": "0x9f98191f08b5753bd1dd65833641f4c6d21502a48dfc85fe142abdd165c9a8fc", 18 | "layout": { 19 | "solcVersion": "0.8.20", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | }, 94 | { 95 | "label": "allo", 96 | "offset": 0, 97 | "slot": "201", 98 | "type": "t_contract(IAllo)1014", 99 | "contract": "MultiRoundCheckout", 100 | "src": "contracts/MultiRoundCheckout.sol:206" 101 | } 102 | ], 103 | "types": { 104 | "t_address": { 105 | "label": "address", 106 | "numberOfBytes": "20" 107 | }, 108 | "t_array(t_uint256)49_storage": { 109 | "label": "uint256[49]", 110 | "numberOfBytes": "1568" 111 | }, 112 | "t_array(t_uint256)50_storage": { 113 | "label": "uint256[50]", 114 | "numberOfBytes": "1600" 115 | }, 116 | "t_bool": { 117 | "label": "bool", 118 | "numberOfBytes": "1" 119 | }, 120 | "t_contract(IAllo)1014": { 121 | "label": "contract IAllo", 122 | "numberOfBytes": "20" 123 | }, 124 | "t_uint256": { 125 | "label": "uint256", 126 | "numberOfBytes": "32" 127 | }, 128 | "t_uint8": { 129 | "label": "uint8", 130 | "numberOfBytes": "1" 131 | } 132 | }, 133 | "namespaces": {} 134 | } 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /.upgradable/zkSync-testnet-sepolia.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x9FD009C448ce9b5DD7D609BFaf7C1C8fb91fb3ff", 5 | "txHash": "0x220c3f0252e022781fef302bca02c4c358c1941ca5199a425eab5745528dc4bc" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x32e93A37dc02f97b8EDe446D8e468B1a894b47e0", 10 | "txHash": "0x3c5f7cb90ad6ca7d2034104f501a6e213be690493be560a41002743d42f628f7", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "4daa717e7e364977f751a3fa6d7a88a267b0547e7776dc06838fd0f35b82bed6": { 16 | "address": "0x89FE583Dca9B97202aC052fd1C2B438f8f286401", 17 | "txHash": "0x7ef73964a4c6b5d6e305d69452c01c120fc7516dfb84f295a2c667c6c3d8f09f", 18 | "layout": { 19 | "solcVersion": "0.8.19", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | }, 94 | { 95 | "label": "allo", 96 | "offset": 0, 97 | "slot": "201", 98 | "type": "t_contract(IAllo)8383", 99 | "contract": "MultiRoundCheckout", 100 | "src": "contracts/MultiRoundCheckout.sol:206" 101 | } 102 | ], 103 | "types": { 104 | "t_address": { 105 | "label": "address", 106 | "numberOfBytes": "20" 107 | }, 108 | "t_array(t_uint256)49_storage": { 109 | "label": "uint256[49]", 110 | "numberOfBytes": "1568" 111 | }, 112 | "t_array(t_uint256)50_storage": { 113 | "label": "uint256[50]", 114 | "numberOfBytes": "1600" 115 | }, 116 | "t_bool": { 117 | "label": "bool", 118 | "numberOfBytes": "1" 119 | }, 120 | "t_contract(IAllo)8383": { 121 | "label": "contract IAllo", 122 | "numberOfBytes": "20" 123 | }, 124 | "t_uint256": { 125 | "label": "uint256", 126 | "numberOfBytes": "32" 127 | }, 128 | "t_uint8": { 129 | "label": "uint8", 130 | "numberOfBytes": "1" 131 | } 132 | }, 133 | "namespaces": {} 134 | } 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /.openzeppelin/unknown-314159.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x30eC57511938b798d604C9feb02B2388306d8f43", 5 | "txHash": "0xf7de5efb75e48230d1d28e7959c5fd03373a06070b4dc33094a263dc936b7e52" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x2447dD8C1f4cd4361a649564Bd441787edf8c03A", 10 | "txHash": "0x2d888ffc04e5f66055ff1b160c6b8799fd49ef9304dff883ea7dab8f990fbf7f", 11 | "kind": "transparent" 12 | }, 13 | { 14 | "address": "0x606BfaCCc19F040F55C7be25C1Db02a4201bf8f0", 15 | "txHash": "0x8bebb7545d5ca840c95eeb70159f4a5e762a523ae27a2953a95eb49ecbe29065", 16 | "kind": "transparent" 17 | } 18 | ], 19 | "impls": { 20 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 21 | "address": "0x3c795a334dE57813D8CA945D1A47D329D6Fc2151", 22 | "txHash": "0x96d3079edeaf1039eb9c3452cbb79fcbb2efc4beccaa8c0053f3ea7036a15f3b", 23 | "layout": { 24 | "solcVersion": "0.8.20", 25 | "storage": [ 26 | { 27 | "label": "_initialized", 28 | "offset": 0, 29 | "slot": "0", 30 | "type": "t_uint8", 31 | "contract": "Initializable", 32 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 33 | "retypedFrom": "bool" 34 | }, 35 | { 36 | "label": "_initializing", 37 | "offset": 1, 38 | "slot": "0", 39 | "type": "t_bool", 40 | "contract": "Initializable", 41 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 42 | }, 43 | { 44 | "label": "__gap", 45 | "offset": 0, 46 | "slot": "1", 47 | "type": "t_array(t_uint256)50_storage", 48 | "contract": "ContextUpgradeable", 49 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 50 | }, 51 | { 52 | "label": "_owner", 53 | "offset": 0, 54 | "slot": "51", 55 | "type": "t_address", 56 | "contract": "OwnableUpgradeable", 57 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 58 | }, 59 | { 60 | "label": "__gap", 61 | "offset": 0, 62 | "slot": "52", 63 | "type": "t_array(t_uint256)49_storage", 64 | "contract": "OwnableUpgradeable", 65 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 66 | }, 67 | { 68 | "label": "_paused", 69 | "offset": 0, 70 | "slot": "101", 71 | "type": "t_bool", 72 | "contract": "PausableUpgradeable", 73 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 74 | }, 75 | { 76 | "label": "__gap", 77 | "offset": 0, 78 | "slot": "102", 79 | "type": "t_array(t_uint256)49_storage", 80 | "contract": "PausableUpgradeable", 81 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 82 | }, 83 | { 84 | "label": "_status", 85 | "offset": 0, 86 | "slot": "151", 87 | "type": "t_uint256", 88 | "contract": "ReentrancyGuardUpgradeable", 89 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 90 | }, 91 | { 92 | "label": "__gap", 93 | "offset": 0, 94 | "slot": "152", 95 | "type": "t_array(t_uint256)49_storage", 96 | "contract": "ReentrancyGuardUpgradeable", 97 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 98 | }, 99 | { 100 | "label": "allo", 101 | "offset": 0, 102 | "slot": "201", 103 | "type": "t_contract(IAllo)1014", 104 | "contract": "MultiRoundCheckout", 105 | "src": "contracts/MultiRoundCheckout.sol:206" 106 | } 107 | ], 108 | "types": { 109 | "t_address": { 110 | "label": "address", 111 | "numberOfBytes": "20" 112 | }, 113 | "t_array(t_uint256)49_storage": { 114 | "label": "uint256[49]", 115 | "numberOfBytes": "1568" 116 | }, 117 | "t_array(t_uint256)50_storage": { 118 | "label": "uint256[50]", 119 | "numberOfBytes": "1600" 120 | }, 121 | "t_bool": { 122 | "label": "bool", 123 | "numberOfBytes": "1" 124 | }, 125 | "t_contract(IAllo)1014": { 126 | "label": "contract IAllo", 127 | "numberOfBytes": "20" 128 | }, 129 | "t_uint256": { 130 | "label": "uint256", 131 | "numberOfBytes": "32" 132 | }, 133 | "t_uint8": { 134 | "label": "uint8", 135 | "numberOfBytes": "1" 136 | } 137 | }, 138 | "namespaces": {} 139 | } 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /test/MRCVote.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.17; 3 | 4 | import "forge-std/Test.sol"; 5 | import "../contracts/MultiRoundCheckout.sol"; 6 | import "../contracts/mocks/MockRoundImplementationETH.sol"; 7 | 8 | contract MrcTestVote is Test { 9 | MultiRoundCheckout private mrc; 10 | MockRoundImplementationETH private round1; 11 | MockRoundImplementationETH private round2; 12 | MockRoundImplementationETH private round3; 13 | address[] public rounds = new address[](3); 14 | bytes[][] public votes = new bytes[][](3); 15 | uint256[] public amounts = new uint256[](3); 16 | 17 | function setUp() public { 18 | round1 = new MockRoundImplementationETH(); 19 | round2 = new MockRoundImplementationETH(); 20 | round3 = new MockRoundImplementationETH(); 21 | mrc = new MultiRoundCheckout(); 22 | mrc.initialize(address(1)); 23 | 24 | rounds[0] = address(round1); 25 | rounds[1] = address(round2); 26 | rounds[2] = address(round3); 27 | 28 | votes[0] = new bytes[](3); 29 | votes[0][0] = "A"; 30 | votes[0][1] = "B"; 31 | votes[0][2] = "C"; 32 | 33 | votes[1] = new bytes[](3); 34 | votes[1][0] = "X"; 35 | votes[1][1] = "Y"; 36 | votes[1][2] = "Z"; 37 | 38 | votes[2] = new bytes[](3); 39 | votes[2][0] = "P"; 40 | votes[2][1] = "Q"; 41 | votes[2][2] = "R"; 42 | 43 | amounts[0] = 1; 44 | amounts[1] = 2; 45 | amounts[2] = 3; 46 | } 47 | 48 | function testNonReentrant() public { 49 | vm.deal(address(this), 10); 50 | MockRoundImplementationETH(rounds[0]).setReentrant(true); 51 | 52 | vm.expectRevert(bytes("ReentrancyGuard: reentrant call")); 53 | mrc.vote{value: 6}(votes, rounds, amounts); 54 | MockRoundImplementationETH(rounds[0]).setReentrant(false); 55 | } 56 | 57 | function testPauseVoteRevert() public { 58 | mrc.pause(); 59 | 60 | vm.deal(address(this), 10 ether); 61 | 62 | uint256 totalValue = 0; 63 | for (uint256 i = 0; i < amounts.length; i++) { 64 | totalValue += amounts[i]; 65 | } 66 | 67 | vm.expectRevert(bytes("Pausable: paused")); 68 | mrc.vote{value: totalValue}(votes, rounds, amounts); 69 | } 70 | 71 | function testVotesPassing() public { 72 | vm.deal(address(this), 10 ether); 73 | 74 | uint256 totalValue = 0; 75 | for (uint256 i = 0; i < amounts.length; i++) { 76 | totalValue += amounts[i]; 77 | } 78 | 79 | mrc.vote{value: totalValue}(votes, rounds, amounts); 80 | 81 | /* Assert that votes were passed on correctly */ 82 | for (uint256 i = 0; i < rounds.length; i++) { 83 | bytes[] memory receivedVotes = MockRoundImplementationETH(rounds[i]).getReceivedVotes(); 84 | for (uint256 j = 0; j < receivedVotes.length; j++) { 85 | assertEq(receivedVotes[j], votes[i][j]); 86 | } 87 | } 88 | 89 | /* Assert that amounts were sent along correctly */ 90 | for (uint256 i = 0; i < rounds.length; i++) { 91 | assertEq(address(rounds[i]).balance, amounts[i]); 92 | } 93 | } 94 | 95 | function testVotesLengthCheck() public { 96 | vm.deal(address(this), 10 ether); 97 | 98 | address[] memory roundsWrongLength = new address[](2); 99 | roundsWrongLength[0] = address(round1); 100 | roundsWrongLength[1] = address(round2); 101 | 102 | uint256 totalValue = 0; 103 | for (uint256 i = 0; i < amounts.length; i++) { 104 | totalValue += amounts[i]; 105 | } 106 | 107 | vm.expectRevert(VotesNotEqualRoundsLength.selector); 108 | mrc.vote{value: totalValue}(votes, roundsWrongLength, amounts); 109 | } 110 | 111 | function testAmountsLengthCheck() public { 112 | vm.deal(address(this), 10 ether); 113 | 114 | uint256[] memory wrongAmounts = new uint256[](2); 115 | wrongAmounts[0] = 1; 116 | wrongAmounts[1] = 2; 117 | 118 | uint256 totalValue = 0; 119 | for (uint256 i = 0; i < wrongAmounts.length; i++) { 120 | totalValue += wrongAmounts[i]; 121 | } 122 | 123 | vm.expectRevert(AmountsNotEqualRoundsLength.selector); 124 | mrc.vote{value: totalValue}(votes, rounds, wrongAmounts); 125 | } 126 | 127 | function testExcessAmountSent() public { 128 | vm.deal(address(this), 10 ether); 129 | 130 | uint256 totalValue = 0; 131 | for (uint256 i = 0; i < amounts.length; i++) { 132 | totalValue += amounts[i]; 133 | } 134 | 135 | vm.expectRevert(ExcessAmountSent.selector); 136 | mrc.vote{value: totalValue + 1}(votes, rounds, amounts); 137 | } 138 | 139 | function testVoteDoS() public { 140 | vm.deal(address(this), 10 ether); 141 | 142 | // let's simulate another contract sent 1 ETH 143 | // to the MRC contract during a selfdestruct 144 | vm.deal(address(mrc), 1); 145 | 146 | uint256 totalValue = 0; 147 | for (uint256 i = 0; i < amounts.length; i++) { 148 | totalValue += amounts[i]; 149 | } 150 | 151 | // we need to make sure that `vote` doesn't fail 152 | // instead of checking that the final balance is zero, MRC checks 153 | // that the final balance is equal to the initial one. 154 | mrc.vote{value: totalValue}(votes, rounds, amounts); 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /contracts/tokens/TestDAI.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: AGPL-3.0-or-later 2 | 3 | /// dai.sol -- Dai Stablecoin ERC-20 Token 4 | 5 | pragma solidity ^0.8.17; 6 | 7 | contract TestDAI { 8 | // --- Auth --- 9 | mapping(address => uint256) public wards; 10 | 11 | function rely(address guy) external auth { 12 | wards[guy] = 1; 13 | } 14 | 15 | function deny(address guy) external auth { 16 | wards[guy] = 0; 17 | } 18 | 19 | modifier auth() { 20 | require(wards[msg.sender] == 1, "Dai/not-authorized"); 21 | _; 22 | } 23 | 24 | // --- ERC20 Data --- 25 | string public constant name = "Dai Stablecoin"; 26 | string public constant symbol = "DAI"; 27 | string public constant version = "1"; 28 | uint8 public constant decimals = 18; 29 | uint256 public totalSupply; 30 | 31 | mapping(address => uint256) public balanceOf; 32 | mapping(address => mapping(address => uint256)) public allowance; 33 | mapping(address => uint256) public nonces; 34 | 35 | event Approval(address indexed src, address indexed guy, uint256 wad); 36 | event Transfer(address indexed src, address indexed dst, uint256 wad); 37 | 38 | // --- Math --- 39 | function add(uint256 x, uint256 y) internal pure returns (uint256 z) { 40 | require((z = x + y) >= x); 41 | } 42 | 43 | function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { 44 | require((z = x - y) <= x); 45 | } 46 | 47 | // --- EIP712 niceties --- 48 | bytes32 public DOMAIN_SEPARATOR; 49 | // bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)"); 50 | bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb; 51 | 52 | constructor(uint256 chainId_) { 53 | wards[msg.sender] = 1; 54 | DOMAIN_SEPARATOR = keccak256( 55 | abi.encode( 56 | keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), 57 | keccak256(bytes(name)), 58 | keccak256(bytes(version)), 59 | chainId_, 60 | address(this) 61 | ) 62 | ); 63 | } 64 | 65 | // --- Token --- 66 | function transfer(address dst, uint256 wad) external returns (bool) { 67 | return transferFrom(msg.sender, dst, wad); 68 | } 69 | 70 | function transferFrom(address src, address dst, uint256 wad) public returns (bool) { 71 | require(balanceOf[src] >= wad, "Dai/insufficient-balance"); 72 | if (src != msg.sender && allowance[src][msg.sender] != type(uint256).max) { 73 | require(allowance[src][msg.sender] >= wad, "Dai/insufficient-allowance"); 74 | allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad); 75 | } 76 | balanceOf[src] = sub(balanceOf[src], wad); 77 | balanceOf[dst] = add(balanceOf[dst], wad); 78 | emit Transfer(src, dst, wad); 79 | return true; 80 | } 81 | 82 | function mint(address usr, uint256 wad) external auth { 83 | balanceOf[usr] = add(balanceOf[usr], wad); 84 | totalSupply = add(totalSupply, wad); 85 | emit Transfer(address(0), usr, wad); 86 | } 87 | 88 | function burn(address usr, uint256 wad) external { 89 | require(balanceOf[usr] >= wad, "Dai/insufficient-balance"); 90 | if (usr != msg.sender && allowance[usr][msg.sender] != type(uint256).max) { 91 | require(allowance[usr][msg.sender] >= wad, "Dai/insufficient-allowance"); 92 | allowance[usr][msg.sender] = sub(allowance[usr][msg.sender], wad); 93 | } 94 | balanceOf[usr] = sub(balanceOf[usr], wad); 95 | totalSupply = sub(totalSupply, wad); 96 | emit Transfer(usr, address(0), wad); 97 | } 98 | 99 | function approve(address usr, uint256 wad) external returns (bool) { 100 | allowance[msg.sender][usr] = wad; 101 | emit Approval(msg.sender, usr, wad); 102 | return true; 103 | } 104 | 105 | // --- Alias --- 106 | function push(address usr, uint256 wad) external { 107 | transferFrom(msg.sender, usr, wad); 108 | } 109 | 110 | function pull(address usr, uint256 wad) external { 111 | transferFrom(usr, msg.sender, wad); 112 | } 113 | 114 | function move(address src, address dst, uint256 wad) external { 115 | transferFrom(src, dst, wad); 116 | } 117 | 118 | // --- Approve by signature --- 119 | function permit( 120 | address holder, 121 | address spender, 122 | uint256 nonce, 123 | uint256 expiry, 124 | bool allowed, 125 | uint8 v, 126 | bytes32 r, 127 | bytes32 s 128 | ) external { 129 | bytes32 digest = keccak256( 130 | abi.encodePacked( 131 | "\x19\x01", 132 | DOMAIN_SEPARATOR, 133 | keccak256(abi.encode(PERMIT_TYPEHASH, holder, spender, nonce, expiry, allowed)) 134 | ) 135 | ); 136 | 137 | require(holder != address(0), "Dai/invalid-address-0"); 138 | require(holder == ecrecover(digest, v, r, s), "Dai/invalid-permit"); 139 | require(expiry == 0 || block.timestamp <= expiry, "Dai/permit-expired"); 140 | require(nonce == nonces[holder]++, "Dai/invalid-nonce"); 141 | uint256 wad = allowed ? type(uint256).max : 0; 142 | allowance[holder][spender] = wad; 143 | emit Approval(holder, spender, wad); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from "dotenv"; 2 | import { HardhatUserConfig } from "hardhat/config"; 3 | import "@openzeppelin/hardhat-upgrades"; 4 | import { getEnv } from "./lib/utils"; 5 | import "@nomicfoundation/hardhat-ledger"; 6 | import { ethers } from "ethers"; 7 | import "@xyrusworx/hardhat-solidity-json"; 8 | 9 | dotenv.config(); 10 | 11 | const account = () => { 12 | if (process.env.PRIVATE_KEY) { 13 | return [getEnv("PRIVATE_KEY")]; 14 | } else { 15 | return { 16 | mnemonic: getEnv("MNEMONIC"), 17 | }; 18 | } 19 | }; 20 | 21 | const config: HardhatUserConfig = { 22 | solidity: { 23 | version: "0.8.20", 24 | settings: { 25 | optimizer: { 26 | enabled: true, 27 | runs: 400, 28 | }, 29 | }, 30 | }, 31 | networks: { 32 | hardhat: {}, 33 | localhost: { 34 | accounts: account(), 35 | }, 36 | sepolia: { 37 | url: getEnv("SEPOLIA_RPC_URL"), 38 | accounts: account(), 39 | }, 40 | pgnTestnet: { 41 | url: getEnv("PGN_TESTNET_RPC_URL"), 42 | accounts: account(), 43 | // gasPrice: 1000000000, 44 | }, 45 | arbitrumTestnet: { 46 | url: getEnv("ARBITRUM_TESTNET_RPC_URL"), 47 | ledgerAccounts: [getEnv("HARDWARE_WALLET_ACCOUNT", ethers.ZeroAddress)], 48 | }, 49 | pgn: { 50 | url: getEnv("PGN_RPC_URL"), 51 | ledgerAccounts: [getEnv("HARDWARE_WALLET_ACCOUNT", ethers.ZeroAddress)], 52 | // gas: 3_000_000, 53 | // gasPrice: 1_800000000, 54 | }, 55 | optimism: { 56 | url: getEnv("OPTIMISM_RPC_URL"), 57 | ledgerAccounts: [getEnv("HARDWARE_WALLET_ACCOUNT", ethers.ZeroAddress)], 58 | }, 59 | fantom: { 60 | url: getEnv("FANTOM_RPC_URL"), 61 | ledgerAccounts: [getEnv("HARDWARE_WALLET_ACCOUNT", ethers.ZeroAddress)], 62 | }, 63 | fantomTestnet: { 64 | url: getEnv("FANTOM_TESTNET_RPC_URL"), 65 | ledgerAccounts: [getEnv("HARDWARE_WALLET_ACCOUNT", ethers.ZeroAddress)], 66 | }, 67 | mainnet: { 68 | url: getEnv("MAINNET_RPC_URL"), 69 | ledgerAccounts: [getEnv("HARDWARE_WALLET_ACCOUNT", ethers.ZeroAddress)], 70 | }, 71 | arbitrumOne: { 72 | url: getEnv("ARBITRUM_ONE_RPC_URL"), 73 | ledgerAccounts: [getEnv("HARDWARE_WALLET_ACCOUNT", ethers.ZeroAddress)], 74 | }, 75 | polygonMumbai: { 76 | url: getEnv("POLYGON_MUMBAI_RPC_URL"), 77 | ledgerAccounts: [getEnv("HARDWARE_WALLET_ACCOUNT", ethers.ZeroAddress)], 78 | }, 79 | polygon: { 80 | url: getEnv("POLYGON_RPC_URL"), 81 | ledgerAccounts: [getEnv("HARDWARE_WALLET_ACCOUNT", ethers.ZeroAddress)], 82 | }, 83 | avalancheFuji: { 84 | url: getEnv("AVALANCHE_FUJI_RPC_URL"), 85 | ledgerAccounts: [getEnv("HARDWARE_WALLET_ACCOUNT", ethers.ZeroAddress)], 86 | }, 87 | avalanche: { 88 | url: getEnv("AVALANCHE_RPC_URL"), 89 | ledgerAccounts: [getEnv("HARDWARE_WALLET_ACCOUNT", ethers.ZeroAddress)], 90 | }, 91 | baseSepolia: { 92 | url: getEnv("BASE_SEPOLIA_RPC_URL"), 93 | accounts: account(), 94 | }, 95 | baseGoerli: { 96 | url: getEnv("BASE_GOERLI_RPC_URL"), 97 | accounts: account(), 98 | }, 99 | base: { 100 | url: getEnv("BASE_RPC_URL"), 101 | ledgerAccounts: [getEnv("HARDWARE_WALLET_ACCOUNT", ethers.ZeroAddress)], 102 | }, 103 | scrollSepolia: { 104 | url: getEnv("SCROLL_SEPOLIA_RPC_URL"), 105 | accounts: account(), 106 | }, 107 | scroll: { 108 | url: getEnv("SCROLL_RPC_URL"), 109 | ledgerAccounts: [getEnv("HARDWARE_WALLET_ACCOUNT", ethers.ZeroAddress)], 110 | }, 111 | seiDevnet: { 112 | url: getEnv("SEI_DEVNET_RPC_URL"), 113 | accounts: account(), 114 | }, 115 | seiMainnet: { 116 | url: getEnv("SEI_RPC_URL"), 117 | accounts: account(), 118 | }, 119 | celo: { 120 | url: getEnv("CELO_RPC_URL"), 121 | accounts: account(), 122 | }, 123 | celoAlfajores: { 124 | url: getEnv("CELO_ALFAJORES_RPC_URL"), 125 | accounts: account(), 126 | }, 127 | filecoin: { 128 | url: getEnv("FILECOIN_RPC_URL"), 129 | accounts: account(), 130 | }, 131 | filecoinTestnet: { 132 | url: getEnv("FILECOIN_TESTNET_RPC_URL"), 133 | accounts: account(), 134 | }, 135 | lukso: { 136 | url: getEnv("LUKSO_RPC_URL"), 137 | accounts: account(), 138 | }, 139 | luksoTestnet: { 140 | url: getEnv("LUKSO_TESTNET_RPC_URL"), 141 | accounts: account(), 142 | }, 143 | metisAndromeda: { 144 | url: getEnv("METIS_MAINNET_RPC_URL"), 145 | accounts: account(), 146 | }, 147 | gnosis: { 148 | url: getEnv("GNOSIS_RPC_URL"), 149 | accounts: account(), 150 | }, 151 | hedera: { 152 | url: getEnv("HEDERA_RPC_URL"), 153 | accounts: account(), 154 | }, 155 | }, 156 | etherscan: { 157 | apiKey: { 158 | mainnet: getEnv("ETHERSCAN_ETHEREUM_API_KEY", ""), 159 | sepolia: getEnv("ETHERSCAN_ETHEREUM_API_KEY", ""), 160 | optimisticEthereum: getEnv("ETHERSCAN_OPTIMISM_API_KEY", ""), 161 | opera: getEnv("ETHERSCAN_FANTOM_API_KEY"), 162 | ftmTestnet: getEnv("ETHERSCAN_FANTOM_API_KEY"), 163 | polygon: getEnv("ETHERSCAN_POLYGON_API_KEY"), 164 | polygonMumbai: getEnv("ETHERSCAN_POLYGON_API_KEY"), 165 | avalanche: getEnv("ETHERSCAN_AVALANCHE_API_KEY"), 166 | base: getEnv("ETHERSCAN_BASE_API_KEY"), 167 | scrollSepolia: getEnv("ETHERSCAN_SCROLL_API_KEY"), 168 | scroll: getEnv("ETHERSCAN_SCROLL_API_KEY"), 169 | arbitrumOne: getEnv("ETHERSCAN_ARBITRUM_API_KEY"), 170 | metisAndromeda: "no-api-key", 171 | xdai: getEnv("GNOSISSCAN_API_KEY"), 172 | hedera: getEnv("HEDERA_API_KEY"), 173 | }, 174 | customChains: [ 175 | { 176 | network: "base", 177 | chainId: 8453, 178 | urls: { 179 | apiURL: "https://api.basescan.org/api", 180 | browserURL: "https://basescan.org", 181 | }, 182 | }, 183 | { 184 | network: "arbitrumOne", 185 | chainId: 42161, 186 | urls: { 187 | apiURL: "https://api.arbiscan.io/api", 188 | browserURL: "https://arbiscan.io", 189 | }, 190 | }, 191 | { 192 | network: "scrollSepolia", 193 | chainId: 534351, 194 | urls: { 195 | apiURL: "https://sepolia.scrollscan.com/api", 196 | browserURL: "https://sepolia.scrollscan.com", 197 | }, 198 | }, 199 | { 200 | network: "scroll", 201 | chainId: 534352, 202 | urls: { 203 | apiURL: "https://api.scrollscan.com/api", 204 | browserURL: "https://scrollscan.com", 205 | }, 206 | }, 207 | { 208 | network: "metisAndromeda", 209 | chainId: 1088, 210 | urls: { 211 | apiURL: 212 | "https://api.routescan.io/v2/network/mainnet/evm/1088/etherscan", 213 | browserURL: "https://explorer.metis.io", 214 | }, 215 | }, 216 | { 217 | network: "hedera", 218 | chainId: 295, 219 | urls: { 220 | apiURL: "https://api.hederaexplorer.io/api", 221 | browserURL: "https://explorer.hedera.com", 222 | }, 223 | }, 224 | ], 225 | }, 226 | }; 227 | 228 | export default config; 229 | -------------------------------------------------------------------------------- /test/MRCVoteERC20Permit.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.17; 3 | 4 | import "forge-std/Test.sol"; 5 | import "../contracts/MultiRoundCheckout.sol"; 6 | import "../contracts/mocks/MockRoundImplementationERC20.sol"; 7 | import "../contracts/mocks/MockVotingStrategy.sol"; 8 | import "../contracts/tokens/TestERC20.sol"; 9 | import "../contracts/utils/SigUtils.sol"; 10 | 11 | contract MrcTestVoteERC20Permit is Test { 12 | MultiRoundCheckout private mrc; 13 | TestERC20 private testERC20; 14 | MockRoundImplementationERC20 private round1; 15 | MockRoundImplementationERC20 private round2; 16 | MockRoundImplementationERC20 private round3; 17 | MockVotingStrategy private votingStrategy; 18 | SigUtils private sigUtils; 19 | SigUtils.Permit private permit; 20 | bytes32 private digest; 21 | uint8 private v; 22 | bytes32 private r; 23 | bytes32 private s; 24 | address[] public rounds = new address[](2); 25 | bytes[][] public votes = new bytes[][](2); 26 | uint256[] public amounts = new uint256[](2); 27 | uint256 public totalAmount; 28 | address public project1; 29 | address public project2; 30 | address public owner; 31 | address public token1; 32 | uint256 private ownerPrivateKey; 33 | 34 | function setUp() public { 35 | votingStrategy = new MockVotingStrategy(); 36 | round1 = new MockRoundImplementationERC20(address(votingStrategy)); 37 | round2 = new MockRoundImplementationERC20(address(votingStrategy)); 38 | round3 = new MockRoundImplementationERC20(address(votingStrategy)); 39 | mrc = new MultiRoundCheckout(); 40 | testERC20 = new TestERC20(); 41 | 42 | sigUtils = new SigUtils(testERC20.DOMAIN_SEPARATOR()); 43 | 44 | mrc.initialize(address(1)); 45 | testERC20.initialize("Test", "TEST"); 46 | rounds[0] = address(round1); 47 | rounds[1] = address(round2); 48 | 49 | totalAmount = 100; 50 | 51 | amounts[0] = 50; 52 | amounts[1] = 50; 53 | 54 | token1 = address(testERC20); 55 | 56 | ownerPrivateKey = 0xA11CE; 57 | owner = vm.addr(ownerPrivateKey); 58 | 59 | testERC20.mint(owner, 100); 60 | 61 | votes[0].push(abi.encode(address(testERC20), 25)); 62 | votes[0].push(abi.encode(address(testERC20), 25)); 63 | votes[1].push(abi.encode(address(testERC20), 25)); 64 | votes[1].push(abi.encode(address(testERC20), 25)); 65 | 66 | permit = 67 | SigUtils.Permit({owner: owner, spender: address(mrc), value: 100, nonce: 0, deadline: type(uint256).max}); 68 | 69 | digest = sigUtils.getTypedDataHash(permit); 70 | 71 | (v, r, s) = vm.sign(ownerPrivateKey, digest); 72 | } 73 | 74 | function testVoteERC20Permit() public { 75 | assertEq(testERC20.balanceOf(owner), 100); 76 | assertEq(testERC20.allowance(owner, address(mrc)), 0); 77 | 78 | vm.prank(owner); 79 | mrc.voteERC20Permit(votes, rounds, amounts, totalAmount, token1, type(uint256).max, v, r, s); 80 | 81 | assertEq(testERC20.allowance(owner, address(mrc)), 0); 82 | assertEq(testERC20.balanceOf(owner), 0); 83 | assertEq(testERC20.balanceOf(address(votingStrategy)), 100); 84 | } 85 | 86 | function testNonReentrant() public { 87 | MockRoundImplementationERC20(rounds[0]).setReentrant(true); 88 | 89 | vm.expectRevert(bytes("ReentrancyGuard: reentrant call")); 90 | vm.prank(owner); 91 | mrc.voteERC20Permit(votes, rounds, amounts, totalAmount, token1, type(uint256).max, v, r, s); 92 | MockRoundImplementationERC20(rounds[0]).setReentrant(false); 93 | } 94 | 95 | function testPauseVoteRevert() public { 96 | mrc.pause(); 97 | 98 | vm.expectRevert(bytes("Pausable: paused")); 99 | vm.prank(owner); 100 | mrc.voteERC20Permit(votes, rounds, amounts, totalAmount, token1, type(uint256).max, v, r, s); 101 | } 102 | 103 | function testVotesLengthCheck() public { 104 | address[] memory roundsWrongLength = new address[](3); 105 | roundsWrongLength[0] = address(round1); 106 | roundsWrongLength[1] = address(round2); 107 | roundsWrongLength[2] = address(round3); 108 | 109 | vm.expectRevert(VotesNotEqualRoundsLength.selector); 110 | mrc.voteERC20Permit(votes, roundsWrongLength, amounts, totalAmount, token1, type(uint256).max, v, r, s); 111 | } 112 | 113 | function testAmountsLengthCheck() public { 114 | uint256[] memory wrongAmounts = new uint256[](3); 115 | wrongAmounts[0] = 1; 116 | wrongAmounts[1] = 2; 117 | wrongAmounts[2] = 3; 118 | 119 | vm.expectRevert(AmountsNotEqualRoundsLength.selector); 120 | mrc.voteERC20Permit(votes, rounds, wrongAmounts, totalAmount, token1, type(uint256).max, v, r, s); 121 | } 122 | 123 | function testExcessAmountSent() public { 124 | uint256 ownerPrivateKey2 = 0xA11CF; 125 | address owner2 = vm.addr(ownerPrivateKey2); 126 | uint256 totalAmount2 = 110; 127 | 128 | testERC20.mint(owner2, 110); 129 | 130 | SigUtils.Permit memory permit2 = 131 | SigUtils.Permit({owner: owner2, spender: address(mrc), value: 110, nonce: 0, deadline: type(uint256).max}); 132 | 133 | bytes32 digest2 = sigUtils.getTypedDataHash(permit2); 134 | 135 | (uint8 v2, bytes32 r2, bytes32 s2) = vm.sign(ownerPrivateKey2, digest2); 136 | 137 | vm.prank(owner2); 138 | vm.expectRevert(ExcessAmountSent.selector); 139 | mrc.voteERC20Permit(votes, rounds, amounts, totalAmount2, token1, type(uint256).max, v2, r2, s2); 140 | } 141 | 142 | function testPermitAlreadyExistsAndVoteERC20PermitDoesNotRevert() public { 143 | vm.prank(owner); 144 | TestERC20(address(testERC20)).permit(owner, address(mrc), 100, type(uint256).max, v, r, s); 145 | 146 | // invalid permit with wrong value and nonce 147 | SigUtils.Permit memory permit3 = 148 | SigUtils.Permit({owner: owner, spender: address(mrc), value: 10, nonce: 5, deadline: type(uint256).max}); 149 | 150 | bytes32 digest3 = sigUtils.getTypedDataHash(permit3); 151 | 152 | (uint8 v3, bytes32 r3, bytes32 s3) = vm.sign(ownerPrivateKey, digest3); 153 | 154 | vm.prank(owner); 155 | mrc.voteERC20Permit(votes, rounds, amounts, totalAmount, token1, type(uint256).max, v3, r3, s3); 156 | 157 | assertEq(testERC20.balanceOf(owner), 0); 158 | assertEq(testERC20.balanceOf(address(votingStrategy)), 100); 159 | } 160 | 161 | function testPermitDoesNotExistAndVoteERC20PermitReverts() public { 162 | // invalid permit with wrong nonce 163 | SigUtils.Permit memory permit3 = 164 | SigUtils.Permit({owner: owner, spender: address(mrc), value: 100, nonce: 5, deadline: type(uint256).max}); 165 | 166 | bytes32 digest3 = sigUtils.getTypedDataHash(permit3); 167 | 168 | (uint8 v3, bytes32 r3, bytes32 s3) = vm.sign(ownerPrivateKey, digest3); 169 | 170 | vm.expectRevert("ERC20Permit: invalid signature"); 171 | vm.prank(owner); 172 | mrc.voteERC20Permit(votes, rounds, amounts, totalAmount, token1, type(uint256).max, v3, r3, s3); 173 | } 174 | 175 | function testVoteERC20DoS() public { 176 | testERC20.mint(address(mrc), 1); 177 | 178 | assertEq(testERC20.balanceOf(owner), 100); 179 | assertEq(testERC20.balanceOf(address(mrc)), 1); 180 | assertEq(testERC20.allowance(owner, address(mrc)), 0); 181 | 182 | // we need to make sure that `vote` doesn't fail 183 | // instead of checking that the final balance is zero, MRC checks 184 | // that the final balance is equal to the initial one. 185 | vm.prank(owner); 186 | mrc.voteERC20Permit(votes, rounds, amounts, totalAmount, token1, type(uint256).max, v, r, s); 187 | 188 | assertEq(testERC20.allowance(owner, address(mrc)), 0); 189 | assertEq(testERC20.balanceOf(owner), 0); 190 | assertEq(testERC20.balanceOf(address(votingStrategy)), 100); 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /test/MRCVoteDAIPermit.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.17; 3 | 4 | import "forge-std/Test.sol"; 5 | import "../contracts/MultiRoundCheckout.sol"; 6 | import "../contracts/mocks/MockRoundImplementationDAI.sol"; 7 | import "../contracts/mocks/MockVotingStrategy.sol"; 8 | import "../contracts/tokens/TestDAI.sol"; 9 | import "../contracts/utils/SigUtilsDAI.sol"; 10 | 11 | contract MrcTestVoteDAIPermit is Test { 12 | MultiRoundCheckout private mrc; 13 | TestDAI private testDAI; 14 | MockRoundImplementationDAI private round1; 15 | MockRoundImplementationDAI private round2; 16 | MockRoundImplementationDAI private round3; 17 | MockVotingStrategy private votingStrategy; 18 | SigUtilsDAI private sigUtilsDAI; 19 | SigUtilsDAI.Permit private permit; 20 | bytes32 private digest; 21 | uint8 private v; 22 | bytes32 private r; 23 | bytes32 private s; 24 | address[] public rounds = new address[](2); 25 | bytes[][] public votes = new bytes[][](2); 26 | uint256[] public amounts = new uint256[](2); 27 | uint256 public totalAmount; 28 | address public project1; 29 | address public project2; 30 | address public owner; 31 | address public token1; 32 | uint256 private ownerPrivateKey; 33 | uint256 private chainId; 34 | uint256 private nonce; 35 | 36 | function setUp() public { 37 | votingStrategy = new MockVotingStrategy(); 38 | round1 = new MockRoundImplementationDAI(address(votingStrategy)); 39 | round2 = new MockRoundImplementationDAI(address(votingStrategy)); 40 | round3 = new MockRoundImplementationDAI(address(votingStrategy)); 41 | mrc = new MultiRoundCheckout(); 42 | chainId = 1; 43 | nonce = 0; 44 | testDAI = new TestDAI(chainId); 45 | 46 | sigUtilsDAI = new SigUtilsDAI(testDAI.DOMAIN_SEPARATOR()); 47 | 48 | mrc.initialize(address(1)); 49 | rounds[0] = address(round1); 50 | rounds[1] = address(round2); 51 | 52 | totalAmount = 100; 53 | 54 | amounts[0] = 50; 55 | amounts[1] = 50; 56 | 57 | token1 = address(testDAI); 58 | 59 | ownerPrivateKey = 0xA11CE; 60 | owner = vm.addr(ownerPrivateKey); 61 | 62 | testDAI.mint(owner, 100); 63 | 64 | votes[0].push(abi.encode(address(testDAI), 25)); 65 | votes[0].push(abi.encode(address(testDAI), 25)); 66 | votes[1].push(abi.encode(address(testDAI), 25)); 67 | votes[1].push(abi.encode(address(testDAI), 25)); 68 | 69 | permit = SigUtilsDAI.Permit({ 70 | holder: owner, 71 | spender: address(mrc), 72 | nonce: nonce, 73 | expiry: type(uint256).max, 74 | allowed: true 75 | }); 76 | 77 | digest = sigUtilsDAI.getTypedDataHash(permit); 78 | 79 | (v, r, s) = vm.sign(ownerPrivateKey, digest); 80 | } 81 | 82 | function testVoteDAIPermit() public { 83 | assertEq(testDAI.balanceOf(owner), 100); 84 | assertEq(testDAI.allowance(owner, address(mrc)), 0); 85 | 86 | vm.prank(owner); 87 | mrc.voteDAIPermit(votes, rounds, amounts, totalAmount, token1, type(uint256).max, nonce, v, r, s); 88 | 89 | assertEq(testDAI.balanceOf(owner), 0); 90 | assertEq(testDAI.balanceOf(address(votingStrategy)), 100); 91 | } 92 | 93 | function testNonReentrant() public { 94 | MockRoundImplementationDAI(rounds[0]).setReentrant(true); 95 | 96 | vm.expectRevert(bytes("ReentrancyGuard: reentrant call")); 97 | vm.prank(owner); 98 | mrc.voteDAIPermit(votes, rounds, amounts, totalAmount, token1, type(uint256).max, nonce, v, r, s); 99 | MockRoundImplementationDAI(rounds[0]).setReentrant(false); 100 | } 101 | 102 | function testPauseVoteRevert() public { 103 | mrc.pause(); 104 | 105 | vm.expectRevert(bytes("Pausable: paused")); 106 | vm.prank(owner); 107 | mrc.voteDAIPermit(votes, rounds, amounts, totalAmount, token1, type(uint256).max, nonce, v, r, s); 108 | } 109 | 110 | function testVotesLengthCheck() public { 111 | address[] memory roundsWrongLength = new address[](3); 112 | roundsWrongLength[0] = address(round1); 113 | roundsWrongLength[1] = address(round2); 114 | roundsWrongLength[2] = address(round3); 115 | 116 | vm.expectRevert(VotesNotEqualRoundsLength.selector); 117 | mrc.voteDAIPermit(votes, roundsWrongLength, amounts, totalAmount, token1, type(uint256).max, nonce, v, r, s); 118 | } 119 | 120 | function testAmountsLengthCheck() public { 121 | uint256[] memory wrongAmounts = new uint256[](3); 122 | wrongAmounts[0] = 1; 123 | wrongAmounts[1] = 2; 124 | wrongAmounts[2] = 3; 125 | 126 | vm.expectRevert(AmountsNotEqualRoundsLength.selector); 127 | mrc.voteDAIPermit(votes, rounds, wrongAmounts, totalAmount, token1, type(uint256).max, nonce, v, r, s); 128 | } 129 | 130 | function testExcessAmountSent() public { 131 | uint256 ownerPrivateKey2 = 0xA11CF; 132 | address owner2 = vm.addr(ownerPrivateKey2); 133 | uint256 totalAmount2 = 110; 134 | 135 | testDAI.mint(owner2, 110); 136 | 137 | SigUtilsDAI.Permit memory permit2 = SigUtilsDAI.Permit({ 138 | holder: owner2, 139 | spender: address(mrc), 140 | nonce: nonce, 141 | expiry: type(uint256).max, 142 | allowed: true 143 | }); 144 | 145 | bytes32 digest2 = sigUtilsDAI.getTypedDataHash(permit2); 146 | 147 | (uint8 v2, bytes32 r2, bytes32 s2) = vm.sign(ownerPrivateKey2, digest2); 148 | 149 | vm.prank(owner2); 150 | vm.expectRevert(ExcessAmountSent.selector); 151 | mrc.voteDAIPermit(votes, rounds, amounts, totalAmount2, token1, type(uint256).max, nonce, v2, r2, s2); 152 | } 153 | 154 | function testPermitAlreadyExistsAndVoteDAIPermitDoesNotRevert() public { 155 | vm.prank(owner); 156 | TestDAI(address(testDAI)).permit(owner, address(mrc), nonce, type(uint256).max, true, v, r, s); 157 | 158 | // invalid permit with wrong nonce 159 | SigUtilsDAI.Permit memory permit3 = SigUtilsDAI.Permit({ 160 | holder: owner, 161 | spender: address(mrc), 162 | nonce: 5, 163 | expiry: type(uint256).max, 164 | allowed: true 165 | }); 166 | 167 | bytes32 digest3 = sigUtilsDAI.getTypedDataHash(permit3); 168 | 169 | (uint8 v3, bytes32 r3, bytes32 s3) = vm.sign(ownerPrivateKey, digest3); 170 | 171 | vm.prank(owner); 172 | mrc.voteDAIPermit(votes, rounds, amounts, totalAmount, token1, type(uint256).max, nonce, v3, r3, s3); 173 | 174 | assertEq(testDAI.balanceOf(owner), 0); 175 | assertEq(testDAI.balanceOf(address(votingStrategy)), 100); 176 | } 177 | 178 | function testPermitDoesNotExistAndVoteDAIPermitReverts() public { 179 | // invalid permit with wrong nonce 180 | SigUtilsDAI.Permit memory permit3 = SigUtilsDAI.Permit({ 181 | holder: owner, 182 | spender: address(mrc), 183 | nonce: 5, 184 | expiry: type(uint256).max, 185 | allowed: true 186 | }); 187 | 188 | bytes32 digest3 = sigUtilsDAI.getTypedDataHash(permit3); 189 | 190 | (uint8 v3, bytes32 r3, bytes32 s3) = vm.sign(ownerPrivateKey, digest3); 191 | 192 | vm.expectRevert("Dai/invalid-permit"); 193 | vm.prank(owner); 194 | mrc.voteDAIPermit(votes, rounds, amounts, totalAmount, token1, type(uint256).max, nonce, v3, r3, s3); 195 | } 196 | 197 | function testVoteDAIDoS() public { 198 | testDAI.mint(address(mrc), 1); 199 | 200 | assertEq(testDAI.balanceOf(owner), 100); 201 | /* assertEq(testDAI.balanceOf(address(mrc)), 1); */ 202 | assertEq(testDAI.allowance(owner, address(mrc)), 0); 203 | 204 | // we need to make sure that `vote` doesn't fail 205 | // instead of checking that the final balance is zero, MRC checks 206 | // that the final balance is equal to the initial one. 207 | vm.prank(owner); 208 | mrc.voteDAIPermit(votes, rounds, amounts, totalAmount, token1, type(uint256).max, nonce, v, r, s); 209 | 210 | /* assertEq(testDAI.allowance(owner, address(mrc)), 0); */ 211 | assertEq(testDAI.balanceOf(owner), 0); 212 | assertEq(testDAI.balanceOf(address(votingStrategy)), 100); 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /.openzeppelin/mainnet.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x15BAEfBab37e0866Aee51a3b93161290fdE57401", 5 | "txHash": "0xe5d4573e0cb8840536cb8f2eba208b466e25f6f0f7e99aa6bfad4fe890f331d2" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x3bA9DF642f5e895DC76d3Aa9e4CE8291108E65b1", 10 | "txHash": "0x493dc7d694324711334213e0cad16bb4db3c9d2009fa46998b98c89eea370135", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "fc7421aad9cc9e702dfe5f50541c858cdc57337746ef1310b5ab7190098a1ede": { 16 | "address": "0xb04d05ec760DC16D66168C20927F41F0974Cc29b", 17 | "txHash": "0x96ad641cc096ec9120ce35b8022966022d82cc77d784fb1ee3e4c7c785076234", 18 | "layout": { 19 | "solcVersion": "0.8.18", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | } 94 | ], 95 | "types": { 96 | "t_address": { 97 | "label": "address", 98 | "numberOfBytes": "20" 99 | }, 100 | "t_array(t_uint256)49_storage": { 101 | "label": "uint256[49]", 102 | "numberOfBytes": "1568" 103 | }, 104 | "t_array(t_uint256)50_storage": { 105 | "label": "uint256[50]", 106 | "numberOfBytes": "1600" 107 | }, 108 | "t_bool": { 109 | "label": "bool", 110 | "numberOfBytes": "1" 111 | }, 112 | "t_uint256": { 113 | "label": "uint256", 114 | "numberOfBytes": "32" 115 | }, 116 | "t_uint8": { 117 | "label": "uint8", 118 | "numberOfBytes": "1" 119 | } 120 | } 121 | } 122 | }, 123 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 124 | "address": "0xB494E77A1414B9Ab00Dd5A06Fb941F317e2AF1dc", 125 | "txHash": "0xaf0629bfb26796aa03e59d3c8e6198ac0c54ae695fc7a231f353f3f03380432f", 126 | "layout": { 127 | "solcVersion": "0.8.20", 128 | "storage": [ 129 | { 130 | "label": "_initialized", 131 | "offset": 0, 132 | "slot": "0", 133 | "type": "t_uint8", 134 | "contract": "Initializable", 135 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 136 | "retypedFrom": "bool" 137 | }, 138 | { 139 | "label": "_initializing", 140 | "offset": 1, 141 | "slot": "0", 142 | "type": "t_bool", 143 | "contract": "Initializable", 144 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 145 | }, 146 | { 147 | "label": "__gap", 148 | "offset": 0, 149 | "slot": "1", 150 | "type": "t_array(t_uint256)50_storage", 151 | "contract": "ContextUpgradeable", 152 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 153 | }, 154 | { 155 | "label": "_owner", 156 | "offset": 0, 157 | "slot": "51", 158 | "type": "t_address", 159 | "contract": "OwnableUpgradeable", 160 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 161 | }, 162 | { 163 | "label": "__gap", 164 | "offset": 0, 165 | "slot": "52", 166 | "type": "t_array(t_uint256)49_storage", 167 | "contract": "OwnableUpgradeable", 168 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 169 | }, 170 | { 171 | "label": "_paused", 172 | "offset": 0, 173 | "slot": "101", 174 | "type": "t_bool", 175 | "contract": "PausableUpgradeable", 176 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 177 | }, 178 | { 179 | "label": "__gap", 180 | "offset": 0, 181 | "slot": "102", 182 | "type": "t_array(t_uint256)49_storage", 183 | "contract": "PausableUpgradeable", 184 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 185 | }, 186 | { 187 | "label": "_status", 188 | "offset": 0, 189 | "slot": "151", 190 | "type": "t_uint256", 191 | "contract": "ReentrancyGuardUpgradeable", 192 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 193 | }, 194 | { 195 | "label": "__gap", 196 | "offset": 0, 197 | "slot": "152", 198 | "type": "t_array(t_uint256)49_storage", 199 | "contract": "ReentrancyGuardUpgradeable", 200 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 201 | }, 202 | { 203 | "label": "allo", 204 | "offset": 0, 205 | "slot": "201", 206 | "type": "t_contract(IAllo)1014", 207 | "contract": "MultiRoundCheckout", 208 | "src": "contracts/MultiRoundCheckout.sol:206" 209 | } 210 | ], 211 | "types": { 212 | "t_address": { 213 | "label": "address", 214 | "numberOfBytes": "20" 215 | }, 216 | "t_array(t_uint256)49_storage": { 217 | "label": "uint256[49]", 218 | "numberOfBytes": "1568" 219 | }, 220 | "t_array(t_uint256)50_storage": { 221 | "label": "uint256[50]", 222 | "numberOfBytes": "1600" 223 | }, 224 | "t_bool": { 225 | "label": "bool", 226 | "numberOfBytes": "1" 227 | }, 228 | "t_contract(IAllo)1014": { 229 | "label": "contract IAllo", 230 | "numberOfBytes": "20" 231 | }, 232 | "t_uint256": { 233 | "label": "uint256", 234 | "numberOfBytes": "32" 235 | }, 236 | "t_uint8": { 237 | "label": "uint8", 238 | "numberOfBytes": "1" 239 | } 240 | }, 241 | "namespaces": {} 242 | } 243 | } 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /.openzeppelin/optimism.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x62a850d7805f3Ae382C6eEf7eEB89A31f68Ce2d5", 5 | "txHash": "0x788f8d3ef39c0c36907f9018acf5ada8dac0b774ebea41b5f8212eb8e22bcdd9" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x15fa08599EB017F89c1712d0Fe76138899FdB9db", 10 | "txHash": "0xd496caf0ff39a6ff16864b02423e5ebb0d397e27fd5bc02b262f2e57602e3548", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "fc7421aad9cc9e702dfe5f50541c858cdc57337746ef1310b5ab7190098a1ede": { 16 | "address": "0x9086d7F2599a5BE83Ade8aa90FB447968f66D832", 17 | "txHash": "0xfc08b81caa86f3ec7d3eb272093e27952fbdf6b83cb8eca8e21f491c4a826805", 18 | "layout": { 19 | "solcVersion": "0.8.18", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | } 94 | ], 95 | "types": { 96 | "t_address": { 97 | "label": "address", 98 | "numberOfBytes": "20" 99 | }, 100 | "t_array(t_uint256)49_storage": { 101 | "label": "uint256[49]", 102 | "numberOfBytes": "1568" 103 | }, 104 | "t_array(t_uint256)50_storage": { 105 | "label": "uint256[50]", 106 | "numberOfBytes": "1600" 107 | }, 108 | "t_bool": { 109 | "label": "bool", 110 | "numberOfBytes": "1" 111 | }, 112 | "t_uint256": { 113 | "label": "uint256", 114 | "numberOfBytes": "32" 115 | }, 116 | "t_uint8": { 117 | "label": "uint8", 118 | "numberOfBytes": "1" 119 | } 120 | } 121 | } 122 | }, 123 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 124 | "address": "0x6583bae2B54ab200e1Dee9bd1e7f254D2F93D72D", 125 | "txHash": "0x5d45edac2c30c3aed83258ce699969d2f03a4409cdc615c9ee1cbc99e14357e8", 126 | "layout": { 127 | "solcVersion": "0.8.20", 128 | "storage": [ 129 | { 130 | "label": "_initialized", 131 | "offset": 0, 132 | "slot": "0", 133 | "type": "t_uint8", 134 | "contract": "Initializable", 135 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 136 | "retypedFrom": "bool" 137 | }, 138 | { 139 | "label": "_initializing", 140 | "offset": 1, 141 | "slot": "0", 142 | "type": "t_bool", 143 | "contract": "Initializable", 144 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 145 | }, 146 | { 147 | "label": "__gap", 148 | "offset": 0, 149 | "slot": "1", 150 | "type": "t_array(t_uint256)50_storage", 151 | "contract": "ContextUpgradeable", 152 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 153 | }, 154 | { 155 | "label": "_owner", 156 | "offset": 0, 157 | "slot": "51", 158 | "type": "t_address", 159 | "contract": "OwnableUpgradeable", 160 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 161 | }, 162 | { 163 | "label": "__gap", 164 | "offset": 0, 165 | "slot": "52", 166 | "type": "t_array(t_uint256)49_storage", 167 | "contract": "OwnableUpgradeable", 168 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 169 | }, 170 | { 171 | "label": "_paused", 172 | "offset": 0, 173 | "slot": "101", 174 | "type": "t_bool", 175 | "contract": "PausableUpgradeable", 176 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 177 | }, 178 | { 179 | "label": "__gap", 180 | "offset": 0, 181 | "slot": "102", 182 | "type": "t_array(t_uint256)49_storage", 183 | "contract": "PausableUpgradeable", 184 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 185 | }, 186 | { 187 | "label": "_status", 188 | "offset": 0, 189 | "slot": "151", 190 | "type": "t_uint256", 191 | "contract": "ReentrancyGuardUpgradeable", 192 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 193 | }, 194 | { 195 | "label": "__gap", 196 | "offset": 0, 197 | "slot": "152", 198 | "type": "t_array(t_uint256)49_storage", 199 | "contract": "ReentrancyGuardUpgradeable", 200 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 201 | }, 202 | { 203 | "label": "allo", 204 | "offset": 0, 205 | "slot": "201", 206 | "type": "t_contract(IAllo)1014", 207 | "contract": "MultiRoundCheckout", 208 | "src": "contracts/MultiRoundCheckout.sol:206" 209 | } 210 | ], 211 | "types": { 212 | "t_address": { 213 | "label": "address", 214 | "numberOfBytes": "20" 215 | }, 216 | "t_array(t_uint256)49_storage": { 217 | "label": "uint256[49]", 218 | "numberOfBytes": "1568" 219 | }, 220 | "t_array(t_uint256)50_storage": { 221 | "label": "uint256[50]", 222 | "numberOfBytes": "1600" 223 | }, 224 | "t_bool": { 225 | "label": "bool", 226 | "numberOfBytes": "1" 227 | }, 228 | "t_contract(IAllo)1014": { 229 | "label": "contract IAllo", 230 | "numberOfBytes": "20" 231 | }, 232 | "t_uint256": { 233 | "label": "uint256", 234 | "numberOfBytes": "32" 235 | }, 236 | "t_uint8": { 237 | "label": "uint8", 238 | "numberOfBytes": "1" 239 | } 240 | }, 241 | "namespaces": {} 242 | } 243 | } 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /.openzeppelin/polygon.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x7C24f3494CC958CF268a92b45D7e54310d161794", 5 | "txHash": "0xcc1ae55cae96cd7f3b710bda66a293c7a1dda52313afefad63435aa2cfb8c1a3" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0xe04d9e9CcDf65EB1Db51E56C04beE4c8582edB73", 10 | "txHash": "0xf10ad162c3bab70f1e35434b2c6acddcb6a03c9f1ca0f0dab18cc6f6aa19aa88", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "fc7421aad9cc9e702dfe5f50541c858cdc57337746ef1310b5ab7190098a1ede": { 16 | "address": "0x8e1bD5Da87C14dd8e08F7ecc2aBf9D1d558ea174", 17 | "txHash": "0xf772c335033e06496f95ee793d7ed5703ca52c71dafcc1cba52a6246ea1d0dea", 18 | "layout": { 19 | "solcVersion": "0.8.18", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | } 94 | ], 95 | "types": { 96 | "t_address": { 97 | "label": "address", 98 | "numberOfBytes": "20" 99 | }, 100 | "t_array(t_uint256)49_storage": { 101 | "label": "uint256[49]", 102 | "numberOfBytes": "1568" 103 | }, 104 | "t_array(t_uint256)50_storage": { 105 | "label": "uint256[50]", 106 | "numberOfBytes": "1600" 107 | }, 108 | "t_bool": { 109 | "label": "bool", 110 | "numberOfBytes": "1" 111 | }, 112 | "t_uint256": { 113 | "label": "uint256", 114 | "numberOfBytes": "32" 115 | }, 116 | "t_uint8": { 117 | "label": "uint8", 118 | "numberOfBytes": "1" 119 | } 120 | } 121 | } 122 | }, 123 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 124 | "address": "0x01D196aEC858C0F466aD8B244b8468889Fc77EBb", 125 | "txHash": "0x7aa3521ec4c0a74c2c9d1de2ee2b2cba326b33d649647e497adb3d9b8863f05e", 126 | "layout": { 127 | "solcVersion": "0.8.20", 128 | "storage": [ 129 | { 130 | "label": "_initialized", 131 | "offset": 0, 132 | "slot": "0", 133 | "type": "t_uint8", 134 | "contract": "Initializable", 135 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 136 | "retypedFrom": "bool" 137 | }, 138 | { 139 | "label": "_initializing", 140 | "offset": 1, 141 | "slot": "0", 142 | "type": "t_bool", 143 | "contract": "Initializable", 144 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 145 | }, 146 | { 147 | "label": "__gap", 148 | "offset": 0, 149 | "slot": "1", 150 | "type": "t_array(t_uint256)50_storage", 151 | "contract": "ContextUpgradeable", 152 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 153 | }, 154 | { 155 | "label": "_owner", 156 | "offset": 0, 157 | "slot": "51", 158 | "type": "t_address", 159 | "contract": "OwnableUpgradeable", 160 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 161 | }, 162 | { 163 | "label": "__gap", 164 | "offset": 0, 165 | "slot": "52", 166 | "type": "t_array(t_uint256)49_storage", 167 | "contract": "OwnableUpgradeable", 168 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 169 | }, 170 | { 171 | "label": "_paused", 172 | "offset": 0, 173 | "slot": "101", 174 | "type": "t_bool", 175 | "contract": "PausableUpgradeable", 176 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 177 | }, 178 | { 179 | "label": "__gap", 180 | "offset": 0, 181 | "slot": "102", 182 | "type": "t_array(t_uint256)49_storage", 183 | "contract": "PausableUpgradeable", 184 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 185 | }, 186 | { 187 | "label": "_status", 188 | "offset": 0, 189 | "slot": "151", 190 | "type": "t_uint256", 191 | "contract": "ReentrancyGuardUpgradeable", 192 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 193 | }, 194 | { 195 | "label": "__gap", 196 | "offset": 0, 197 | "slot": "152", 198 | "type": "t_array(t_uint256)49_storage", 199 | "contract": "ReentrancyGuardUpgradeable", 200 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 201 | }, 202 | { 203 | "label": "allo", 204 | "offset": 0, 205 | "slot": "201", 206 | "type": "t_contract(IAllo)1014", 207 | "contract": "MultiRoundCheckout", 208 | "src": "contracts/MultiRoundCheckout.sol:206" 209 | } 210 | ], 211 | "types": { 212 | "t_address": { 213 | "label": "address", 214 | "numberOfBytes": "20" 215 | }, 216 | "t_array(t_uint256)49_storage": { 217 | "label": "uint256[49]", 218 | "numberOfBytes": "1568" 219 | }, 220 | "t_array(t_uint256)50_storage": { 221 | "label": "uint256[50]", 222 | "numberOfBytes": "1600" 223 | }, 224 | "t_bool": { 225 | "label": "bool", 226 | "numberOfBytes": "1" 227 | }, 228 | "t_contract(IAllo)1014": { 229 | "label": "contract IAllo", 230 | "numberOfBytes": "20" 231 | }, 232 | "t_uint256": { 233 | "label": "uint256", 234 | "numberOfBytes": "32" 235 | }, 236 | "t_uint8": { 237 | "label": "uint8", 238 | "numberOfBytes": "1" 239 | } 240 | }, 241 | "namespaces": {} 242 | } 243 | } 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /.openzeppelin/arbitrum-one.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0xec77FccE4f0396BaB43BC66a513157Ee59EE07c7", 5 | "txHash": "0xd23df95a1ffebb7de397b9c18715336a1be444ec7ff9e1e120f8ff1c676f7871" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x8e1bD5Da87C14dd8e08F7ecc2aBf9D1d558ea174", 10 | "txHash": "0xe5f75c7a32f05e4c05f67d1b784a0439ee65010f3faa9199a0ed10d9d9ae0ead", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "fc7421aad9cc9e702dfe5f50541c858cdc57337746ef1310b5ab7190098a1ede": { 16 | "address": "0xbce556cf365E631fF50449211A6f2CB8936f40D1", 17 | "txHash": "0x5030a0228c61692f21a4fe7cb2b38ffc86ca3685a5ad82d0ed24501b1a6b48b6", 18 | "layout": { 19 | "solcVersion": "0.8.18", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | } 94 | ], 95 | "types": { 96 | "t_address": { 97 | "label": "address", 98 | "numberOfBytes": "20" 99 | }, 100 | "t_array(t_uint256)49_storage": { 101 | "label": "uint256[49]", 102 | "numberOfBytes": "1568" 103 | }, 104 | "t_array(t_uint256)50_storage": { 105 | "label": "uint256[50]", 106 | "numberOfBytes": "1600" 107 | }, 108 | "t_bool": { 109 | "label": "bool", 110 | "numberOfBytes": "1" 111 | }, 112 | "t_uint256": { 113 | "label": "uint256", 114 | "numberOfBytes": "32" 115 | }, 116 | "t_uint8": { 117 | "label": "uint8", 118 | "numberOfBytes": "1" 119 | } 120 | } 121 | } 122 | }, 123 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 124 | "address": "0x62a850d7805f3Ae382C6eEf7eEB89A31f68Ce2d5", 125 | "txHash": "0xb4ca16470f8f7d4a7650c1b7ce375728aa9706a709e588391385db2d1ddbb4ce", 126 | "layout": { 127 | "solcVersion": "0.8.20", 128 | "storage": [ 129 | { 130 | "label": "_initialized", 131 | "offset": 0, 132 | "slot": "0", 133 | "type": "t_uint8", 134 | "contract": "Initializable", 135 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 136 | "retypedFrom": "bool" 137 | }, 138 | { 139 | "label": "_initializing", 140 | "offset": 1, 141 | "slot": "0", 142 | "type": "t_bool", 143 | "contract": "Initializable", 144 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 145 | }, 146 | { 147 | "label": "__gap", 148 | "offset": 0, 149 | "slot": "1", 150 | "type": "t_array(t_uint256)50_storage", 151 | "contract": "ContextUpgradeable", 152 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 153 | }, 154 | { 155 | "label": "_owner", 156 | "offset": 0, 157 | "slot": "51", 158 | "type": "t_address", 159 | "contract": "OwnableUpgradeable", 160 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 161 | }, 162 | { 163 | "label": "__gap", 164 | "offset": 0, 165 | "slot": "52", 166 | "type": "t_array(t_uint256)49_storage", 167 | "contract": "OwnableUpgradeable", 168 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 169 | }, 170 | { 171 | "label": "_paused", 172 | "offset": 0, 173 | "slot": "101", 174 | "type": "t_bool", 175 | "contract": "PausableUpgradeable", 176 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 177 | }, 178 | { 179 | "label": "__gap", 180 | "offset": 0, 181 | "slot": "102", 182 | "type": "t_array(t_uint256)49_storage", 183 | "contract": "PausableUpgradeable", 184 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 185 | }, 186 | { 187 | "label": "_status", 188 | "offset": 0, 189 | "slot": "151", 190 | "type": "t_uint256", 191 | "contract": "ReentrancyGuardUpgradeable", 192 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 193 | }, 194 | { 195 | "label": "__gap", 196 | "offset": 0, 197 | "slot": "152", 198 | "type": "t_array(t_uint256)49_storage", 199 | "contract": "ReentrancyGuardUpgradeable", 200 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 201 | }, 202 | { 203 | "label": "allo", 204 | "offset": 0, 205 | "slot": "201", 206 | "type": "t_contract(IAllo)1014", 207 | "contract": "MultiRoundCheckout", 208 | "src": "contracts/MultiRoundCheckout.sol:206" 209 | } 210 | ], 211 | "types": { 212 | "t_address": { 213 | "label": "address", 214 | "numberOfBytes": "20" 215 | }, 216 | "t_array(t_uint256)49_storage": { 217 | "label": "uint256[49]", 218 | "numberOfBytes": "1568" 219 | }, 220 | "t_array(t_uint256)50_storage": { 221 | "label": "uint256[50]", 222 | "numberOfBytes": "1600" 223 | }, 224 | "t_bool": { 225 | "label": "bool", 226 | "numberOfBytes": "1" 227 | }, 228 | "t_contract(IAllo)1014": { 229 | "label": "contract IAllo", 230 | "numberOfBytes": "20" 231 | }, 232 | "t_uint256": { 233 | "label": "uint256", 234 | "numberOfBytes": "32" 235 | }, 236 | "t_uint8": { 237 | "label": "uint8", 238 | "numberOfBytes": "1" 239 | } 240 | }, 241 | "namespaces": {} 242 | } 243 | } 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /.openzeppelin/avalanche.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x7C24f3494CC958CF268a92b45D7e54310d161794", 5 | "txHash": "0x346c0fa6b5690838cc7a3bf02b80ab960375adb4a70db934dba482aa3b1d0fe2" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0xe04d9e9CcDf65EB1Db51E56C04beE4c8582edB73", 10 | "txHash": "0xcc336908e4955beefb032c29f13f4cb15605aa61092f2c9150dbd6896e9e1bab", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "fc7421aad9cc9e702dfe5f50541c858cdc57337746ef1310b5ab7190098a1ede": { 16 | "address": "0x8e1bD5Da87C14dd8e08F7ecc2aBf9D1d558ea174", 17 | "txHash": "0x20f46e5d241e5ab0d6ca1071a3686857e3817d9cd47acdfb787d4fff1ff202a9", 18 | "layout": { 19 | "solcVersion": "0.8.18", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | } 94 | ], 95 | "types": { 96 | "t_address": { 97 | "label": "address", 98 | "numberOfBytes": "20" 99 | }, 100 | "t_array(t_uint256)49_storage": { 101 | "label": "uint256[49]", 102 | "numberOfBytes": "1568" 103 | }, 104 | "t_array(t_uint256)50_storage": { 105 | "label": "uint256[50]", 106 | "numberOfBytes": "1600" 107 | }, 108 | "t_bool": { 109 | "label": "bool", 110 | "numberOfBytes": "1" 111 | }, 112 | "t_uint256": { 113 | "label": "uint256", 114 | "numberOfBytes": "32" 115 | }, 116 | "t_uint8": { 117 | "label": "uint8", 118 | "numberOfBytes": "1" 119 | } 120 | } 121 | } 122 | }, 123 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 124 | "address": "0x15fa08599EB017F89c1712d0Fe76138899FdB9db", 125 | "txHash": "0x2f5e5cdb1fe1f9502b35cbc83eb2451651edb7e081fd7c664f2319b618ae4565", 126 | "layout": { 127 | "solcVersion": "0.8.20", 128 | "storage": [ 129 | { 130 | "label": "_initialized", 131 | "offset": 0, 132 | "slot": "0", 133 | "type": "t_uint8", 134 | "contract": "Initializable", 135 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 136 | "retypedFrom": "bool" 137 | }, 138 | { 139 | "label": "_initializing", 140 | "offset": 1, 141 | "slot": "0", 142 | "type": "t_bool", 143 | "contract": "Initializable", 144 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 145 | }, 146 | { 147 | "label": "__gap", 148 | "offset": 0, 149 | "slot": "1", 150 | "type": "t_array(t_uint256)50_storage", 151 | "contract": "ContextUpgradeable", 152 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 153 | }, 154 | { 155 | "label": "_owner", 156 | "offset": 0, 157 | "slot": "51", 158 | "type": "t_address", 159 | "contract": "OwnableUpgradeable", 160 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 161 | }, 162 | { 163 | "label": "__gap", 164 | "offset": 0, 165 | "slot": "52", 166 | "type": "t_array(t_uint256)49_storage", 167 | "contract": "OwnableUpgradeable", 168 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 169 | }, 170 | { 171 | "label": "_paused", 172 | "offset": 0, 173 | "slot": "101", 174 | "type": "t_bool", 175 | "contract": "PausableUpgradeable", 176 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 177 | }, 178 | { 179 | "label": "__gap", 180 | "offset": 0, 181 | "slot": "102", 182 | "type": "t_array(t_uint256)49_storage", 183 | "contract": "PausableUpgradeable", 184 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 185 | }, 186 | { 187 | "label": "_status", 188 | "offset": 0, 189 | "slot": "151", 190 | "type": "t_uint256", 191 | "contract": "ReentrancyGuardUpgradeable", 192 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 193 | }, 194 | { 195 | "label": "__gap", 196 | "offset": 0, 197 | "slot": "152", 198 | "type": "t_array(t_uint256)49_storage", 199 | "contract": "ReentrancyGuardUpgradeable", 200 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 201 | }, 202 | { 203 | "label": "allo", 204 | "offset": 0, 205 | "slot": "201", 206 | "type": "t_contract(IAllo)1014", 207 | "contract": "MultiRoundCheckout", 208 | "src": "contracts/MultiRoundCheckout.sol:206" 209 | } 210 | ], 211 | "types": { 212 | "t_address": { 213 | "label": "address", 214 | "numberOfBytes": "20" 215 | }, 216 | "t_array(t_uint256)49_storage": { 217 | "label": "uint256[49]", 218 | "numberOfBytes": "1568" 219 | }, 220 | "t_array(t_uint256)50_storage": { 221 | "label": "uint256[50]", 222 | "numberOfBytes": "1600" 223 | }, 224 | "t_bool": { 225 | "label": "bool", 226 | "numberOfBytes": "1" 227 | }, 228 | "t_contract(IAllo)1014": { 229 | "label": "contract IAllo", 230 | "numberOfBytes": "20" 231 | }, 232 | "t_uint256": { 233 | "label": "uint256", 234 | "numberOfBytes": "32" 235 | }, 236 | "t_uint8": { 237 | "label": "uint8", 238 | "numberOfBytes": "1" 239 | } 240 | }, 241 | "namespaces": {} 242 | } 243 | } 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /.openzeppelin/unknown-250.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x1139c2F5e7C7EDd6Fc62d1105eCC5650E7168bF0", 5 | "txHash": "0x8cbe7bc8e683591287f1c5953b9e4529f067b7f8c693f372c045b6471621dff9" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x03506eD3f57892C85DB20C36846e9c808aFe9ef4", 10 | "txHash": "0x283ccfc58831bd429344574944b9151aa498e5323ad235180230fd6893d6503d", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "fc7421aad9cc9e702dfe5f50541c858cdc57337746ef1310b5ab7190098a1ede": { 16 | "address": "0x15fa08599EB017F89c1712d0Fe76138899FdB9db", 17 | "txHash": "0x3da45dddbacb0fe6b856170fa53fa4b848d937f9ba3a88e1dd3c1bf72700668c", 18 | "layout": { 19 | "solcVersion": "0.8.18", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | } 94 | ], 95 | "types": { 96 | "t_address": { 97 | "label": "address", 98 | "numberOfBytes": "20" 99 | }, 100 | "t_array(t_uint256)49_storage": { 101 | "label": "uint256[49]", 102 | "numberOfBytes": "1568" 103 | }, 104 | "t_array(t_uint256)50_storage": { 105 | "label": "uint256[50]", 106 | "numberOfBytes": "1600" 107 | }, 108 | "t_bool": { 109 | "label": "bool", 110 | "numberOfBytes": "1" 111 | }, 112 | "t_uint256": { 113 | "label": "uint256", 114 | "numberOfBytes": "32" 115 | }, 116 | "t_uint8": { 117 | "label": "uint8", 118 | "numberOfBytes": "1" 119 | } 120 | } 121 | } 122 | }, 123 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 124 | "address": "0x01D196aEC858C0F466aD8B244b8468889Fc77EBb", 125 | "txHash": "0xad710f93ecfdaa8261feb57869cb9dfa80c706189114c70c9f7ad734a14fe6ec", 126 | "layout": { 127 | "solcVersion": "0.8.20", 128 | "storage": [ 129 | { 130 | "label": "_initialized", 131 | "offset": 0, 132 | "slot": "0", 133 | "type": "t_uint8", 134 | "contract": "Initializable", 135 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 136 | "retypedFrom": "bool" 137 | }, 138 | { 139 | "label": "_initializing", 140 | "offset": 1, 141 | "slot": "0", 142 | "type": "t_bool", 143 | "contract": "Initializable", 144 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 145 | }, 146 | { 147 | "label": "__gap", 148 | "offset": 0, 149 | "slot": "1", 150 | "type": "t_array(t_uint256)50_storage", 151 | "contract": "ContextUpgradeable", 152 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 153 | }, 154 | { 155 | "label": "_owner", 156 | "offset": 0, 157 | "slot": "51", 158 | "type": "t_address", 159 | "contract": "OwnableUpgradeable", 160 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 161 | }, 162 | { 163 | "label": "__gap", 164 | "offset": 0, 165 | "slot": "52", 166 | "type": "t_array(t_uint256)49_storage", 167 | "contract": "OwnableUpgradeable", 168 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 169 | }, 170 | { 171 | "label": "_paused", 172 | "offset": 0, 173 | "slot": "101", 174 | "type": "t_bool", 175 | "contract": "PausableUpgradeable", 176 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 177 | }, 178 | { 179 | "label": "__gap", 180 | "offset": 0, 181 | "slot": "102", 182 | "type": "t_array(t_uint256)49_storage", 183 | "contract": "PausableUpgradeable", 184 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 185 | }, 186 | { 187 | "label": "_status", 188 | "offset": 0, 189 | "slot": "151", 190 | "type": "t_uint256", 191 | "contract": "ReentrancyGuardUpgradeable", 192 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 193 | }, 194 | { 195 | "label": "__gap", 196 | "offset": 0, 197 | "slot": "152", 198 | "type": "t_array(t_uint256)49_storage", 199 | "contract": "ReentrancyGuardUpgradeable", 200 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 201 | }, 202 | { 203 | "label": "allo", 204 | "offset": 0, 205 | "slot": "201", 206 | "type": "t_contract(IAllo)1014", 207 | "contract": "MultiRoundCheckout", 208 | "src": "contracts/MultiRoundCheckout.sol:206" 209 | } 210 | ], 211 | "types": { 212 | "t_address": { 213 | "label": "address", 214 | "numberOfBytes": "20" 215 | }, 216 | "t_array(t_uint256)49_storage": { 217 | "label": "uint256[49]", 218 | "numberOfBytes": "1568" 219 | }, 220 | "t_array(t_uint256)50_storage": { 221 | "label": "uint256[50]", 222 | "numberOfBytes": "1600" 223 | }, 224 | "t_bool": { 225 | "label": "bool", 226 | "numberOfBytes": "1" 227 | }, 228 | "t_contract(IAllo)1014": { 229 | "label": "contract IAllo", 230 | "numberOfBytes": "20" 231 | }, 232 | "t_uint256": { 233 | "label": "uint256", 234 | "numberOfBytes": "32" 235 | }, 236 | "t_uint8": { 237 | "label": "uint8", 238 | "numberOfBytes": "1" 239 | } 240 | }, 241 | "namespaces": {} 242 | } 243 | } 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /.openzeppelin/unknown-4002.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "3.2", 3 | "admin": { 4 | "address": "0x9086d7F2599a5BE83Ade8aa90FB447968f66D832", 5 | "txHash": "0x3d8413cf584570f32f6c6db38acc9fa9a81a03a6f1959e75a26ac68a094cfadc" 6 | }, 7 | "proxies": [ 8 | { 9 | "address": "0x62a850d7805f3Ae382C6eEf7eEB89A31f68Ce2d5", 10 | "txHash": "0x48574e3198748bb4c427fb7f94c8ff6ca6f87715f5778f98f8ae56f56d9cc1b3", 11 | "kind": "transparent" 12 | } 13 | ], 14 | "impls": { 15 | "fc7421aad9cc9e702dfe5f50541c858cdc57337746ef1310b5ab7190098a1ede": { 16 | "address": "0xe04d9e9CcDf65EB1Db51E56C04beE4c8582edB73", 17 | "txHash": "0x28f74411464e6638fd97316944abb94a1b617cc2f8bf9b20c94317144e8607cf", 18 | "layout": { 19 | "solcVersion": "0.8.18", 20 | "storage": [ 21 | { 22 | "label": "_initialized", 23 | "offset": 0, 24 | "slot": "0", 25 | "type": "t_uint8", 26 | "contract": "Initializable", 27 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 28 | "retypedFrom": "bool" 29 | }, 30 | { 31 | "label": "_initializing", 32 | "offset": 1, 33 | "slot": "0", 34 | "type": "t_bool", 35 | "contract": "Initializable", 36 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 37 | }, 38 | { 39 | "label": "__gap", 40 | "offset": 0, 41 | "slot": "1", 42 | "type": "t_array(t_uint256)50_storage", 43 | "contract": "ContextUpgradeable", 44 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 45 | }, 46 | { 47 | "label": "_owner", 48 | "offset": 0, 49 | "slot": "51", 50 | "type": "t_address", 51 | "contract": "OwnableUpgradeable", 52 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 53 | }, 54 | { 55 | "label": "__gap", 56 | "offset": 0, 57 | "slot": "52", 58 | "type": "t_array(t_uint256)49_storage", 59 | "contract": "OwnableUpgradeable", 60 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 61 | }, 62 | { 63 | "label": "_paused", 64 | "offset": 0, 65 | "slot": "101", 66 | "type": "t_bool", 67 | "contract": "PausableUpgradeable", 68 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 69 | }, 70 | { 71 | "label": "__gap", 72 | "offset": 0, 73 | "slot": "102", 74 | "type": "t_array(t_uint256)49_storage", 75 | "contract": "PausableUpgradeable", 76 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 77 | }, 78 | { 79 | "label": "_status", 80 | "offset": 0, 81 | "slot": "151", 82 | "type": "t_uint256", 83 | "contract": "ReentrancyGuardUpgradeable", 84 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 85 | }, 86 | { 87 | "label": "__gap", 88 | "offset": 0, 89 | "slot": "152", 90 | "type": "t_array(t_uint256)49_storage", 91 | "contract": "ReentrancyGuardUpgradeable", 92 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 93 | } 94 | ], 95 | "types": { 96 | "t_address": { 97 | "label": "address", 98 | "numberOfBytes": "20" 99 | }, 100 | "t_array(t_uint256)49_storage": { 101 | "label": "uint256[49]", 102 | "numberOfBytes": "1568" 103 | }, 104 | "t_array(t_uint256)50_storage": { 105 | "label": "uint256[50]", 106 | "numberOfBytes": "1600" 107 | }, 108 | "t_bool": { 109 | "label": "bool", 110 | "numberOfBytes": "1" 111 | }, 112 | "t_uint256": { 113 | "label": "uint256", 114 | "numberOfBytes": "32" 115 | }, 116 | "t_uint8": { 117 | "label": "uint8", 118 | "numberOfBytes": "1" 119 | } 120 | } 121 | } 122 | }, 123 | "b4c94f77e06f9be7d32370a459b5f884f4f68c060a048f9eb1e482b5ea1d1cb6": { 124 | "address": "0x1139c2F5e7C7EDd6Fc62d1105eCC5650E7168bF0", 125 | "txHash": "0x23fc59184be737d1c219e22ccc106362bf7d57703b7199967da2bf232c01957e", 126 | "layout": { 127 | "solcVersion": "0.8.20", 128 | "storage": [ 129 | { 130 | "label": "_initialized", 131 | "offset": 0, 132 | "slot": "0", 133 | "type": "t_uint8", 134 | "contract": "Initializable", 135 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", 136 | "retypedFrom": "bool" 137 | }, 138 | { 139 | "label": "_initializing", 140 | "offset": 1, 141 | "slot": "0", 142 | "type": "t_bool", 143 | "contract": "Initializable", 144 | "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" 145 | }, 146 | { 147 | "label": "__gap", 148 | "offset": 0, 149 | "slot": "1", 150 | "type": "t_array(t_uint256)50_storage", 151 | "contract": "ContextUpgradeable", 152 | "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" 153 | }, 154 | { 155 | "label": "_owner", 156 | "offset": 0, 157 | "slot": "51", 158 | "type": "t_address", 159 | "contract": "OwnableUpgradeable", 160 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" 161 | }, 162 | { 163 | "label": "__gap", 164 | "offset": 0, 165 | "slot": "52", 166 | "type": "t_array(t_uint256)49_storage", 167 | "contract": "OwnableUpgradeable", 168 | "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" 169 | }, 170 | { 171 | "label": "_paused", 172 | "offset": 0, 173 | "slot": "101", 174 | "type": "t_bool", 175 | "contract": "PausableUpgradeable", 176 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" 177 | }, 178 | { 179 | "label": "__gap", 180 | "offset": 0, 181 | "slot": "102", 182 | "type": "t_array(t_uint256)49_storage", 183 | "contract": "PausableUpgradeable", 184 | "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" 185 | }, 186 | { 187 | "label": "_status", 188 | "offset": 0, 189 | "slot": "151", 190 | "type": "t_uint256", 191 | "contract": "ReentrancyGuardUpgradeable", 192 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" 193 | }, 194 | { 195 | "label": "__gap", 196 | "offset": 0, 197 | "slot": "152", 198 | "type": "t_array(t_uint256)49_storage", 199 | "contract": "ReentrancyGuardUpgradeable", 200 | "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:88" 201 | }, 202 | { 203 | "label": "allo", 204 | "offset": 0, 205 | "slot": "201", 206 | "type": "t_contract(IAllo)1014", 207 | "contract": "MultiRoundCheckout", 208 | "src": "contracts/MultiRoundCheckout.sol:206" 209 | } 210 | ], 211 | "types": { 212 | "t_address": { 213 | "label": "address", 214 | "numberOfBytes": "20" 215 | }, 216 | "t_array(t_uint256)49_storage": { 217 | "label": "uint256[49]", 218 | "numberOfBytes": "1568" 219 | }, 220 | "t_array(t_uint256)50_storage": { 221 | "label": "uint256[50]", 222 | "numberOfBytes": "1600" 223 | }, 224 | "t_bool": { 225 | "label": "bool", 226 | "numberOfBytes": "1" 227 | }, 228 | "t_contract(IAllo)1014": { 229 | "label": "contract IAllo", 230 | "numberOfBytes": "20" 231 | }, 232 | "t_uint256": { 233 | "label": "uint256", 234 | "numberOfBytes": "32" 235 | }, 236 | "t_uint8": { 237 | "label": "uint8", 238 | "numberOfBytes": "1" 239 | } 240 | }, 241 | "namespaces": {} 242 | } 243 | } 244 | } 245 | } 246 | --------------------------------------------------------------------------------