From 4e9c92fc284e60e1eda9e5bae82f62ad75b97612 Mon Sep 17 00:00:00 2001 From: Alain Olivier Date: Tue, 5 Mar 2024 10:18:21 +0100 Subject: [PATCH 01/14] test(fork): add tests for v1 vault liquidity migration to v3 vault --- lib/abi/pBTConEthereum.json | 1507 +++++++++++++++++++++++++++++++++++ lib/constants.js | 5 +- test/fork/dao.test.js | 88 +- 3 files changed, 1598 insertions(+), 2 deletions(-) create mode 100644 lib/abi/pBTConEthereum.json diff --git a/lib/abi/pBTConEthereum.json b/lib/abi/pBTConEthereum.json new file mode 100644 index 0000000..9e34769 --- /dev/null +++ b/lib/abi/pBTConEthereum.json @@ -0,0 +1,1507 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldOperator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOperator", + "type": "address" + } + ], + "name": "AdminOperatorChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "AdminTransferInvoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenHolder", + "type": "address" + } + ], + "name": "AuthorizedOperator", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "Burned", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "Minted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "underlyingAssetRecipient", + "type": "string" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "userData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes4", + "name": "originChainId", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "bytes4", + "name": "destinationChainId", + "type": "bytes4" + } + ], + "name": "Redeem", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldRelayHub", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newRelayHub", + "type": "address" + } + ], + "name": "RelayHubChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenHolder", + "type": "address" + } + ], + "name": "RevokedOperator", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "Sent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ORIGIN_CHAIN_ID", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gsnTrustedSigner", + "type": "address" + }, + { + "internalType": "address", + "name": "_gsnFeeTarget", + "type": "address" + } + ], + "name": "__ERC777GSNUpgradeable_init", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_adminOperator", + "type": "address" + } + ], + "name": "__ERC777WithAdminOperatorUpgradeable_init", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relay", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "bytes", + "name": "encodedFunction", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "transactionFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "approvalData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "acceptRelayedCall", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "adminOperator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "adminTransfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "authorizeOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenHolder", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_newOriginChainId", + "type": "bytes4" + } + ], + "name": "changeOriginChainId", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "defaultOperators", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getHubAddr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "grantMinterRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "granularity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gsnExtraGas", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gsnFeeTarget", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gsnTrustedSigner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "hasMinterRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "tokenName", + "type": "string" + }, + { + "internalType": "string", + "name": "tokenSymbol", + "type": "string" + }, + { + "internalType": "address", + "name": "defaultAdmin", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "originChainId", + "type": "bytes4" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenHolder", + "type": "address" + } + ], + "name": "isOperatorFor", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "operatorBurn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + }, + { + "internalType": "string", + "name": "underlyingAssetRecipient", + "type": "string" + }, + { + "internalType": "bytes4", + "name": "destinationChainId", + "type": "bytes4" + } + ], + "name": "operatorRedeem", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "operatorSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "context", + "type": "bytes" + }, + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "actualCharge", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "preRetVal", + "type": "bytes32" + } + ], + "name": "postRelayedCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "context", + "type": "bytes" + } + ], + "name": "preRelayedCall", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + }, + { + "internalType": "string", + "name": "underlyingAssetRecipient", + "type": "string" + }, + { + "internalType": "bytes4", + "name": "destinationChainId", + "type": "bytes4" + } + ], + "name": "redeem", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "underlyingAssetRecipient", + "type": "string" + }, + { + "internalType": "bytes4", + "name": "destinationChainId", + "type": "bytes4" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "relayHubVersion", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "revokeMinterRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "revokeOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "adminOperator_", + "type": "address" + } + ], + "name": "setAdminOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gsnFeeTarget", + "type": "address" + } + ], + "name": "setFeeTarget", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_gsnExtraGas", + "type": "uint256" + } + ], + "name": "setGSNExtraGas", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gsnTrustedSigner", + "type": "address" + } + ], + "name": "setTrustedSigner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/lib/constants.js b/lib/constants.js index ce63712..4c16104 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -32,12 +32,15 @@ module.exports = { MAINNET: { PNT: '0x89Ab32156e46F46D02ade3FEcbe5Fc4243B9AAeD', ETHPNT: '0xf4ea6b892853413bd9d9f1a5d3a620a0ba39c5b2', + PBTC: '0x62199b909fb8b8cf870f97bef2ce6783493c4908', FORWARDER: '0x0000000000000000000000000000000000000000', ERC20_VAULT: '0xe396757EC7E6aC7C8E5ABE7285dde47b98F22db8', DANDELION_VOTING: '0x2211bFD97b1c02aE8Ac305d206e9780ba7D8BfF4', + FINANCE_VAULT: '0xdd92eb1478d3189707ab7f4a5ace3a615cdd0476', ACL: '0xFDcae423E5e92B76FE7D1e2bcabd36fca8a6a8Fe', PNETWORK: '0x341aA660fD5c280F5a9501E3822bB4a98E816D1b', - ASSOCIATION: '0xf1f6568a76559d85cF68E6597fA587544184dD46' + ASSOCIATION: '0xf1f6568a76559d85cF68E6597fA587544184dD46', + PBTC_MINTER: '0x0E3bDe3d39ded57813f0D0727e574D16D675938b' } }, VOTE_STATUS: { diff --git a/test/fork/dao.test.js b/test/fork/dao.test.js index 39a35b3..9f64e39 100644 --- a/test/fork/dao.test.js +++ b/test/fork/dao.test.js @@ -8,6 +8,7 @@ const DaoPntAbi = require('../../lib/abi/daoPNT.json') const ERC20VaultAbi = require('../../lib/abi/ERC20Vault.json') const EthPntAbi = require('../../lib/abi/ethPNT.json') const FinanceAbi = require('../../lib/abi/Finance.json') +const pBTConEthereumAbi = require('../../lib/abi/pBTConEthereum.json') const pntOnGnosisAbi = require('../../lib/abi/PNTonGnosis.json') const pntOnPolygonAbi = require('../../lib/abi/PNTonPolygon.json') const VaultAbi = require('../../lib/abi/Vault.json') @@ -32,7 +33,17 @@ const { PNT_MINTER: PNT_MINTER_ON_GNOSIS, FORWARDER: FORWARDER_ON_GNOSIS }, - MAINNET: { ERC20_VAULT, DANDELION_VOTING: DANDELION_VOTING_V1, PNT: PNT_ON_ETH, ETHPNT, PNETWORK, ASSOCIATION }, + MAINNET: { + ERC20_VAULT, + DANDELION_VOTING: DANDELION_VOTING_V1, + PNT: PNT_ON_ETH, + ETHPNT, + PNETWORK, + ASSOCIATION, + FINANCE_VAULT: FINANCE_VAULT_V1, + PBTC: PBTC_ON_ETHEREUM, + PBTC_MINTER + }, POLYGON: { PNT: PNT_ON_POLYGON, FORWARDER: FORWARDER_ON_POLYGON, PNT_MINTER: PNT_MINTER_ON_POLYGON } }, MISC: { ONE_DAY }, @@ -1069,6 +1080,81 @@ describe('Integration tests on Ethereum deployment', () => { .withArgs(ADDRESS_PLACEHOLDER) }) + it('[dapp] should migrate v1 vault ethPNT liquidity to new v3 vault', async () => { + await crossExecutor + .connect(safe) + .call( + ethPnt.target, + ethPnt.interface.encodeFunctionData('withdrawInflation', [crossExecutor.target, ethers.parseUnits('100')]) + ) + await crossExecutor + .connect(safe) + .call( + ethPnt.target, + ethPnt.interface.encodeFunctionData('transfer', [FINANCE_VAULT_V1, ethers.parseUnits('100')]) + ) + await daoVotingV1.connect(association).newVote( + // secretlint-disable-next-line + '0x00000001dd92eb1478d3189707ab7f4a5ace3a615cdd047600000064beabacc8000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b20000000000000000000000002211bfd97b1c02ae8ac305d206e9780ba7d8bff40000000000000000000000000000000000000000000000056bc75e2d63100000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b200000044095ea7b3000000000000000000000000e396757ec7e6ac7c8e5abe7285dde47b98f22db80000000000000000000000000000000000000000000000056bc75e2d63100000e396757ec7e6ac7c8e5abe7285dde47b98f22db800000124c322525d0000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b200000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000f1918e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a307866316636353638613736353539643835634636384536353937664135383735343431383464443436000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + 'shall we move ethPNT to v3 vault?', + false + ) + const voteId = await daoVotingV1.votesLength() + await Promise.all(tokenHolders.map((_holder) => daoVotingV1.connect(_holder).vote(voteId, true))) + const vote = await daoVotingV1.getVote(voteId) + await mineUpTo(vote[3] + 1n) + await expect(daoVotingV1.connect(association).executeVote(voteId)) + .to.emit(daoVotingV1, 'ExecuteVote') + .withArgs(voteId) + .and.to.emit(ethPnt, 'Transfer') + .withArgs(daoVotingV1.target, vault.target, ethers.parseUnits('100')) + .and.to.emit(vault, 'PegIn') + .withArgs( + PNT_ON_ETH, + daoVotingV1.target, + ethers.parseUnits('100'), + ASSOCIATION, + '0x', + PNETWORK_NETWORK_IDS.MAINNET, + PNETWORK_NETWORK_IDS.GNOSIS + ) + }) + + // pBTC is not native! so the execution script should not peg-in + it.skip('[dapp] should migrate v1 vault pBTC liquidity to new v3 vault', async () => { + const amount = ethers.parseEther('100') + const pbtc = await ethers.getContractAt(pBTConEthereumAbi, PBTC_ON_ETHEREUM) + const minter = await ethers.getImpersonatedSigner(PBTC_MINTER) + await sendEth(ethers, faucet, minter.address, amount) + await pbtc.connect(minter).mint(minter, amount) + await pbtc.connect(minter).transfer(FINANCE_VAULT_V1, amount) + await daoVotingV1.connect(association).newVote( + // secretlint-disable-next-line + '0x00000001dd92eb1478d3189707ab7f4a5ace3a615cdd047600000064beabacc800000000000000000000000062199b909fb8b8cf870f97bef2ce6783493c49080000000000000000000000002211bfd97b1c02ae8ac305d206e9780ba7d8bff40000000000000000000000000000000000000000000000056bc75e2d6310000062199b909fb8b8cf870f97bef2ce6783493c490800000044095ea7b3000000000000000000000000e396757ec7e6ac7c8e5abe7285dde47b98f22db80000000000000000000000000000000000000000000000056bc75e2d63100000e396757ec7e6ac7c8e5abe7285dde47b98f22db800000144c322525d0000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000062199b909fb8b8cf870f97bef2ce6783493c490800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000f1918e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a307830313233343536373839303132333435363738393031323334353637383930313233343536373839000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004f00dbabe00000000000000000000000000000000000000000000000000000000', + 'shall we move pbtc to v3 vault?', + false + ) + const voteId = await daoVotingV1.votesLength() + await Promise.all(tokenHolders.map((_holder) => daoVotingV1.connect(_holder).vote(voteId, true))) + const vote = await daoVotingV1.getVote(voteId) + await mineUpTo(vote[3] + 1n) + await expect(daoVotingV1.connect(association).executeVote(voteId)) + .to.emit(daoVotingV1, 'ExecuteVote') + .withArgs(voteId) + .and.to.emit(ethPnt, 'Transfer') + .withArgs(daoVotingV1.target, vault.target, ethers.parseUnits('100')) + .and.to.emit(vault, 'PegIn') + .withArgs( + PNT_ON_ETH, + daoVotingV1.target, + ethers.parseUnits('100'), + ASSOCIATION, + '0x', + PNETWORK_NETWORK_IDS.MAINNET, + PNETWORK_NETWORK_IDS.GNOSIS + ) + }) + it('should be able to change inflationOwner from CrossExecutor', async () => { await expect( crossExecutor From a7c6be0db909b420d9a138b057ef4443ca077d9f Mon Sep 17 00:00:00 2001 From: Alain Olivier Date: Wed, 6 Mar 2024 16:15:13 +0100 Subject: [PATCH 02/14] refactor(forwarder-native): decode the minimum necessary from metadata Since right now perc20-on-int uses v1 metadata encoding, the decoding should be limited to v1 fields. --- contracts/forwarder/ForwarderNative.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/forwarder/ForwarderNative.sol b/contracts/forwarder/ForwarderNative.sol index b3e72fd..c15b68c 100644 --- a/contracts/forwarder/ForwarderNative.sol +++ b/contracts/forwarder/ForwarderNative.sol @@ -46,9 +46,9 @@ contract ForwarderNative is IForwarder, IERC777Recipient, Context, Ownable { bytes calldata /*_operatorData*/ ) external override { if (_msgSender() == token && _from == vault) { - (, bytes memory userData, , address originAddress, , , , ) = abi.decode( + (, bytes memory userData, , address originAddress) = abi.decode( _userData, - (bytes1, bytes, bytes4, address, bytes4, address, bytes, bytes) + (bytes1, bytes, bytes4, address) ); (bytes memory callsAndTargets, address caller) = abi.decode( From 4d6057121c82ee123ca6d7e43143b39447af9fdd Mon Sep 17 00:00:00 2001 From: Alain Olivier Date: Wed, 6 Mar 2024 16:34:20 +0100 Subject: [PATCH 03/14] refactor(cross-executor): add function to de-whitelist originAddress --- contracts/forwarder/CrossExecutor.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contracts/forwarder/CrossExecutor.sol b/contracts/forwarder/CrossExecutor.sol index d75e51f..63980a4 100644 --- a/contracts/forwarder/CrossExecutor.sol +++ b/contracts/forwarder/CrossExecutor.sol @@ -74,4 +74,8 @@ contract CrossExecutor is IERC777Recipient, Context, Ownable { function whitelistOriginAddress(address originAddress) external onlyOwner { _whitelistedOriginAddresses[originAddress] = true; } + + function dewhitelistOriginAddress(address originAddress) external onlyOwner { + delete _whitelistedOriginAddresses[originAddress]; + } } From 2d9b6210556d9a06425aee7988df6e99d2299144 Mon Sep 17 00:00:00 2001 From: Alain Olivier Date: Wed, 6 Mar 2024 16:35:05 +0100 Subject: [PATCH 04/14] refactor(cross-executor): decode the minimum necessary from metadata Since right now perc20-on-int uses v1 metadata encoding, the decoding should be limited to v1 fields. --- contracts/forwarder/CrossExecutor.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/forwarder/CrossExecutor.sol b/contracts/forwarder/CrossExecutor.sol index 63980a4..a7bdbb2 100644 --- a/contracts/forwarder/CrossExecutor.sol +++ b/contracts/forwarder/CrossExecutor.sol @@ -37,9 +37,9 @@ contract CrossExecutor is IERC777Recipient, Context, Ownable { bytes calldata /*_operatorData*/ ) external override { if (_msgSender() == token && _from == sender) { - (, bytes memory callsAndTargets, , address originAddress, , , , ) = abi.decode( + (, bytes memory callsAndTargets, , address originAddress) = abi.decode( _metaData, - (bytes1, bytes, bytes4, address, bytes4, address, bytes, bytes) + (bytes1, bytes, bytes4, address) ); if (!_whitelistedOriginAddresses[originAddress]) { From 80cb32d7c2797590bfe2065bac7c811c93d77b11 Mon Sep 17 00:00:00 2001 From: Alain Olivier Date: Wed, 6 Mar 2024 16:36:20 +0100 Subject: [PATCH 05/14] chore(hardhat): add bsc in verification configuration --- hardhat.config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hardhat.config.js b/hardhat.config.js index 7de2752..cc3cf38 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -83,7 +83,8 @@ module.exports = { apiKey: { mainnet: getEnvironmentVariable('ETHERSCAN_API_KEY'), polygon: getEnvironmentVariable('POLYGONSCAN_API_KEY'), - xdai: getEnvironmentVariable('GNOSISSCAN_API_KEY') + xdai: getEnvironmentVariable('GNOSISSCAN_API_KEY'), + bsc: getEnvironmentVariable('BSCSCAN_API_KEY') } }, gasReporter: { From 86967c206f83299fd2f183b4041b3672f45a9c6c Mon Sep 17 00:00:00 2001 From: Alain Olivier Date: Wed, 6 Mar 2024 16:44:57 +0100 Subject: [PATCH 06/14] refactor(constants): update forwarders and cross-executor addresses --- lib/constants.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/constants.js b/lib/constants.js index 4c16104..4662d34 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -14,7 +14,7 @@ module.exports = { SAFE: '0xfE8BCE5b156D9bCD28b5373CDC6b4F08B4b9646a', FINANCE_VAULT: '0x6239968e6231164687CB40f8389d933dD7f7e0A5', FINANCE: '0x3d749Bc0eb27795Da58d2f67a2D6527A95567aEC', - FORWARDER: '0x49157Ddc1cA1907AC7b1f6e871Aa90e93567aDa4', + FORWARDER: '0x99405B4E46256dD28e424A0EDf296A28e2aE32a0', PNT: '0x8805Aa0C1a8e59b03fA95740F691E28942Cf44f6', DAOPNT: '0xFF8Ce5Aca26251Cc3f31e597291c71794C06092a', TOKEN_MANAGER: '0xCec0058735D50de98d3715792569921FEb9EfDC1', @@ -27,13 +27,14 @@ module.exports = { }, BSC: { PNT: '0xdaacB0Ab6Fb34d24E8a67BfA14BF4D95D4C7aF92', - FORWARDER: '0x0000000000000000000000000000000000000000' + FORWARDER: '0x4200Bf8D6eEb6D7EA46b9C99564cCb4246416412' }, MAINNET: { PNT: '0x89Ab32156e46F46D02ade3FEcbe5Fc4243B9AAeD', ETHPNT: '0xf4ea6b892853413bd9d9f1a5d3a620a0ba39c5b2', PBTC: '0x62199b909fb8b8cf870f97bef2ce6783493c4908', - FORWARDER: '0x0000000000000000000000000000000000000000', + FORWARDER: '0x4200bf8d6eeb6d7ea46b9c99564ccb4246416412', + CROSS_EXECUTOR: '0xe0bfe5ae5cebbf666c381f267187379117d0da73', ERC20_VAULT: '0xe396757EC7E6aC7C8E5ABE7285dde47b98F22db8', DANDELION_VOTING: '0x2211bFD97b1c02aE8Ac305d206e9780ba7D8BfF4', FINANCE_VAULT: '0xdd92eb1478d3189707ab7f4a5ace3a615cdd0476', From f4d74d03d851edba0b806e10245ab0a51ab6d5c6 Mon Sep 17 00:00:00 2001 From: Alain Olivier Date: Wed, 6 Mar 2024 16:52:42 +0100 Subject: [PATCH 07/14] test(fork): add tests for treasury liquidity migration --- test/fork/dao.test.js | 58 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/test/fork/dao.test.js b/test/fork/dao.test.js index 9f64e39..bf10503 100644 --- a/test/fork/dao.test.js +++ b/test/fork/dao.test.js @@ -1080,7 +1080,59 @@ describe('Integration tests on Ethereum deployment', () => { .withArgs(ADDRESS_PLACEHOLDER) }) - it('[dapp] should migrate v1 vault ethPNT liquidity to new v3 vault', async () => { + it('[dapp] should open a vote for migrating ethPNT treasury funds (1)', async () => { + await daoVotingV1.connect(association).newVote( + // secretlint-disable-next-line + '0x00000001dd92eb1478d3189707ab7f4a5ace3a615cdd047600000064beabacc8000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b20000000000000000000000002211bfd97b1c02ae8ac305d206e9780ba7d8bff40000000000000000000000000000000000000000000000056bc75e2d63100000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b200000044095ea7b3000000000000000000000000e396757ec7e6ac7c8e5abe7285dde47b98f22db80000000000000000000000000000000000000000000000056bc75e2d63100000e396757ec7e6ac7c8e5abe7285dde47b98f22db800000124c322525d0000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b200000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000f1918e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a307866316636353638613736353539643835634636384536353937664135383735343431383464443436000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + 'shall we move ethPNT to v3 vault?', + false + ) + const voteId = await daoVotingV1.votesLength() + await Promise.all(tokenHolders.map((_holder) => daoVotingV1.connect(_holder).vote(voteId, true))) + const vote = await daoVotingV1.getVote(voteId) + await mineUpTo(vote[3] + 1n) + await expect(daoVotingV1.connect(association).executeVote(voteId)) + .to.emit(daoVotingV1, 'ExecuteVote') + .withArgs(voteId) + .and.to.emit(vault, 'PegIn') + .withArgs( + PNT_ON_ETH, + daoVotingV1.target, + ethers.parseUnits('100'), + ASSOCIATION, + '0x', + PNETWORK_NETWORK_IDS.MAINNET, + PNETWORK_NETWORK_IDS.GNOSIS + ) + }) + + it('[dapp] should open a vote for migrating ethPNT treasury funds (2)', async () => { + await daoVotingV1.connect(association).newVote( + // secretlint-disable-next-line + '0x00000001dd92eb1478d3189707ab7f4a5ace3a615cdd047600000064beabacc8000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b20000000000000000000000002211bfd97b1c02ae8ac305d206e9780ba7d8bff40000000000000000000000000000000000000000000000056bc75e2d63100000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b200000044095ea7b3000000000000000000000000e396757ec7e6ac7c8e5abe7285dde47b98f22db80000000000000000000000000000000000000000000000056bc75e2d63100000e396757ec7e6ac7c8e5abe7285dde47b98f22db800000144c322525d0000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b200000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000f1918e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a307866316636353638613736353539643835634636384536353937664135383735343431383464443436000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004f00dbabe00000000000000000000000000000000000000000000000000000000', + 'shall we move ethPNT to v3 vault?', + false + ) + const voteId = await daoVotingV1.votesLength() + await Promise.all(tokenHolders.map((_holder) => daoVotingV1.connect(_holder).vote(voteId, true))) + const vote = await daoVotingV1.getVote(voteId) + await mineUpTo(vote[3] + 1n) + await expect(daoVotingV1.connect(association).executeVote(voteId)) + .to.emit(daoVotingV1, 'ExecuteVote') + .withArgs(voteId) + .and.to.emit(vault, 'PegIn') + .withArgs( + PNT_ON_ETH, + daoVotingV1.target, + ethers.parseUnits('100'), + ASSOCIATION, + '0xf00dbabe', + PNETWORK_NETWORK_IDS.MAINNET, + PNETWORK_NETWORK_IDS.GNOSIS + ) + }) + + it('[dapp] should open a vote for migrating ethPNT treasury funds (3)', async () => { await crossExecutor .connect(safe) .call( @@ -1121,7 +1173,7 @@ describe('Integration tests on Ethereum deployment', () => { }) // pBTC is not native! so the execution script should not peg-in - it.skip('[dapp] should migrate v1 vault pBTC liquidity to new v3 vault', async () => { + it.skip('[dapp] should open a vote for migrating pBTC treasury funds (4', async () => { const amount = ethers.parseEther('100') const pbtc = await ethers.getContractAt(pBTConEthereumAbi, PBTC_ON_ETHEREUM) const minter = await ethers.getImpersonatedSigner(PBTC_MINTER) @@ -1131,7 +1183,7 @@ describe('Integration tests on Ethereum deployment', () => { await daoVotingV1.connect(association).newVote( // secretlint-disable-next-line '0x00000001dd92eb1478d3189707ab7f4a5ace3a615cdd047600000064beabacc800000000000000000000000062199b909fb8b8cf870f97bef2ce6783493c49080000000000000000000000002211bfd97b1c02ae8ac305d206e9780ba7d8bff40000000000000000000000000000000000000000000000056bc75e2d6310000062199b909fb8b8cf870f97bef2ce6783493c490800000044095ea7b3000000000000000000000000e396757ec7e6ac7c8e5abe7285dde47b98f22db80000000000000000000000000000000000000000000000056bc75e2d63100000e396757ec7e6ac7c8e5abe7285dde47b98f22db800000144c322525d0000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000062199b909fb8b8cf870f97bef2ce6783493c490800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000f1918e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a307830313233343536373839303132333435363738393031323334353637383930313233343536373839000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004f00dbabe00000000000000000000000000000000000000000000000000000000', - 'shall we move pbtc to v3 vault?', + 'shall we move pBTC to v3 vault?', false ) const voteId = await daoVotingV1.votesLength() From 1277968d40f869734442226e99f6c0d5f214647e Mon Sep 17 00:00:00 2001 From: Alain Olivier Date: Wed, 6 Mar 2024 19:14:20 +0100 Subject: [PATCH 08/14] refactor(constants): update addresses --- lib/constants.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/constants.js b/lib/constants.js index 4662d34..688b6c4 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -23,25 +23,28 @@ module.exports = { POLYGON: { PNT: '0xb6bcae6468760bc0cdfb9c8ef4ee75c9dd23e1ed', FORWARDER: '0xC85cd78555DF9991245F15c7AA6c4eDBb7791c19', - PNT_MINTER: '0x66917DDA63bC429AE6555e6a2ec17f583FeA732a' + PNT_MINTER: '0x66917DDA63bC429AE6555e6a2ec17f583FeA732a', + SAFE: '0x9203CD49BAb23Ed6e1EE8D6AB376DD5A9CA8486B' }, BSC: { PNT: '0xdaacB0Ab6Fb34d24E8a67BfA14BF4D95D4C7aF92', - FORWARDER: '0x4200Bf8D6eEb6D7EA46b9C99564cCb4246416412' + FORWARDER: '0x23bAa1e6572233f3cf02a002db865FCa495f2926', + SAFE: '0x9203CD49BAb23Ed6e1EE8D6AB376DD5A9CA8486B' }, MAINNET: { PNT: '0x89Ab32156e46F46D02ade3FEcbe5Fc4243B9AAeD', ETHPNT: '0xf4ea6b892853413bd9d9f1a5d3a620a0ba39c5b2', PBTC: '0x62199b909fb8b8cf870f97bef2ce6783493c4908', - FORWARDER: '0x4200bf8d6eeb6d7ea46b9c99564ccb4246416412', - CROSS_EXECUTOR: '0xe0bfe5ae5cebbf666c381f267187379117d0da73', + FORWARDER: '0x4200Bf8D6eEb6D7EA46b9C99564cCb4246416412', + CROSS_EXECUTOR: '0xE0bFE5Ae5ceBbf666C381f267187379117d0dA73', ERC20_VAULT: '0xe396757EC7E6aC7C8E5ABE7285dde47b98F22db8', DANDELION_VOTING: '0x2211bFD97b1c02aE8Ac305d206e9780ba7D8BfF4', FINANCE_VAULT: '0xdd92eb1478d3189707ab7f4a5ace3a615cdd0476', ACL: '0xFDcae423E5e92B76FE7D1e2bcabd36fca8a6a8Fe', PNETWORK: '0x341aA660fD5c280F5a9501E3822bB4a98E816D1b', ASSOCIATION: '0xf1f6568a76559d85cF68E6597fA587544184dD46', - PBTC_MINTER: '0x0E3bDe3d39ded57813f0D0727e574D16D675938b' + PBTC_MINTER: '0x0E3bDe3d39ded57813f0D0727e574D16D675938b', + SAFE: '0xBF828b541593AeFC98a65F15b70209151E7d67a2' } }, VOTE_STATUS: { From 3591b0fe32ec6be8c535631021d2f42a73acf302 Mon Sep 17 00:00:00 2001 From: Alain Olivier Date: Wed, 6 Mar 2024 19:14:47 +0100 Subject: [PATCH 09/14] test(fork): update tests with new addresses --- test/fork/dao.test.js | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/test/fork/dao.test.js b/test/fork/dao.test.js index bf10503..987fa78 100644 --- a/test/fork/dao.test.js +++ b/test/fork/dao.test.js @@ -15,7 +15,7 @@ const VaultAbi = require('../../lib/abi/Vault.json') const { ADDRESSES: { GNOSIS: { - SAFE, + SAFE: SAFE_ON_GNOSIS, EPOCHS_MANAGER, STAKING_MANAGER, STAKING_MANAGER_LM, @@ -42,7 +42,9 @@ const { ASSOCIATION, FINANCE_VAULT: FINANCE_VAULT_V1, PBTC: PBTC_ON_ETHEREUM, - PBTC_MINTER + PBTC_MINTER, + CROSS_EXECUTOR, + SAFE: SAFE_ON_ETH }, POLYGON: { PNT: PNT_ON_POLYGON, FORWARDER: FORWARDER_ON_POLYGON, PNT_MINTER: PNT_MINTER_ON_POLYGON } }, @@ -69,7 +71,7 @@ const FORWARDER_STAKE_USER_DATA = '0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000ddb5f4535123daa5ae343c24006f4075abaf5f7b0000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000123456789012345678901234567890123456789000000000000000000000000dee8ebe2b7152eccd935fd67134bf1bad55302bc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000044095ea7b3000000000000000000000000dee8ebe2b7152eccd935fd67134bf1bad55302bc0000000000000000000000000000000000000000000000000162ea854d0fc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000642b54f551000000000000000000000000ddb5f4535123daa5ae343c24006f4075abaf5f7b0000000000000000000000000000000000000000000000000162ea854d0fc0000000000000000000000000000000000000000000000000000000000000093a8000000000000000000000000000000000000000000000000000000000' const WITHDRAW_INFLATION_FROM_GNOSIS_USER_DATA = // secretlint-disable-next-line - '0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000003000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b2000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b2000000000000000000000000e396757ec7e6ac7c8e5abe7285dde47b98f22db80000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000443352d49b0000000000000000000000000123456789012345678901234567890123456789000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044095ea7b3000000000000000000000000e396757ec7e6ac7c8e5abe7285dde47b98f22db8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124c322525d000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b200000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000f1918e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a30783632333939363865363233313136343638374342343066383338396439333364443766376530413500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + '0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000003000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b2000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b2000000000000000000000000e396757ec7e6ac7c8e5abe7285dde47b98f22db80000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000443352d49b000000000000000000000000e0bfe5ae5cebbf666c381f267187379117d0da73000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044095ea7b3000000000000000000000000e396757ec7e6ac7c8e5abe7285dde47b98f22db8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124c322525d000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b200000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000f1918e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a30783632333939363865363233313136343638374342343066383338396439333364443766376530413500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' const WITHDRAW_INFLATION_FROM_GNOSIS_USER_DATA_2 = // secretlint-disable-next-line '0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000003000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b2000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b2000000000000000000000000e396757ec7e6ac7c8e5abe7285dde47b98f22db80000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000443352d49b00000000000000000000000001234567890123456789012345678901234567890000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044095ea7b3000000000000000000000000e396757ec7e6ac7c8e5abe7285dde47b98f22db80000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124c322525d0000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b200000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000f1918e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a30786631663635363861373635353964383563463638453635393766413538373534343138346444343600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' @@ -163,7 +165,6 @@ describe('Integration tests on Gnosis deployment', () => { feesManager, RewardsManager, rewardsManager, - ForwarderHost, forwarder, daoPNT, daoTreasury, @@ -177,9 +178,7 @@ describe('Integration tests on Gnosis deployment', () => { ] const missingSteps = async () => { - ForwarderHost = await ethers.getContractFactory('ForwarderHost') - forwarder = await ForwarderHost.deploy(pntOnGnosis.target) - await forwarder.whitelistOriginAddress(FORWARDER_ON_POLYGON) + await forwarder.connect(daoOwner).whitelistOriginAddress(FORWARDER_ON_POLYGON) await daoVoting.connect(daoOwner).changeForwarder(forwarder.target) await mintPntOnGnosis(forwarder.target, ethers.parseUnits('1')) await mintPntOnGnosis(daoVoting.target, ethers.parseUnits('1')) @@ -251,7 +250,7 @@ describe('Integration tests on Gnosis deployment', () => { ;[faucet] = await ethers.getSigners() tokenHolders = await Promise.all(TOKEN_HOLDERS_ADDRESSES.map(ethers.getImpersonatedSigner)) user = await ethers.getImpersonatedSigner(USER_ADDRESS) - daoOwner = await ethers.getImpersonatedSigner(SAFE) + daoOwner = await ethers.getImpersonatedSigner(SAFE_ON_GNOSIS) await sendEth(ethers, faucet, daoOwner.address, '5') pntMinter = await ethers.getImpersonatedSigner(PNT_MINTER_ON_GNOSIS) @@ -277,6 +276,7 @@ describe('Integration tests on Gnosis deployment', () => { registrationManager = RegistrationManager.attach(REGISTRATION_MANAGER) feesManager = EpochsManager.attach(FEES_MANAGER) rewardsManager = RewardsManager.attach(REWARDS_MANAGER) + forwarder = await ethers.getContractAt('ForwarderHost', FORWARDER_ON_GNOSIS) await missingSteps() @@ -478,7 +478,6 @@ describe('Integration tests on Gnosis deployment', () => { // this test is coupled with Integration tests on Ethereum deployment -> should process pegOut, withdrawInflation, and pegIn to treasury it('should call withdrawInflation from Gnosis', async () => { - const CROSS_EXECUTOR_ETH = ADDRESS_PLACEHOLDER const ETH_PTN_ADDRESS = ETHPNT const amount = 10 @@ -489,7 +488,7 @@ describe('Integration tests on Gnosis deployment', () => { [ [ETH_PTN_ADDRESS, ETH_PTN_ADDRESS, ERC20_VAULT], [ - new ethers.Interface(EthPntAbi).encodeFunctionData('withdrawInflation', [CROSS_EXECUTOR_ETH, amount]), + new ethers.Interface(EthPntAbi).encodeFunctionData('withdrawInflation', [CROSS_EXECUTOR, amount]), new ethers.Interface(EthPntAbi).encodeFunctionData('approve', [ERC20_VAULT, amount]), new ethers.Interface(ERC20VaultAbi).encodeFunctionData('pegIn(uint256,address,string,bytes,bytes4)', [ amount, @@ -508,7 +507,7 @@ describe('Integration tests on Gnosis deployment', () => { pntOnGnosis.interface.encodeFunctionData('redeem(uint256,bytes,string,bytes4)', [ 1, userData, - CROSS_EXECUTOR_ETH, + CROSS_EXECUTOR, PNETWORK_NETWORK_IDS.MAINNET ]) ] @@ -530,7 +529,7 @@ describe('Integration tests on Gnosis deployment', () => { .withArgs( DANDELION_VOTING, 1, - CROSS_EXECUTOR_ETH, + CROSS_EXECUTOR, // secretlint-disable-next-line WITHDRAW_INFLATION_FROM_GNOSIS_USER_DATA, PNETWORK_NETWORK_IDS.GNOSIS, @@ -932,10 +931,6 @@ describe('Integration tests on Ethereum deployment', () => { pegoutToken(vault, pnetwork, _recipient, PNT_ON_ETH, _value, _metadata) const missingSteps = async () => { - const CrossExecutor = await ethers.getContractFactory('CrossExecutor') - crossExecutor = await CrossExecutor.connect(safe).deploy(PNT_ON_ETH, ERC20_VAULT) - expect(await crossExecutor.owner()).to.be.eq(SAFE) - await crossExecutor.whitelistOriginAddress(DANDELION_VOTING) daoVotingV1 = await ethers.getContractAt(DandelionVotingAbi, DANDELION_VOTING_V1) // open vote to change inflationOwner const executionScript = encodeCallScript( @@ -971,7 +966,9 @@ describe('Integration tests on Ethereum deployment', () => { association = await ethers.getImpersonatedSigner(ASSOCIATION) ethPnt = await ethers.getContractAt(EthPntAbi, ETHPNT) vault = await ethers.getContractAt('IErc20Vault', ERC20_VAULT) - safe = await ethers.getImpersonatedSigner(SAFE) + safe = await ethers.getImpersonatedSigner(SAFE_ON_ETH) + crossExecutor = await ethers.getContractAt('CrossExecutor', CROSS_EXECUTOR) + expect(await crossExecutor.owner()).to.be.eq(SAFE_ON_ETH) await sendEth(ethers, faucet, pnetwork.address, '10') await sendEth(ethers, faucet, association.address, '10') await sendEth(ethers, faucet, safe.address, '10') @@ -982,12 +979,7 @@ describe('Integration tests on Ethereum deployment', () => { // this test is coupled with Integration tests on Gnosis deployment -> should call withdrawInflation from Gnosis it('should process pegOut, withdrawInflation, and pegIn to treasury', async () => { const metadata = encodeMetadata(ethers, { - userData: - // secretlint-disable-next-line - WITHDRAW_INFLATION_FROM_GNOSIS_USER_DATA.replaceAll( - ADDRESS_PLACEHOLDER.slice(2), - crossExecutor.target.slice(2) - ), + userData: WITHDRAW_INFLATION_FROM_GNOSIS_USER_DATA, sourceNetworkId: PNETWORK_NETWORK_IDS.GNOSIS, senderAddress: DANDELION_VOTING, destinationNetworkId: PNETWORK_NETWORK_IDS.MAINNET, From 79bc4b204068bb5e9e8a0b467629a5b09c72b28f Mon Sep 17 00:00:00 2001 From: Alain Olivier Date: Wed, 6 Mar 2024 20:04:12 +0100 Subject: [PATCH 10/14] test(fork): add test asserting votes cannot be opened in Gnosis --- test/fork/dao.test.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/fork/dao.test.js b/test/fork/dao.test.js index 987fa78..b21bfbf 100644 --- a/test/fork/dao.test.js +++ b/test/fork/dao.test.js @@ -915,6 +915,16 @@ describe('Integration tests on Gnosis deployment', () => { }) ).to.be.eq(expectedMetadata) }) + + it('should not permit to open a vote even when staking a lot', async () => { + const amount = ethers.parseUnits('10000000') + await mintPntOnGnosis(tokenHolders[0].address, amount) + await stake(tokenHolders[0], amount) + expect(await daoPNT.balanceOf(tokenHolders[0])).to.be.gte(amount) + await expect( + daoVoting.connect(tokenHolders[0]).newVote('0x', 'Should I become the owner?', true) + ).to.be.revertedWith('DANDELION_VOTING_CAN_NOT_OPEN_VOTE') + }) }) describe('Integration tests on Ethereum deployment', () => { From b6ca95eb6851c01bf30ffd4856bc7f5ad1590c09 Mon Sep 17 00:00:00 2001 From: Alain Olivier Date: Wed, 6 Mar 2024 20:29:49 +0100 Subject: [PATCH 11/14] test(fork): fix failing tests due to change in minOpenVoteAmount --- test/fork/dao.test.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/fork/dao.test.js b/test/fork/dao.test.js index b21bfbf..b0403d8 100644 --- a/test/fork/dao.test.js +++ b/test/fork/dao.test.js @@ -841,9 +841,8 @@ describe('Integration tests on Gnosis deployment', () => { }) it('[dapp] should open a vote to transfer from vault', async () => { - await mintPntOnGnosis(tokenHolders[0], ethers.parseUnits('200000')) await mintPntOnGnosis(daoTreasury.target, ethers.parseUnits('1000000')) - await stake(tokenHolders[0], ethers.parseUnits('200000')) + await grantCreateVotesPermission(acl, daoOwner, tokenHolders[0]) await daoVoting .connect(tokenHolders[0]) .newVote( @@ -867,9 +866,8 @@ describe('Integration tests on Gnosis deployment', () => { }) it('[dapp] should open a vote to withdraw inflation', async () => { - await mintPntOnGnosis(tokenHolders[0], ethers.parseUnits('200000')) await mintPntOnGnosis(daoTreasury.target, ethers.parseUnits('1000000')) - await stake(tokenHolders[0], ethers.parseUnits('200000')) + await grantCreateVotesPermission(acl, daoOwner, tokenHolders[0]) await daoVoting.connect(tokenHolders[0]).newVote( // secretlint-disable-next-line '0x000000010259461eed4d76d4f0f900f9035f6c4dfb39159a000004a408e1e4d3000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000440005fe7f90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000003000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b2000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b2000000000000000000000000e396757ec7e6ac7c8e5abe7285dde47b98f22db80000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000443352d49b00000000000000000000000001234567890123456789012345678901234567890000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044095ea7b3000000000000000000000000e396757ec7e6ac7c8e5abe7285dde47b98f22db80000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124c322525d0000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b200000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000f1918e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a30786631663635363861373635353964383563463638453635393766413538373534343138346444343600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a30783031323334353637383930313233343536373839303132333435363738393031323334353637383900000000000000000000000000000000000000000000'.replace( From cd735df871965a8fbea5ea679c4097db725ca8e7 Mon Sep 17 00:00:00 2001 From: Alain Olivier Date: Wed, 6 Mar 2024 21:08:38 +0100 Subject: [PATCH 12/14] test(fork): update missingSteps for Gnosis --- test/fork/dao.test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/fork/dao.test.js b/test/fork/dao.test.js index b0403d8..15429c2 100644 --- a/test/fork/dao.test.js +++ b/test/fork/dao.test.js @@ -178,8 +178,6 @@ describe('Integration tests on Gnosis deployment', () => { ] const missingSteps = async () => { - await forwarder.connect(daoOwner).whitelistOriginAddress(FORWARDER_ON_POLYGON) - await daoVoting.connect(daoOwner).changeForwarder(forwarder.target) await mintPntOnGnosis(forwarder.target, ethers.parseUnits('1')) await mintPntOnGnosis(daoVoting.target, ethers.parseUnits('1')) } From a8179a4f4887e83b237ecf562d884e0120465b03 Mon Sep 17 00:00:00 2001 From: Alain Olivier Date: Thu, 7 Mar 2024 10:59:56 +0100 Subject: [PATCH 13/14] feat(tasks): add task to check forwarders --- tasks/check-forwarder.js | 22 ++++++++++++++++++++++ tasks/index.js | 1 + 2 files changed, 23 insertions(+) create mode 100644 tasks/check-forwarder.js diff --git a/tasks/check-forwarder.js b/tasks/check-forwarder.js new file mode 100644 index 0000000..05e9665 --- /dev/null +++ b/tasks/check-forwarder.js @@ -0,0 +1,22 @@ +const { task } = require('hardhat/config') + +const { ADDRESSES: _ADDRESSES } = require('../lib/constants') + +const main = async (_args, _hre) => { + if (!(_hre.network.name.toUpperCase() in _ADDRESSES)) { + console.warn('No addresses!') + return + } + const ADDRESSES = _ADDRESSES[_hre.network.name.toUpperCase()] + for (const entry of Object.entries(ADDRESSES)) { + console.log(`Checking ${entry[0]} @ ${entry[1]}`) + const c = await _hre.ethers.getContractAt(['function forwarder() view returns(address)'], entry[1]) + try { + console.log('Forwarder', await c.forwarder()) + } catch (_) { + console.log('No forwarder') + } + } +} + +task('permissions:check-forwarder').setAction(main) diff --git a/tasks/index.js b/tasks/index.js index 79a591f..65ce202 100644 --- a/tasks/index.js +++ b/tasks/index.js @@ -1,6 +1,7 @@ require('./acl-permission') require('./decode-forwarder-metadata') require('./check-all-permissions') +require('./check-forwarder') require('./check-permissions') require('./deploy-dao') require('./deploy_forwarder_bsc') From 1945b41dc5701b19327324049f9f977278e8b513 Mon Sep 17 00:00:00 2001 From: Alain Olivier Date: Thu, 7 Mar 2024 12:24:51 +0100 Subject: [PATCH 14/14] test(fork): add test for staking from Polygon --- test/fork/dao.test.js | 59 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/test/fork/dao.test.js b/test/fork/dao.test.js index 15429c2..1e3c340 100644 --- a/test/fork/dao.test.js +++ b/test/fork/dao.test.js @@ -69,6 +69,9 @@ const FORWARDER_DELEGATE_VOTE_USER_DATA = const FORWARDER_STAKE_USER_DATA = // secretlint-disable-next-line '0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000ddb5f4535123daa5ae343c24006f4075abaf5f7b0000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000123456789012345678901234567890123456789000000000000000000000000dee8ebe2b7152eccd935fd67134bf1bad55302bc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000044095ea7b3000000000000000000000000dee8ebe2b7152eccd935fd67134bf1bad55302bc0000000000000000000000000000000000000000000000000162ea854d0fc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000642b54f551000000000000000000000000ddb5f4535123daa5ae343c24006f4075abaf5f7b0000000000000000000000000000000000000000000000000162ea854d0fc0000000000000000000000000000000000000000000000000000000000000093a8000000000000000000000000000000000000000000000000000000000' +const FORWARDER_STAKE_USER_DATA_2 = + // secretlint-disable-next-line + '0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000ddb5f4535123daa5ae343c24006f4075abaf5f7b0000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000020000000000000000000000008805aa0c1a8e59b03fa95740f691e28942cf44f6000000000000000000000000dee8ebe2b7152eccd935fd67134bf1bad55302bc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000044095ea7b3000000000000000000000000dee8ebe2b7152eccd935fd67134bf1bad55302bc0000000000000000000000000000000000000000000000000b0bfa54806c1db90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000642b54f551000000000000000000000000ddb5f4535123daa5ae343c24006f4075abaf5f7b0000000000000000000000000000000000000000000000000b0bfa54806c1db90000000000000000000000000000000000000000000000000000000000093a8000000000000000000000000000000000000000000000000000000000' const WITHDRAW_INFLATION_FROM_GNOSIS_USER_DATA = // secretlint-disable-next-line '0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000003000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b2000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b2000000000000000000000000e396757ec7e6ac7c8e5abe7285dde47b98f22db80000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000443352d49b000000000000000000000000e0bfe5ae5cebbf666c381f267187379117d0da73000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044095ea7b3000000000000000000000000e396757ec7e6ac7c8e5abe7285dde47b98f22db8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124c322525d000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000f4ea6b892853413bd9d9f1a5d3a620a0ba39c5b200000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000f1918e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a30783632333939363865363233313136343638374342343066383338396439333364443766376530413500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' @@ -791,6 +794,42 @@ describe('Integration tests on Gnosis deployment', () => { expect(await pntOnGnosis.balanceOf(STAKING_MANAGER)).to.be.eq(smBalance + ethers.parseUnits('0.0999')) }) + it('[dapp] should stake from forwarder call (2)', async () => { + expect(await daoPNT.balanceOf(USER_ADDRESS)).to.be.eq(ethers.parseUnits('0')) + const smBalance = await pntOnGnosis.balanceOf(STAKING_MANAGER) + const metadata = encodeMetadata(ethers, { + userData: + // secretlint-disable-next-line + FORWARDER_STAKE_USER_DATA_2, + sourceNetworkId: PNETWORK_NETWORK_IDS.POLYGON, + senderAddress: FORWARDER_ON_POLYGON, + destinationNetworkId: PNETWORK_NETWORK_IDS.GNOSIS, + receiverAddress: forwarder.target + }) + await expect( + mintPToken( + pntOnGnosis, + pntMinter, + forwarder.target, + (ethers.parseUnits('0.797999999999789996') * (1000000n - 2500n)) / 1000000n, + metadata + ) + ) + .to.emit(pntOnGnosis, 'Approval') + .withArgs( + forwarder.target, + stakingManager.target, + (ethers.parseUnits('0.797999999999789996') * (1000000n - 2500n)) / 1000000n + ) + .to.emit(stakingManager, 'Staked') + expect(await daoPNT.balanceOf(USER_ADDRESS)).to.be.eq( + (ethers.parseUnits('0.797999999999789996') * (1000000n - 2500n)) / 1000000n + ) + expect(await pntOnGnosis.balanceOf(STAKING_MANAGER)).to.be.eq( + smBalance + (ethers.parseUnits('0.797999999999789996') * (1000000n - 2500n)) / 1000000n + ) + }) + it('[dapp] should delegateVote from forwarder call', async () => { const stakedAmount = ethers.parseUnits('10') await mintPntOnGnosis(user.address, stakedAmount) @@ -1265,6 +1304,26 @@ describe('Integration tests on Polygon deployment', () => { ) }) + it('[dapp] should call forwarder for staking (2)', async () => { + await expect( + user.sendTransaction({ + to: '0xC85cd78555DF9991245F15c7AA6c4eDBb7791c19', + // secretlint-disable-next-line + data: '0x996adf550000000000000000000000000000000000000000000000000b1310c5a2bfcbac00000000000000000000000099405b4e46256dd28e424a0edf296a28e2ae32a0000000000000000000000000000000000000000000000000000000000000008000f1918e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000020000000000000000000000008805aa0c1a8e59b03fa95740f691e28942cf44f6000000000000000000000000dee8ebe2b7152eccd935fd67134bf1bad55302bc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000044095ea7b3000000000000000000000000dee8ebe2b7152eccd935fd67134bf1bad55302bc0000000000000000000000000000000000000000000000000b0bfa54806c1db90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000642b54f551000000000000000000000000ddb5f4535123daa5ae343c24006f4075abaf5f7b0000000000000000000000000000000000000000000000000b0bfa54806c1db90000000000000000000000000000000000000000000000000000000000093a8000000000000000000000000000000000000000000000000000000000' + }) + ) + .to.emit(pntOnPolygon, 'Redeem') + .withArgs( + forwarder.target, + ethers.parseUnits('0.797999999999789996'), + FORWARDER_ON_GNOSIS.toLowerCase().slice(2), + // secretlint-disable-next-line + FORWARDER_STAKE_USER_DATA_2, + PNETWORK_NETWORK_IDS.POLYGON, + PNETWORK_NETWORK_IDS.GNOSIS + ) + }) + it('[dapp] should call forwarder for voting', async () => { await expect( forwarder.connect(user).call(