From bf7f152e3dc97945d7c13267cc1a5625d3c00389 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Wed, 15 Jan 2020 10:45:32 -0500 Subject: [PATCH 01/47] stub out new contracts --- .../DharmaSmartWalletImplementationV7.sol | 4 + .../token/DharmaDaiImplementationV0.sol | 4 + .../DharmaDaiInitializationImplementation.sol | 4 + .../token/DharmaUSDCImplementationV0.sol | 4 + ...DharmaUSDCInitializationImplementation.sol | 4 + contracts/mock/RelayContract.sol | 73 ---------- contracts/mock/RelayContractV2.sol | 133 ------------------ .../DharmaSpreadRegistryMultisig.sol | 4 + contracts/multisigs/DharmaVaultMultisig.sol | 4 + contracts/proxies/token/DharmaDai.sol | 4 + contracts/proxies/token/DharmaUSDC.sol | 4 + .../registries/DharmaSpreadRegistryV1.sol | 4 + .../token/DharmaDaiUpgradeBeacon.sol | 4 + .../token/DharmaUSDCUpgradeBeacon.sol | 4 + contracts/vaults/DharmaVaultV1.sol | 4 + package.json | 2 +- 16 files changed, 53 insertions(+), 207 deletions(-) create mode 100644 contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol create mode 100644 contracts/implementations/token/DharmaDaiImplementationV0.sol create mode 100644 contracts/implementations/token/DharmaDaiInitializationImplementation.sol create mode 100644 contracts/implementations/token/DharmaUSDCImplementationV0.sol create mode 100644 contracts/implementations/token/DharmaUSDCInitializationImplementation.sol delete mode 100644 contracts/mock/RelayContract.sol delete mode 100644 contracts/mock/RelayContractV2.sol create mode 100644 contracts/multisigs/DharmaSpreadRegistryMultisig.sol create mode 100644 contracts/multisigs/DharmaVaultMultisig.sol create mode 100644 contracts/proxies/token/DharmaDai.sol create mode 100644 contracts/proxies/token/DharmaUSDC.sol create mode 100644 contracts/registries/DharmaSpreadRegistryV1.sol create mode 100644 contracts/upgradeability/token/DharmaDaiUpgradeBeacon.sol create mode 100644 contracts/upgradeability/token/DharmaUSDCUpgradeBeacon.sol create mode 100644 contracts/vaults/DharmaVaultV1.sol diff --git a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol new file mode 100644 index 0000000..970d4b4 --- /dev/null +++ b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol @@ -0,0 +1,4 @@ +pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg + + +contract DharmaSmartWalletImplementationV7 {} \ No newline at end of file diff --git a/contracts/implementations/token/DharmaDaiImplementationV0.sol b/contracts/implementations/token/DharmaDaiImplementationV0.sol new file mode 100644 index 0000000..c655dfe --- /dev/null +++ b/contracts/implementations/token/DharmaDaiImplementationV0.sol @@ -0,0 +1,4 @@ +pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg + + +contract DharmaDaiImplementationV0 {} \ No newline at end of file diff --git a/contracts/implementations/token/DharmaDaiInitializationImplementation.sol b/contracts/implementations/token/DharmaDaiInitializationImplementation.sol new file mode 100644 index 0000000..f865245 --- /dev/null +++ b/contracts/implementations/token/DharmaDaiInitializationImplementation.sol @@ -0,0 +1,4 @@ +pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg + + +contract DharmaDaiInitializationImplementation {} \ No newline at end of file diff --git a/contracts/implementations/token/DharmaUSDCImplementationV0.sol b/contracts/implementations/token/DharmaUSDCImplementationV0.sol new file mode 100644 index 0000000..cb3fbcb --- /dev/null +++ b/contracts/implementations/token/DharmaUSDCImplementationV0.sol @@ -0,0 +1,4 @@ +pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg + + +contract DharmaUSDCImplementationV0 {} \ No newline at end of file diff --git a/contracts/implementations/token/DharmaUSDCInitializationImplementation.sol b/contracts/implementations/token/DharmaUSDCInitializationImplementation.sol new file mode 100644 index 0000000..258da35 --- /dev/null +++ b/contracts/implementations/token/DharmaUSDCInitializationImplementation.sol @@ -0,0 +1,4 @@ +pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg + + +contract DharmaUSDCInitializationImplementation {} \ No newline at end of file diff --git a/contracts/mock/RelayContract.sol b/contracts/mock/RelayContract.sol deleted file mode 100644 index c6e5018..0000000 --- a/contracts/mock/RelayContract.sol +++ /dev/null @@ -1,73 +0,0 @@ -pragma solidity 0.5.11; -pragma experimental ABIEncoderV2; - - -// A contract that is uniquely associated with one Dharma user, -// who can use it to store funds and execute transactions "trustlessly". -contract RelayContract { - // The public address of the key pair that controls this relay contract. - address public controller; - - // A struct representation of a signature. - struct ECDSASignature { - uint8 v; - bytes32 r; - bytes32 s; - } - - // A struct representing the parameters required for to execute a transaction. - struct transactionParameters { - address to; - bytes data; - uint value; - ECDSASignature signature; - address signer; - uint nonce; - } - - // Events related to setting the controller variable. - event SetControllerAttempt(address candidate); - event SetControllerSuccess(address candidate); - event SetControllerFailure(address candidate); - - // Events related to executing transactions. - event ExecuteTransactionAttempt( - address to, - address signer - ); - event ExecuteTransactionSuccess( - address to, - address signer - ); - - // The prefix used for all signed messages. - bytes constant internal PREFIX = "\x19Ethereum Signed Message:\n32"; - - // A function that can only be executed once, by the original deployer. - function setController(address candidate) public { - emit SetControllerAttempt(candidate); - - if (msg.sender == controller) { - controller = candidate; - - emit SetControllerSuccess(candidate); - } else { - emit SetControllerFailure(candidate); - } - } - - // A function that returns the controller of the current contract. - function getController() public view returns (address) { - return controller; - } - - function recoverSignerAddress( - bytes32 prefixedHash, - ECDSASignature memory signature - ) public view returns (address signer) { - return ecrecover(prefixedHash, signature.v, signature.r, signature.s); - } - - // Payable fallback function - function () external payable {} -} \ No newline at end of file diff --git a/contracts/mock/RelayContractV2.sol b/contracts/mock/RelayContractV2.sol deleted file mode 100644 index f42f495..0000000 --- a/contracts/mock/RelayContractV2.sol +++ /dev/null @@ -1,133 +0,0 @@ -pragma solidity 0.5.11; -pragma experimental ABIEncoderV2; - -import "@openzeppelin/contracts/ownership/Ownable.sol"; -import "./RelayContract.sol"; - - -// V2 of Relay Contracts -contract RelayContractV2 is RelayContract, Ownable { - // A list of the hash of completed transactions, - // to prevent replay attacks. - mapping (bytes32 => bool) public completedTransactions; - - // Emitted when funds are paid to this contract. - event ETHReceived( - address payee, - uint256 value - ); - - // Events related to force-changing the controller variable. - event ForceChangeControllerSuccess( - address candidate, - address sender - ); - - // Takes in the address of the owner, and the address of the controller. - // The owner is an offline address for emergency use. - constructor(address ownerIn, address controllerIn) public payable { - controller = controllerIn; - transferOwnership(ownerIn); - } - - // Given parameters for a transaction, execute that transaction. - function executeTransaction( - transactionParameters memory parameters - ) public - { - address to = parameters.to; - bytes memory data = parameters.data; - uint value = parameters.value; - address signer = parameters.signer; - - // An attempt has been made to execute a transaction; log an event. - emit ExecuteTransactionAttempt(to, signer); - - // Prevent unsigned transactions or replay attacks. - requireUniqueAndSignedByController(parameters); - - // Execute the transaction. - (bool ok, ) = to.call.value(value)(data); - require(ok, "Transaction failed during execution"); - - // The execution was successfully submitted; log a success event. - emit ExecuteTransactionSuccess(to, signer); - } - - // Allows an array of transactions to be executed serially. - function executeTransactions( - transactionParameters[] memory transactions - ) public - { - for (uint8 i = 0 ; i < transactions.length; i++) { - executeTransaction(transactions[i]); - } - } - - // Reverts if the transaction was not signed by the controller, - // of if the transaction has already been submitted. - function requireUniqueAndSignedByController( - transactionParameters memory parameters - ) public returns (bool) { - address to = parameters.to; - bytes memory data = parameters.data; - uint value = parameters.value; - address signer = parameters.signer; - uint nonce = parameters.nonce; - ECDSASignature memory signature = parameters.signature; - - // The person who signed the data must be the controller of the contract. - require(signer == controller); - - // Ethereum prefixed hash of the data. - bytes32 prefixedHash = getHash(to, data, value, nonce); - - // Prevent replay attacks. - requireIsUniqueTransaction(prefixedHash); - - // We verify that the given signer address signed the hash. - address recoveredSigner = recoverSignerAddress(prefixedHash, signature); - - require( - recoveredSigner == signer, - "Controller is not authorized to execute transaction" - ); - } - - function getHash( - address to, - bytes memory data, - uint value, - uint nonce - ) public view returns (bytes32 prefixedHash) { - // A hash of all the relevant data. - bytes32 hash = keccak256(abi.encodePacked(to, data, value, nonce)); - - // Ethereum prefixed hash of the data. - return keccak256(abi.encodePacked(PREFIX, hash)); - } - - function requireIsUniqueTransaction(bytes32 prefixedHash) public { - require( - !completedTransactions[prefixedHash], - "Nonce has already been used for these transaction parameters" - ); - - // Store that this transaction has completed. - completedTransactions[prefixedHash] = true; - } - - function forceChangeController(address candidate) public onlyOwner { - controller = candidate; - - emit ForceChangeControllerSuccess(candidate, msg.sender); - } - - // Payable fallback function - function () external payable { - emit ETHReceived( - msg.sender, - msg.value - ); - } -} \ No newline at end of file diff --git a/contracts/multisigs/DharmaSpreadRegistryMultisig.sol b/contracts/multisigs/DharmaSpreadRegistryMultisig.sol new file mode 100644 index 0000000..288b1be --- /dev/null +++ b/contracts/multisigs/DharmaSpreadRegistryMultisig.sol @@ -0,0 +1,4 @@ +pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg + + +contract DharmaSpreadRegistryMultisig {} \ No newline at end of file diff --git a/contracts/multisigs/DharmaVaultMultisig.sol b/contracts/multisigs/DharmaVaultMultisig.sol new file mode 100644 index 0000000..89fdd1e --- /dev/null +++ b/contracts/multisigs/DharmaVaultMultisig.sol @@ -0,0 +1,4 @@ +pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg + + +contract DharmaVaultMultisig {} \ No newline at end of file diff --git a/contracts/proxies/token/DharmaDai.sol b/contracts/proxies/token/DharmaDai.sol new file mode 100644 index 0000000..df5fe73 --- /dev/null +++ b/contracts/proxies/token/DharmaDai.sol @@ -0,0 +1,4 @@ +pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg + + +contract DharmaDai {} \ No newline at end of file diff --git a/contracts/proxies/token/DharmaUSDC.sol b/contracts/proxies/token/DharmaUSDC.sol new file mode 100644 index 0000000..2beded1 --- /dev/null +++ b/contracts/proxies/token/DharmaUSDC.sol @@ -0,0 +1,4 @@ +pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg + + +contract DharmaUSDC {} \ No newline at end of file diff --git a/contracts/registries/DharmaSpreadRegistryV1.sol b/contracts/registries/DharmaSpreadRegistryV1.sol new file mode 100644 index 0000000..b1c1055 --- /dev/null +++ b/contracts/registries/DharmaSpreadRegistryV1.sol @@ -0,0 +1,4 @@ +pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg + + +contract DharmaSpreadRegistryV1 {} \ No newline at end of file diff --git a/contracts/upgradeability/token/DharmaDaiUpgradeBeacon.sol b/contracts/upgradeability/token/DharmaDaiUpgradeBeacon.sol new file mode 100644 index 0000000..659e336 --- /dev/null +++ b/contracts/upgradeability/token/DharmaDaiUpgradeBeacon.sol @@ -0,0 +1,4 @@ +pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg + + +contract DharmaDaiUpgradeBeacon {} \ No newline at end of file diff --git a/contracts/upgradeability/token/DharmaUSDCUpgradeBeacon.sol b/contracts/upgradeability/token/DharmaUSDCUpgradeBeacon.sol new file mode 100644 index 0000000..f6cccf1 --- /dev/null +++ b/contracts/upgradeability/token/DharmaUSDCUpgradeBeacon.sol @@ -0,0 +1,4 @@ +pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg + + +contract DharmaUSDCUpgradeBeacon {} \ No newline at end of file diff --git a/contracts/vaults/DharmaVaultV1.sol b/contracts/vaults/DharmaVaultV1.sol new file mode 100644 index 0000000..fc38152 --- /dev/null +++ b/contracts/vaults/DharmaVaultV1.sol @@ -0,0 +1,4 @@ +pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg + + +contract DharmaVaultV1 {} \ No newline at end of file diff --git a/package.json b/package.json index d624dcf..7ad5f24 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dharma-smart-wallet", - "version": "1.3.0", + "version": "1.4.0", "description": "An upgradeable, meta-transaction-enabled smart wallet for earning interest on stablecoins while retaining custody of funds, with an added security backstop provided by Dharma Labs.", "author": "Dharma Labs", "license": "MIT", From 150b957fbbd46d6fabb89bf190fc1e11d676a9de Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Wed, 15 Jan 2020 23:11:15 -0500 Subject: [PATCH 02/47] derive addresses and prep for dTokens --- .solcover.js | 3 +- .soliumignore | 4 +- .../DharmaSmartWalletImplementationV7.sol | 2079 ++++++++++++++++- .../DharmaSpreadRegistryMultisig.sol | 4 - contracts/multisigs/DharmaVaultMultisig.sol | 4 - contracts/proxies/token/DharmaDai.sol | 52 +- contracts/proxies/token/DharmaUSDC.sol | 52 +- .../registries/DharmaSpreadRegistryV1.sol | 4 - .../token/DharmaDaiUpgradeBeacon.sol | 36 +- .../token/DharmaUSDCUpgradeBeacon.sol | 36 +- contracts/vaults/DharmaVaultV1.sol | 4 - .../helpers/FactoryFactFinder.sol | 0 ...rtWalletFactoryV1UserSigningKeyUpdater.sol | 0 interfaces/CTokenInterface.sol | 24 +- interfaces/DTokenInterface.sol | 36 + ...maSmartWalletImplementationV7Interface.sol | 9 + scripts/test/constants.js | 70 +- scripts/test/deploy.js | 20 +- 18 files changed, 2391 insertions(+), 46 deletions(-) delete mode 100644 contracts/multisigs/DharmaSpreadRegistryMultisig.sol delete mode 100644 contracts/multisigs/DharmaVaultMultisig.sol delete mode 100644 contracts/registries/DharmaSpreadRegistryV1.sol delete mode 100644 contracts/vaults/DharmaVaultV1.sol rename {contracts => extra-contracts}/helpers/FactoryFactFinder.sol (100%) rename {contracts => extra-contracts}/helpers/SmartWalletFactoryV1UserSigningKeyUpdater.sol (100%) create mode 100644 interfaces/DTokenInterface.sol create mode 100644 interfaces/DharmaSmartWalletImplementationV7Interface.sol diff --git a/.solcover.js b/.solcover.js index 5169391..f576192 100644 --- a/.solcover.js +++ b/.solcover.js @@ -26,7 +26,8 @@ module.exports = { 'implementations/smart-wallet/DharmaSmartWalletImplementationV3.sol', 'implementations/smart-wallet/DharmaSmartWalletImplementationV4.sol', 'implementations/smart-wallet/DharmaSmartWalletImplementationV5.sol', - //'implementations/smart-wallet/DharmaSmartWalletImplementationV6.sol', + 'implementations/smart-wallet/DharmaSmartWalletImplementationV6.sol', + //'implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol' 'implementations/smart-wallet/DharmaSmartWalletImplementationVX.sol', 'mock/MockSaiToDaiMigrator.sol', 'mock/MockCodeCheck.sol', diff --git a/.soliumignore b/.soliumignore index 7c2eeab..715d65c 100644 --- a/.soliumignore +++ b/.soliumignore @@ -5,8 +5,7 @@ contracts/mock/RelayContractV2.sol interfaces/RelayContractInterface.sol # disagree with indentation error -contracts/helpers/FactoryFactFinder.sol -contracts/helpers/SmartWalletFactoryV1UserSigningKeyUpdater.sol +extra-contracts/helpers/FactoryFactFinder.sol contracts/upgradeability/DharmaUpgradeBeaconController.sol contracts/implementations/smart-wallet/AdharmaSmartWalletImplementation.sol @@ -18,6 +17,7 @@ contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV3.sol contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV4.sol contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV5.sol contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV6.sol +contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol contracts/implementations/smart-wallet/DharmaSmartWalletImplementationVX.sol extra-contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV0.sol diff --git a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol index 970d4b4..f6e6b44 100644 --- a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol +++ b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol @@ -1,4 +1,2081 @@ pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg +// WARNING - `executeActionWithAtomicBatchCalls` has a `bytes[]` argument that +// requires ABIEncoderV2. Exercise caution when calling that specific function. +pragma experimental ABIEncoderV2; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/cryptography/ECDSA.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "../../../interfaces/DharmaSmartWalletImplementationV0Interface.sol"; +import "../../../interfaces/DharmaSmartWalletImplementationV1Interface.sol"; +import "../../../interfaces/DharmaSmartWalletImplementationV3Interface.sol"; +import "../../../interfaces/DharmaSmartWalletImplementationV4Interface.sol"; +import "../../../interfaces/DharmaSmartWalletImplementationV7Interface.sol"; +import "../../../interfaces/CTokenInterface.sol"; +import "../../../interfaces/DTokenInterface.sol"; +import "../../../interfaces/USDCV1Interface.sol"; +import "../../../interfaces/DharmaKeyRegistryInterface.sol"; +import "../../../interfaces/DharmaEscapeHatchRegistryInterface.sol"; +import "../../../interfaces/ERC1271.sol"; +import "../../../interfaces/SaiToDaiMigratorInterface.sol"; -contract DharmaSmartWalletImplementationV7 {} \ No newline at end of file + +/** + * @title DharmaSmartWalletImplementationV7 + * @author 0age + * @notice The V7 implementation for the Dharma smart wallet is a non-custodial, + * meta-transaction-enabled wallet with helper functions to facilitate lending + * funds through Dharma Dai and Dharma USDC (which in turn use CompoundV2), and + * with a security backstop provided by Dharma Labs prior to making withdrawals. + * It adds support for Dharma Dai and Dharma USDC, which wrap the respective + * cTokens and mint and redeem them internally as interest-bearing collateral. + * It contains methods to support account recovery, escape hatch functionality, + * and generic actions, including in an atomic batch. The smart wallet instances + * utilizing this implementation are deployed through the Dharma Smart Wallet + * Factory via `CREATE2`, which allows for their address to be known ahead of + * time, and any Dai or USDC that has already been sent into that address will + * automatically be deposited into the respective Dharma Token upon deployment + * of the new smart wallet instance. + */ +contract DharmaSmartWalletImplementationV7 is + DharmaSmartWalletImplementationV0Interface, + DharmaSmartWalletImplementationV1Interface, + DharmaSmartWalletImplementationV3Interface, + DharmaSmartWalletImplementationV4Interface, + DharmaSmartWalletImplementationV7Interface { + using Address for address; + using ECDSA for bytes32; + // WARNING: DO NOT REMOVE OR REORDER STORAGE WHEN WRITING NEW IMPLEMENTATIONS! + + // The user signing key associated with this account is in storage slot 0. + // It is the core differentiator when it comes to the account in question. + address private _userSigningKey; + + // The nonce associated with this account is in storage slot 1. Every time a + // signature is submitted, it must have the appropriate nonce, and once it has + // been accepted the nonce will be incremented. + uint256 private _nonce; + + // The self-call context flag is in storage slot 2. Some protected functions + // may only be called externally from calls originating from other methods on + // this contract, which enables appropriate exception handling on reverts. + // Any storage should only be set immediately preceding a self-call and should + // be cleared upon entering the protected function being called. + bytes4 internal _selfCallContext; + + // END STORAGE DECLARATIONS - DO NOT REMOVE OR REORDER STORAGE ABOVE HERE! + + // The smart wallet version will be used when constructing valid signatures. + uint256 internal constant _DHARMA_SMART_WALLET_VERSION = 7; + + // DharmaKeyRegistryV2 holds a public key for verifying meta-transactions. + DharmaKeyRegistryInterface internal constant _DHARMA_KEY_REGISTRY = ( + DharmaKeyRegistryInterface(0x000000000D38df53b45C5733c7b34000dE0BDF52) + ); + + // Account recovery is facilitated using a hard-coded recovery manager, + // controlled by Dharma and implementing appropriate timelocks. + address internal constant _ACCOUNT_RECOVERY_MANAGER = address( + 0x0000000000DfEd903aD76996FC07BF89C0127B1E + ); + + // Users can designate an "escape hatch" account with the ability to sweep all + // funds from their smart wallet by using the Dharma Escape Hatch Registry. + DharmaEscapeHatchRegistryInterface internal constant _ESCAPE_HATCH_REGISTRY = ( + DharmaEscapeHatchRegistryInterface(0x00000000005280B515004B998a944630B6C663f8) + ); + + // Interface with Sai, Dai, USDC, related CompoundV2 contracts, and migrator. + CTokenInterface internal constant _CSAI = CTokenInterface( + 0xF5DCe57282A584D2746FaF1593d3121Fcac444dC // mainnet + ); + + CTokenInterface internal constant _CDAI = CTokenInterface( + 0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643 // mainnet + ); + + CTokenInterface internal constant _CUSDC = CTokenInterface( + 0x39AA39c021dfbaE8faC545936693aC917d5E7563 // mainnet + ); + + DTokenInterface internal constant _DDAI = DTokenInterface( + 0x00000000001876eB1444c986fD502e618c587430 // mainnet + ); + + DTokenInterface internal constant _DUSDC = DTokenInterface( + 0x0000000000946A7848C50C8f0AE1BB2792602Cb7 // mainnet + ); + + IERC20 internal constant _SAI = IERC20( + 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359 // mainnet + ); + + IERC20 internal constant _DAI = IERC20( + 0x6B175474E89094C44Da98b954EedeAC495271d0F // mainnet + ); + + IERC20 internal constant _USDC = IERC20( + 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 // mainnet + ); + + SaiToDaiMigratorInterface internal constant _MIGRATOR = SaiToDaiMigratorInterface( + 0xc73e0383F3Aff3215E6f04B0331D58CeCf0Ab849 // mainnet + ); + + USDCV1Interface internal constant _USDC_NAUGHTY = USDCV1Interface( + 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 // mainnet + ); + + // Compound returns a value of 0 to indicate success, or lack of an error. + uint256 internal constant _COMPOUND_SUCCESS = 0; + + // ERC-1271 must return this magic value when `isValidSignature` is called. + bytes4 internal constant _ERC_1271_MAGIC_VALUE = bytes4(0x20c13b0b); + + // Minimum supported deposit & non-maximum withdrawal size is .001 underlying. + uint256 private constant _JUST_UNDER_ONE_1000th_DAI = 999999999999999; + uint256 private constant _JUST_UNDER_ONE_1000th_USDC = 999; + + // Specify the amount of gas to supply when making Ether transfers. + uint256 private constant _ETH_TRANSFER_GAS = 4999; + + /** + * @notice In the initializer, set up the initial user signing key, set + * approval on the Dharma Dai and Dharma USDC contracts, and deposit any Dai + * or USDC already at this address to receive dDai or dUSDC. Note that this + * initializer is only callable while the smart wallet instance is still in + * the contract creation phase. + * @param userSigningKey address The initial user signing key for the smart + * wallet. + */ + function initialize(address userSigningKey) external { + // Ensure that this function is only callable during contract construction. + assembly { if extcodesize(address) { revert(0, 0) } } + + // Set up the user's signing key and emit a corresponding event. + _setUserSigningKey(userSigningKey); + + // Approve the dDai contract to transfer Dai on behalf of this contract. + if (_setFullApproval(AssetType.DAI)) { + // Get the current Dai balance on this contract. + uint256 daiBalance = _DAI.balanceOf(address(this)); + + // Try to deposit the full Dai balance to Dharma Dai. + _depositDharmaToken(AssetType.DAI, daiBalance); + } + + // Approve the dUSDC contract to transfer USDC on behalf of this contract. + if (_setFullApproval(AssetType.USDC)) { + // Get the current USDC balance on this contract. + uint256 usdcBalance = _USDC.balanceOf(address(this)); + + // Try to deposit the full Dai balance to Dharma USDC. + _depositDharmaToken(AssetType.USDC, usdcBalance); + } + } + + /** + * @notice Deposit all Dai and USDC currently residing at this address and + * receive Dharma Dai or Dharma USDC in return. Note that "repay" is not + * currently implemented, though it may be in a future implementation. If some + * step of this function fails, the function itself will still succeed, but an + * `ExternalError` with information on what went wrong will be emitted. + */ + function repayAndDeposit() external { + // Get the current Dai balance on this contract. + uint256 daiBalance = _DAI.balanceOf(address(this)); + + // If there is any Dai balance, check for adequate approval for dDai. + if (daiBalance > 0) { + uint256 daiAllowance = _DAI.allowance(address(this), address(_DDAI)); + // If allowance is insufficient, try to set it before depositing. + if (daiAllowance < daiBalance) { + if (_setFullApproval(AssetType.DAI)) { + // Deposit the full available Dai balance to Dharma Dai. + _depositDharmaToken(AssetType.DAI, daiBalance); + } + // Otherwise, just go ahead and try the Dai deposit. + } else { + // Deposit the full available Dai balance to Dharma Dai. + _depositDharmaToken(AssetType.DAI, daiBalance); + } + } + + // Get the current USDC balance on this contract. + uint256 usdcBalance = _USDC.balanceOf(address(this)); + + // If there is any USDC balance, check for adequate approval for dUSDC. + if (usdcBalance > 0) { + uint256 usdcAllowance = _USDC.allowance(address(this), address(_DUSDC)); + // If allowance is insufficient, try to set it before depositing. + if (usdcAllowance < usdcBalance) { + if (_setFullApproval(AssetType.USDC)) { + // Deposit the full available USDC balance to Dharma USDC. + _depositDharmaToken(AssetType.USDC, usdcBalance); + } + // Otherwise, just go ahead and try the USDC deposit. + } else { + // Deposit the full available USDC balance to Dharma USDC. + _depositDharmaToken(AssetType.USDC, usdcBalance); + } + } + } + + /** + * @notice Withdraw Dai to a provided recipient address by redeeming the + * underlying Dai from the dDai contract and transferring it to the recipient. + * All Dai in Dharma Dai and in the smart wallet itself can be withdrawn by + * providing an amount of uint256(-1) or 0xfff...fff. This function can be + * called directly by the account set as the global key on the Dharma Key + * Registry, or by any relayer that provides a signed message from the same + * keyholder. The nonce used for the signature must match the current nonce on + * the smart wallet, and gas supplied to the call must exceed the specified + * minimum action gas, plus the gas that will be spent before the gas check is + * reached - usually somewhere around 25,000 gas. If the withdrawal fails, an + * `ExternalError` with additional details on what went wrong will be emitted. + * Note that some dust may still be left over, even in the event of a max + * withdrawal, due to the fact that Dai has a higher precision than dDai. Also + * note that the withdrawal will fail in the event that Compound does not have + * sufficient Dai available to withdraw. + * @param amount uint256 The amount of Dai to withdraw. + * @param recipient address The account to transfer the withdrawn Dai to. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @param userSignature bytes A signature that resolves to the public key + * set for this account in storage slot zero, `_userSigningKey`. If the user + * signing key is not a contract, ecrecover will be used; otherwise, ERC1271 + * will be used. A unique hash returned from `getCustomActionID` is prefixed + * and hashed to create the message hash for the signature. + * @param dharmaSignature bytes A signature that resolves to the public key + * returned for this account from the Dharma Key Registry. A unique hash + * returned from `getCustomActionID` is prefixed and hashed to create the + * signed message. + * @return True if the withdrawal succeeded, otherwise false. + */ + function withdrawDai( + uint256 amount, + address recipient, + uint256 minimumActionGas, + bytes calldata userSignature, + bytes calldata dharmaSignature + ) external returns (bool ok) { + // Ensure caller and/or supplied signatures are valid and increment nonce. + _validateActionAndIncrementNonce( + ActionType.DAIWithdrawal, + abi.encode(amount, recipient), + minimumActionGas, + userSignature, + dharmaSignature + ); + + // Ensure that an amount of at least 0.001 Dai has been supplied. + require(amount > _JUST_UNDER_ONE_1000th_DAI, "Insufficient Dai supplied."); + + // Ensure that a non-zero recipient has been supplied. + require(recipient != address(0), "No recipient supplied."); + + // Set the self-call context in order to call _withdrawDaiAtomic. + _selfCallContext = this.withdrawDai.selector; + + // Make the atomic self-call - if redeemUnderlying fails on dDai, it will + // succeed but nothing will happen except firing an ExternalError event. If + // the second part of the self-call (the Dai transfer) fails, it will revert + // and roll back the first part of the call as well as fire an ExternalError + // event after returning from the failed call. + bytes memory returnData; + (ok, returnData) = address(this).call(abi.encodeWithSelector( + this._withdrawDaiAtomic.selector, amount, recipient + )); + + // If the atomic call failed, emit an event signifying a transfer failure. + if (!ok) { + emit ExternalError(address(_DAI), "Could not transfer Dai."); + } else { + // Set ok to false if the call succeeded but the withdrawal failed. + ok = abi.decode(returnData, (bool)); + } + } + + /** + * @notice Protected function that can only be called from `withdrawDai` on + * this contract. It will attempt to withdraw the supplied amount of Dai, or + * the maximum amount if specified using `uint256(-1)`, to the supplied + * recipient address by redeeming the underlying Dai from the dDai contract + * and transferring it to the recipient. An ExternalError will be emitted and + * the transfer will be skipped if the call to `redeem` or `redeemUnderlying` + * fails, and any revert will be caught by `withdrawDai` and diagnosed in + * order to emit an appropriate `ExternalError` as well. + * @param amount uint256 The amount of Dai to withdraw. + * @param recipient address The account to transfer the withdrawn Dai to. + * @return True if the withdrawal succeeded, otherwise false. + */ + function _withdrawDaiAtomic( + uint256 amount, + address recipient + ) external returns (bool success) { + // Ensure caller is this contract and self-call context is correctly set. + _enforceSelfCallFrom(this.withdrawDai.selector); + + // If amount = 0xfff...fff, withdraw the maximum amount possible. + bool maxWithdraw = (amount == uint256(-1)); + if (maxWithdraw) { + // First attempt to redeem all dDai if there is a balance. + _withdrawMaxFromDharmaToken(AssetType.DAI); + + // Then transfer all Dai to recipient if there is a balance. + require(_transferMax(_DAI, recipient, false)); + success = true; + } else { + // Attempt to withdraw specified Dai from Dharma Dai before proceeding. + if (_withdrawFromDharmaToken(AssetType.DAI, amount)) { + // At this point Dai transfer should never fail - wrap it just in case. + require(_DAI.transfer(recipient, amount)); + success = true; + } + } + } + + /** + * @notice Withdraw USDC to a provided recipient address by redeeming the + * underlying USDC from the dUSDC contract and transferring it to recipient. + * All USDC in Dharma USDC and in the smart wallet itself can be withdrawn by + * providing an amount of uint256(-1) or 0xfff...fff. This function can be + * called directly by the account set as the global key on the Dharma Key + * Registry, or by any relayer that provides a signed message from the same + * keyholder. The nonce used for the signature must match the current nonce on + * the smart wallet, and gas supplied to the call must exceed the specified + * minimum action gas, plus the gas that will be spent before the gas check is + * reached - usually somewhere around 25,000 gas. If the withdrawal fails, an + * `ExternalError` with additional details on what went wrong will be emitted. + * Note that the USDC contract can be paused and also allows for blacklisting + * accounts - either of these possibilities may cause a withdrawal to fail. In + * addition, Compound may not have sufficient USDC available at the time to + * withdraw. + * @param amount uint256 The amount of USDC to withdraw. + * @param recipient address The account to transfer the withdrawn USDC to. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @param userSignature bytes A signature that resolves to the public key + * set for this account in storage slot zero, `_userSigningKey`. If the user + * signing key is not a contract, ecrecover will be used; otherwise, ERC1271 + * will be used. A unique hash returned from `getCustomActionID` is prefixed + * and hashed to create the message hash for the signature. + * @param dharmaSignature bytes A signature that resolves to the public key + * returned for this account from the Dharma Key Registry. A unique hash + * returned from `getCustomActionID` is prefixed and hashed to create the + * signed message. + * @return True if the withdrawal succeeded, otherwise false. + */ + function withdrawUSDC( + uint256 amount, + address recipient, + uint256 minimumActionGas, + bytes calldata userSignature, + bytes calldata dharmaSignature + ) external returns (bool ok) { + // Ensure caller and/or supplied signatures are valid and increment nonce. + _validateActionAndIncrementNonce( + ActionType.USDCWithdrawal, + abi.encode(amount, recipient), + minimumActionGas, + userSignature, + dharmaSignature + ); + + // Ensure that an amount of at least 0.001 USDC has been supplied. + require(amount > _JUST_UNDER_ONE_1000th_USDC, "Insufficient USDC supplied."); + + // Ensure that a non-zero recipient has been supplied. + require(recipient != address(0), "No recipient supplied."); + + // Set the self-call context in order to call _withdrawUSDCAtomic. + _selfCallContext = this.withdrawUSDC.selector; + + // Make the atomic self-call - if redeemUnderlying fails on dUSDC, it will + // succeed but nothing will happen except firing an ExternalError event. If + // the second part of the self-call (USDC transfer) fails, it will revert + // and roll back the first part of the call as well as fire an ExternalError + // event after returning from the failed call. + bytes memory returnData; + (ok, returnData) = address(this).call(abi.encodeWithSelector( + this._withdrawUSDCAtomic.selector, amount, recipient + )); + if (!ok) { + // Find out why USDC transfer reverted (doesn't give revert reasons). + _diagnoseAndEmitUSDCSpecificError(_USDC.transfer.selector); + } else { + // Set ok to false if the call succeeded but the withdrawal failed. + ok = abi.decode(returnData, (bool)); + } + } + + /** + * @notice Protected function that can only be called from `withdrawUSDC` on + * this contract. It will attempt to withdraw the supplied amount of USDC, or + * the maximum amount if specified using `uint256(-1)`, to the supplied + * recipient address by redeeming the underlying USDC from the dUSDC contract + * and transferring it to the recipient. An ExternalError will be emitted and + * the transfer will be skipped if the call to `redeemUnderlying` fails, and + * any revert will be caught by `withdrawUSDC` and diagnosed in order to emit + * an appropriate ExternalError as well. + * @param amount uint256 The amount of USDC to withdraw. + * @param recipient address The account to transfer the withdrawn USDC to. + * @return True if the withdrawal succeeded, otherwise false. + */ + function _withdrawUSDCAtomic( + uint256 amount, + address recipient + ) external returns (bool success) { + // Ensure caller is this contract and self-call context is correctly set. + _enforceSelfCallFrom(this.withdrawUSDC.selector); + + // If amount = 0xfff...fff, withdraw the maximum amount possible. + bool maxWithdraw = (amount == uint256(-1)); + if (maxWithdraw) { + // Attempt to redeem all dUSDC from Dharma USDC if there is a balance. + _withdrawMaxFromDharmaToken(AssetType.USDC); + + // Then transfer all USDC to recipient if there is a balance. + require(_transferMax(_USDC, recipient, false)); + success = true; + } else { + // Attempt to withdraw specified USDC from Dharma USDC before proceeding. + if (_withdrawFromDharmaToken(AssetType.USDC, amount)) { + // Ensure that the USDC transfer does not fail. + require(_USDC.transfer(recipient, amount)); + success = true; + } + } + } + + /** + * @notice Withdraw Ether to a provided recipient address by transferring it + * to a recipient. This is only intended to be utilized on V7 as a mechanism + * for recovering Ether from this contract. + * @param amount uint256 The amount of Ether to withdraw. + * @param recipient address The account to transfer the Ether to. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @param userSignature bytes A signature that resolves to the public key + * set for this account in storage slot zero, `_userSigningKey`. If the user + * signing key is not a contract, ecrecover will be used; otherwise, ERC1271 + * will be used. A unique hash returned from `getCustomActionID` is prefixed + * and hashed to create the message hash for the signature. + * @param dharmaSignature bytes A signature that resolves to the public key + * returned for this account from the Dharma Key Registry. A unique hash + * returned from `getCustomActionID` is prefixed and hashed to create the + * signed message. + * @return True if the transfer succeeded, otherwise false. + */ + function withdrawEther( + uint256 amount, + address payable recipient, + uint256 minimumActionGas, + bytes calldata userSignature, + bytes calldata dharmaSignature + ) external returns (bool ok) { + // Ensure caller and/or supplied signatures are valid and increment nonce. + _validateActionAndIncrementNonce( + ActionType.ETHWithdrawal, + abi.encode(amount, recipient), + minimumActionGas, + userSignature, + dharmaSignature + ); + + // Ensure that a non-zero amount of Ether has been supplied. + require(amount > 0, "Must supply a non-zero amount of Ether."); + + // Ensure that a non-zero recipient has been supplied. + require(recipient != address(0), "No recipient supplied."); + + // Attempt to transfer Ether to the recipient and emit an appropriate event. + ok = _transferETH(recipient, amount); + } + + /** + * @notice Allow a signatory to increment the nonce at any point. The current + * nonce needs to be provided as an argument to the a signature so as not to + * enable griefing attacks. All arguments can be omitted if called directly. + * No value is returned from this function - it will either succeed or revert. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @param signature bytes A signature that resolves to either the public key + * set for this account in storage slot zero, `_userSigningKey`, or the public + * key returned for this account from the Dharma Key Registry. A unique hash + * returned from `getCustomActionID` is prefixed and hashed to create the + * signed message. + */ + function cancel( + uint256 minimumActionGas, + bytes calldata signature + ) external { + // Get the current nonce. + uint256 nonceToCancel = _nonce; + + // Ensure the caller or the supplied signature is valid and increment nonce. + _validateActionAndIncrementNonce( + ActionType.Cancel, + abi.encode(), + minimumActionGas, + signature, + signature + ); + + // Emit an event to validate that the nonce is no longer valid. + emit Cancel(nonceToCancel); + } + + /** + * @notice Perform a generic call to another contract. Note that accounts with + * no code may not be specified, nor may the smart wallet itself. In order to + * increment the nonce and invalidate the signatures, a call to this function + * with a valid target, signatutes, and gas will always succeed. To determine + * whether the call made as part of the action was successful or not, either + * the return values or the `CallSuccess` or `CallFailure` event can be used. + * @param to address The contract to call. + * @param data bytes The calldata to provide when making the call. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @param userSignature bytes A signature that resolves to the public key + * set for this account in storage slot zero, `_userSigningKey`. If the user + * signing key is not a contract, ecrecover will be used; otherwise, ERC1271 + * will be used. A unique hash returned from `getCustomActionID` is prefixed + * and hashed to create the message hash for the signature. + * @param dharmaSignature bytes A signature that resolves to the public key + * returned for this account from the Dharma Key Registry. A unique hash + * returned from `getCustomActionID` is prefixed and hashed to create the + * signed message. + * @return A boolean signifying the status of the call, as well as any data + * returned from the call. + */ + function executeAction( + address to, + bytes calldata data, + uint256 minimumActionGas, + bytes calldata userSignature, + bytes calldata dharmaSignature + ) external returns (bool ok, bytes memory returnData) { + // Ensure that the `to` address is a contract and is not this contract. + _ensureValidGenericCallTarget(to); + + // Ensure caller and/or supplied signatures are valid and increment nonce. + (bytes32 actionID, uint256 nonce) = _validateActionAndIncrementNonce( + ActionType.Generic, + abi.encode(to, data), + minimumActionGas, + userSignature, + dharmaSignature + ); + + // Note: from this point on, there are no reverts (apart from out-of-gas or + // call-depth-exceeded) originating from this action. However, the call + // itself may revert, in which case the function will return `false`, along + // with the revert reason encoded as bytes, and fire an CallFailure event. + + // Perform the action via low-level call and set return values using result. + (ok, returnData) = to.call(data); + + // Emit a CallSuccess or CallFailure event based on the outcome of the call. + if (ok) { + // Note: while the call succeeded, the action may still have "failed" + // (for example, successful calls to Compound can still return an error). + emit CallSuccess(actionID, false, nonce, to, data, returnData); + } else { + // Note: while the call failed, the nonce will still be incremented, which + // will invalidate all supplied signatures. + emit CallFailure(actionID, nonce, to, data, string(returnData)); + } + } + + /** + * @notice Allow signatory to set a new user signing key. The current nonce + * needs to be provided as an argument to the a signature so as not to enable + * griefing attacks. No value is returned from this function - it will either + * succeed or revert. + * @param userSigningKey address The new user signing key to set on this smart + * wallet. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @param userSignature bytes A signature that resolves to the public key + * set for this account in storage slot zero, `_userSigningKey`. If the user + * signing key is not a contract, ecrecover will be used; otherwise, ERC1271 + * will be used. A unique hash returned from `getCustomActionID` is prefixed + * and hashed to create the message hash for the signature. + * @param dharmaSignature bytes A signature that resolves to the public key + * returned for this account from the Dharma Key Registry. A unique hash + * returned from `getCustomActionID` is prefixed and hashed to create the + * signed message. + */ + function setUserSigningKey( + address userSigningKey, + uint256 minimumActionGas, + bytes calldata userSignature, + bytes calldata dharmaSignature + ) external { + // Ensure caller and/or supplied signatures are valid and increment nonce. + _validateActionAndIncrementNonce( + ActionType.SetUserSigningKey, + abi.encode(userSigningKey), + minimumActionGas, + userSignature, + dharmaSignature + ); + + // Set new user signing key on smart wallet and emit a corresponding event. + _setUserSigningKey(userSigningKey); + } + + /** + * @notice Set a dedicated address as the "escape hatch" account. This account + * can then call `escape()` at any point to "sweep" the entire Dai, USDC, + * residual cDai, cUSDC, dDai, dUSDC, and Ether balance from the smart wallet. + * This function call will revert if the smart wallet has previously called + * `permanentlyDisableEscapeHatch` at any point and disabled the escape hatch. + * No value is returned from this function - it will either succeed or revert. + * @param account address The account to set as the escape hatch account. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @param userSignature bytes A signature that resolves to the public key + * set for this account in storage slot zero, `_userSigningKey`. If the user + * signing key is not a contract, ecrecover will be used; otherwise, ERC1271 + * will be used. A unique hash returned from `getCustomActionID` is prefixed + * and hashed to create the message hash for the signature. + * @param dharmaSignature bytes A signature that resolves to the public key + * returned for this account from the Dharma Key Registry. A unique hash + * returned from `getCustomActionID` is prefixed and hashed to create the + * signed message. + */ + function setEscapeHatch( + address account, + uint256 minimumActionGas, + bytes calldata userSignature, + bytes calldata dharmaSignature + ) external { + // Ensure caller and/or supplied signatures are valid and increment nonce. + _validateActionAndIncrementNonce( + ActionType.SetEscapeHatch, + abi.encode(account), + minimumActionGas, + userSignature, + dharmaSignature + ); + + // Ensure that an escape hatch account has been provided. + require(account != address(0), "Must supply an escape hatch account."); + + // Set a new escape hatch for the smart wallet unless it has been disabled. + _ESCAPE_HATCH_REGISTRY.setEscapeHatch(account); + } + + /** + * @notice Remove the "escape hatch" account if one is currently set. This + * function call will revert if the smart wallet has previously called + * `permanentlyDisableEscapeHatch` at any point and disabled the escape hatch. + * No value is returned from this function - it will either succeed or revert. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @param userSignature bytes A signature that resolves to the public key + * set for this account in storage slot zero, `_userSigningKey`. If the user + * signing key is not a contract, ecrecover will be used; otherwise, ERC1271 + * will be used. A unique hash returned from `getCustomActionID` is prefixed + * and hashed to create the message hash for the signature. + * @param dharmaSignature bytes A signature that resolves to the public key + * returned for this account from the Dharma Key Registry. A unique hash + * returned from `getCustomActionID` is prefixed and hashed to create the + * signed message. + */ + function removeEscapeHatch( + uint256 minimumActionGas, + bytes calldata userSignature, + bytes calldata dharmaSignature + ) external { + // Ensure caller and/or supplied signatures are valid and increment nonce. + _validateActionAndIncrementNonce( + ActionType.RemoveEscapeHatch, + abi.encode(), + minimumActionGas, + userSignature, + dharmaSignature + ); + + // Remove the escape hatch for the smart wallet if one is currently set. + _ESCAPE_HATCH_REGISTRY.removeEscapeHatch(); + } + + /** + * @notice Permanently disable the "escape hatch" mechanism for this smart + * wallet. This function call will revert if the smart wallet has already + * called `permanentlyDisableEscapeHatch` at any point in the past. No value + * is returned from this function - it will either succeed or revert. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @param userSignature bytes A signature that resolves to the public key + * set for this account in storage slot zero, `_userSigningKey`. If the user + * signing key is not a contract, ecrecover will be used; otherwise, ERC1271 + * will be used. A unique hash returned from `getCustomActionID` is prefixed + * and hashed to create the message hash for the signature. + * @param dharmaSignature bytes A signature that resolves to the public key + * returned for this account from the Dharma Key Registry. A unique hash + * returned from `getCustomActionID` is prefixed and hashed to create the + * signed message. + */ + function permanentlyDisableEscapeHatch( + uint256 minimumActionGas, + bytes calldata userSignature, + bytes calldata dharmaSignature + ) external { + // Ensure caller and/or supplied signatures are valid and increment nonce. + _validateActionAndIncrementNonce( + ActionType.DisableEscapeHatch, + abi.encode(), + minimumActionGas, + userSignature, + dharmaSignature + ); + + // Permanently disable the escape hatch mechanism for this smart wallet. + _ESCAPE_HATCH_REGISTRY.permanentlyDisableEscapeHatch(); + } + + /** + * @notice Allow the designated escape hatch account to "sweep" the entire + * Sai, Dai, USDC, residual dDai, dUSDC, cSai, cDai & cUSDC, and Ether balance + * from the smart wallet. The call will revert for any other caller, or if + * there is no escape hatch account on this smart wallet. First, an attempt + * will be made to redeem any dDai or dUSDC that is currently deposited in a + * dToken. Then, attempts will be made to transfer all Sai, Dai, USDC, + * residual cSai, cDai & cUSDC, and Ether to the escape hatch account. If any + * portion of this operation does not succeed, it will simply be skipped, + * allowing the rest of the operation to proceed. Finally, an `Escaped` event + * will be emitted. No value is returned from this function - it will either + * succeed or revert. + */ + function escape() external { + // Get the escape hatch account, if one exists, for this account. + (bool exists, address escapeHatch) = _ESCAPE_HATCH_REGISTRY.getEscapeHatch(); + + // Ensure that an escape hatch is currently set for this smart wallet. + require(exists, "No escape hatch is currently set for this smart wallet."); + + // Ensure that the escape hatch account is the caller. + require( + msg.sender == escapeHatch, + "Only the escape hatch account may call this function." + ); + + // Attempt to redeem all dDai for Dai on Dharma Dai. + _withdrawMaxFromDharmaToken(AssetType.DAI); + + // Attempt to redeem all dUSDC for USDC on Dharma USDC. + _withdrawMaxFromDharmaToken(AssetType.USDC); + + // Attempt to transfer the total Dai balance to the caller. + _transferMax(_DAI, msg.sender, true); + + // Attempt to transfer the total USDC balance to the caller. + _transferMax(_USDC, msg.sender, true); + + // Attempt to transfer any residual cSai to the caller. + _transferMax(IERC20(address(_CSAI)), msg.sender, true); + + // Attempt to transfer any residual cDai to the caller. + _transferMax(IERC20(address(_CDAI)), msg.sender, true); + + // Attempt to transfer any residual cUSDC to the caller. + _transferMax(IERC20(address(_CUSDC)), msg.sender, true); + + // Attempt to transfer any residual dDai to the caller. + _transferMax(IERC20(address(_DDAI)), msg.sender, true); + + // Attempt to transfer any residual dUSDC to the caller. + _transferMax(IERC20(address(_DUSDC)), msg.sender, true); + + // Determine if there is Ether at this address that should be transferred. + uint256 balance = address(this).balance; + if (balance > 0) { + // Attempt to transfer any Ether to caller and emit an appropriate event. + _transferETH(msg.sender, balance); + } + + // Emit an `Escaped` event. + emit Escaped(); + } + + /** + * @notice Allow the account recovery manager to set a new user signing key on + * the smart wallet. The call will revert for any other caller. The account + * recovery manager implements a set of controls around the process, including + * a timelock and an option to permanently opt out of account recover. No + * value is returned from this function - it will either succeed or revert. + * @param newUserSigningKey address The new user signing key to set on this + * smart wallet. + */ + function recover(address newUserSigningKey) external { + require( + msg.sender == _ACCOUNT_RECOVERY_MANAGER, + "Only the account recovery manager may call this function." + ); + + // Increment nonce to prevent signature reuse should original key be reset. + _nonce++; + + // Set up the user's new dharma key and emit a corresponding event. + _setUserSigningKey(newUserSigningKey); + } + + /** + * @notice Convert all available Sai for Dai. If the conversion fails, or if + * the realized exchange rate is less than 1:1, the call will revert. Note + * that cSai is not included as part of this operation. + */ + function migrateSaiToDai() external { + // Swap the current Sai balance on this contract for Dai. + _swapSaiForDai(_SAI.balanceOf(address(this))); + } + + /** + * @notice Redeem all available cSAI for Sai, swap that Sai for Dai, and use + * that Dai to mint dDai. If any step in the process fails, the call will + * revert and prior steps will be rolled back. Also note that existing Sai and + * Dai are not included as part of this operation. + */ + function migrateCSaiToDDai() external { + // Get the current cSai balance for this account. + uint256 redeemAmount = _CSAI.balanceOf(address(this)); + + // Only perform the call to redeem if there is a non-zero balance. + if (redeemAmount > 0) { + // Get the current Sai balance on this contract. + uint256 currentSaiBalance = _SAI.balanceOf(address(this)); + + // Redeem underlying balance from cSai and revert if unsuccessful. + require( + _CSAI.redeem(redeemAmount) == _COMPOUND_SUCCESS, "cSai redeem failed." + ); + + // Calculate difference between pre-redeem and post-redeem Sai balances. + uint256 saiBalance = _SAI.balanceOf(address(this)) - currentSaiBalance; + + // Swap any Sai for Dai and get the newly-swapped Dai balance. + uint256 daiBalance = _swapSaiForDai(saiBalance); + + // If the dDai allowance is insufficient, set it before depositing. + if (_DAI.allowance(address(this), address(_DDAI)) < daiBalance) { + require( + _DAI.approve(address(_DDAI), uint256(-1)), "Dai approval failed." + ); + } + + // Deposit the new Dai balance on Dharma Dai. + _DDAI.mint(daiBalance); + } + } + + /** + * @notice Redeem all available cDAI for Dai and use that Dai to mint dDai. If + * any step in the process fails, the call will revert and prior steps will be + * rolled back. Also note that existing Sai and Dai are not included as part + * of this operation. + */ + function migrateCDaiToDDai() external { + _migrateCTokenToDToken(AssetType.DAI); + } + + /** + * @notice Redeem all available cUSDC for USDC and use that USDC to mint + * dUSDC. If any step in the process fails, the call will revert and prior + * steps will be rolled back. Also note that existing USDC is not included as + * part of this operation. + */ + function migrateCUSDCToDUSDC() external { + _migrateCTokenToDToken(AssetType.USDC); + } + + /** + * @notice Retrieve the Dai and USDC balances held by the smart wallet, both + * directly and held in Dharma Dai and Dharma USD Coin. + * @return The Dai balance, the USDC balance, the underlying Dai balance of + * the dDai balance, and the underlying USDC balance of the dUSDC balance. + */ + function getBalances() external returns ( + uint256 daiBalance, + uint256 usdcBalance, + uint256 etherBalance, // always returns 0 + uint256 dDaiUnderlyingDaiBalance, + uint256 dUsdcUnderlyingUsdcBalance, + uint256 dEtherUnderlyingEtherBalance // always returns 0 + ) { + daiBalance = _DAI.balanceOf(address(this)); + usdcBalance = _USDC.balanceOf(address(this)); + dDaiUnderlyingDaiBalance = _DDAI.balanceOfUnderlying(address(this)); + dUsdcUnderlyingUsdcBalance = _DUSDC.balanceOfUnderlying(address(this)); + } + + /** + * @notice View function for getting the current user signing key for the + * smart wallet. + * @return The current user signing key. + */ + function getUserSigningKey() external view returns (address userSigningKey) { + userSigningKey = _userSigningKey; + } + + /** + * @notice View function for getting the current nonce of the smart wallet. + * This nonce is incremented whenever an action is taken that requires a + * signature and/or a specific caller. + * @return The current nonce. + */ + function getNonce() external view returns (uint256 nonce) { + nonce = _nonce; + } + + /** + * @notice View function that, given an action type and arguments, will return + * the action ID or message hash that will need to be prefixed (according to + * EIP-191 0x45), hashed, and signed by both the user signing key and by the + * key returned for this smart wallet by the Dharma Key Registry in order to + * construct a valid signature for the corresponding action. Any nonce value + * may be supplied, which enables constructing valid message hashes for + * multiple future actions ahead of time. + * @param action uint8 The type of action, designated by it's index. Valid + * custom actions in V7 include Cancel (0), SetUserSigningKey (1), + * DAIWithdrawal (10), USDCWithdrawal (5), ETHWithdrawal (6), + * SetEscapeHatch (7), RemoveEscapeHatch (8), and DisableEscapeHatch (9). + * @param amount uint256 The amount to withdraw for Withdrawal actions. This + * value is ignored for non-withdrawal action types. + * @param recipient address The account to transfer withdrawn funds to or the + * new user signing key. This value is ignored for Cancel, RemoveEscapeHatch, + * and DisableEscapeHatch action types. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @return The action ID, which will need to be prefixed, hashed and signed in + * order to construct a valid signature. + */ + function getNextCustomActionID( + ActionType action, + uint256 amount, + address recipient, + uint256 minimumActionGas + ) external view returns (bytes32 actionID) { + // Determine the actionID - this serves as a signature hash for an action. + actionID = _getActionID( + action, + _validateCustomActionTypeAndGetArguments(action, amount, recipient), + _nonce, + minimumActionGas, + _userSigningKey, + _getDharmaSigningKey() + ); + } + + /** + * @notice View function that, given an action type and arguments, will return + * the action ID or message hash that will need to be prefixed (according to + * EIP-191 0x45), hashed, and signed by both the user signing key and by the + * key returned for this smart wallet by the Dharma Key Registry in order to + * construct a valid signature for the corresponding action. The current nonce + * will be used, which means that it will only be valid for the next action + * taken. + * @param action uint8 The type of action, designated by it's index. Valid + * custom actions in V6 include Cancel (0), SetUserSigningKey (1), + * DAIWithdrawal (10), USDCWithdrawal (5), ETHWithdrawal (6), + * SetEscapeHatch (7), RemoveEscapeHatch (8), and DisableEscapeHatch (9). + * @param amount uint256 The amount to withdraw for Withdrawal actions. This + * value is ignored for non-withdrawal action types. + * @param recipient address The account to transfer withdrawn funds to or the + * new user signing key. This value is ignored for Cancel, RemoveEscapeHatch, + * and DisableEscapeHatch action types. + * @param nonce uint256 The nonce to use. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @return The action ID, which will need to be prefixed, hashed and signed in + * order to construct a valid signature. + */ + function getCustomActionID( + ActionType action, + uint256 amount, + address recipient, + uint256 nonce, + uint256 minimumActionGas + ) external view returns (bytes32 actionID) { + // Determine the actionID - this serves as a signature hash for an action. + actionID = _getActionID( + action, + _validateCustomActionTypeAndGetArguments(action, amount, recipient), + nonce, + minimumActionGas, + _userSigningKey, + _getDharmaSigningKey() + ); + } + + /** + * @notice View function that, given an action type and arguments, will return + * the action ID or message hash that will need to be prefixed (according to + * EIP-191 0x45), hashed, and signed by both the user signing key and by the + * key returned for this smart wallet by the Dharma Key Registry in order to + * construct a valid signature for a given generic action. The current nonce + * will be used, which means that it will only be valid for the next action + * taken. + * @param to address The target to call into as part of the generic action. + * @param data bytes The data to supply when calling into the target. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @return The action ID, which will need to be prefixed, hashed and signed in + * order to construct a valid signature. + */ + function getNextGenericActionID( + address to, + bytes calldata data, + uint256 minimumActionGas + ) external view returns (bytes32 actionID) { + // Determine the actionID - this serves as a signature hash for an action. + actionID = _getActionID( + ActionType.Generic, + abi.encode(to, data), + _nonce, + minimumActionGas, + _userSigningKey, + _getDharmaSigningKey() + ); + } + + /** + * @notice View function that, given an action type and arguments, will return + * the action ID or message hash that will need to be prefixed (according to + * EIP-191 0x45), hashed, and signed by both the user signing key and by the + * key returned for this smart wallet by the Dharma Key Registry in order to + * construct a valid signature for a given generic action. Any nonce value may + * be supplied, which enables constructing valid message hashes for multiple + * future actions ahead of time. + * @param to address The target to call into as part of the generic action. + * @param data bytes The data to supply when calling into the target. + * @param nonce uint256 The nonce to use. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @return The action ID, which will need to be prefixed, hashed and signed in + * order to construct a valid signature. + */ + function getGenericActionID( + address to, + bytes calldata data, + uint256 nonce, + uint256 minimumActionGas + ) external view returns (bytes32 actionID) { + // Determine the actionID - this serves as a signature hash for an action. + actionID = _getActionID( + ActionType.Generic, + abi.encode(to, data), + nonce, + minimumActionGas, + _userSigningKey, + _getDharmaSigningKey() + ); + } + + /** + * @notice Pure function for getting the current Dharma Smart Wallet version. + * @return The current Dharma Smart Wallet version. + */ + function getVersion() external pure returns (uint256 version) { + version = _DHARMA_SMART_WALLET_VERSION; + } + + /** + * @notice Perform a series of generic calls to other contracts. If any call + * fails during execution, the preceding calls will be rolled back, but their + * original return data will still be accessible. Calls that would otherwise + * occur after the failed call will not be executed. Note that accounts with + * no code may not be specified, nor may the smart wallet itself or the escape + * hatch registry. In order to increment the nonce and invalidate the + * signatures, a call to this function with valid targets, signatutes, and gas + * will always succeed. To determine whether each call made as part of the + * action was successful or not, either the corresponding return value or the + * corresponding `CallSuccess` or `CallFailure` event can be used - note that + * even calls that return a success status will have been rolled back unless + * all of the calls returned a success status. Finally, note that this + * function must currently be implemented as a public function (instead of as + * an external one) due to an ABIEncoderV2 `UnimplementedFeatureError`. + * @param calls Call[] A struct containing the target and calldata to provide + * when making each call. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @param userSignature bytes A signature that resolves to the public key + * set for this account in storage slot zero, `_userSigningKey`. If the user + * signing key is not a contract, ecrecover will be used; otherwise, ERC1271 + * will be used. A unique hash returned from `getCustomActionID` is prefixed + * and hashed to create the message hash for the signature. + * @param dharmaSignature bytes A signature that resolves to the public key + * returned for this account from the Dharma Key Registry. A unique hash + * returned from `getCustomActionID` is prefixed and hashed to create the + * signed message. + * @return An array of structs signifying the status of each call, as well as + * any data returned from that call. Calls that are not executed will return + * empty data. + */ + function executeActionWithAtomicBatchCalls( + Call[] memory calls, + uint256 minimumActionGas, + bytes memory userSignature, + bytes memory dharmaSignature + ) public returns (bool[] memory ok, bytes[] memory returnData) { + // Ensure that each `to` address is a contract and is not this contract. + for (uint256 i = 0; i < calls.length; i++) { + _ensureValidGenericCallTarget(calls[i].to); + } + + // Ensure caller and/or supplied signatures are valid and increment nonce. + (bytes32 actionID, uint256 nonce) = _validateActionAndIncrementNonce( + ActionType.GenericAtomicBatch, + abi.encode(calls), + minimumActionGas, + userSignature, + dharmaSignature + ); + + // Note: from this point on, there are no reverts (apart from out-of-gas or + // call-depth-exceeded) originating from this contract. However, one of the + // calls may revert, in which case the function will return `false`, along + // with the revert reason encoded as bytes, and fire an CallFailure event. + + // Specify length of returned values in order to work with them in memory. + ok = new bool[](calls.length); + returnData = new bytes[](calls.length); + + // Set self-call context to call _executeActionWithAtomicBatchCallsAtomic. + _selfCallContext = this.executeActionWithAtomicBatchCalls.selector; + + // Make the atomic self-call - if any call fails, calls that preceded it + // will be rolled back and calls that follow it will not be made. + (bool externalOk, bytes memory rawCallResults) = address(this).call( + abi.encodeWithSelector( + this._executeActionWithAtomicBatchCallsAtomic.selector, calls + ) + ); + + // Parse data returned from self-call into each call result and store / log. + CallReturn[] memory callResults = abi.decode(rawCallResults, (CallReturn[])); + for (uint256 i = 0; i < callResults.length; i++) { + Call memory currentCall = calls[i]; + + // Set the status and the return data / revert reason from the call. + ok[i] = callResults[i].ok; + returnData[i] = callResults[i].returnData; + + // Emit CallSuccess or CallFailure event based on the outcome of the call. + if (callResults[i].ok) { + // Note: while the call succeeded, the action may still have "failed". + emit CallSuccess( + actionID, + !externalOk, // if another call failed this will have been rolled back + nonce, + currentCall.to, + currentCall.data, + callResults[i].returnData + ); + } else { + // Note: while the call failed, the nonce will still be incremented, + // which will invalidate all supplied signatures. + emit CallFailure( + actionID, + nonce, + currentCall.to, + currentCall.data, + string(callResults[i].returnData) + ); + + // exit early - any calls after the first failed call will not execute. + break; + } + } + } + + /** + * @notice Protected function that can only be called from + * `executeActionWithAtomicBatchCalls` on this contract. It will attempt to + * perform each specified call, populating the array of results as it goes, + * unless a failure occurs, at which point it will revert and "return" the + * array of results as revert data. Otherwise, it will simply return the array + * upon successful completion of each call. Finally, note that this function + * must currently be implemented as a public function (instead of as an + * external one) due to an ABIEncoderV2 `UnimplementedFeatureError`. + * @param calls Call[] A struct containing the target and calldata to provide + * when making each call. + * @return An array of structs signifying the status of each call, as well as + * any data returned from that call. Calls that are not executed will return + * empty data. If any of the calls fail, the array will be returned as revert + * data. + */ + function _executeActionWithAtomicBatchCallsAtomic( + Call[] memory calls + ) public returns (CallReturn[] memory callResults) { + // Ensure caller is this contract and self-call context is correctly set. + _enforceSelfCallFrom(this.executeActionWithAtomicBatchCalls.selector); + + bool rollBack = false; + callResults = new CallReturn[](calls.length); + + for (uint256 i = 0; i < calls.length; i++) { + // Perform low-level call and set return values using result. + (bool ok, bytes memory returnData) = calls[i].to.call(calls[i].data); + callResults[i] = CallReturn({ok: ok, returnData: returnData}); + if (!ok) { + // Exit early - any calls after the first failed call will not execute. + rollBack = true; + break; + } + } + + if (rollBack) { + // Wrap in length encoding and revert (provide data instead of a string). + bytes memory callResultsBytes = abi.encode(callResults); + assembly { revert(add(32, callResultsBytes), mload(callResultsBytes)) } + } + } + + /** + * @notice View function that, given an action type and arguments, will return + * the action ID or message hash that will need to be prefixed (according to + * EIP-191 0x45), hashed, and signed by both the user signing key and by the + * key returned for this smart wallet by the Dharma Key Registry in order to + * construct a valid signature for a given generic atomic batch action. The + * current nonce will be used, which means that it will only be valid for the + * next action taken. Finally, note that this function must currently be + * implemented as a public function (instead of as an external one) due to an + * ABIEncoderV2 `UnimplementedFeatureError`. + * @param calls Call[] A struct containing the target and calldata to provide + * when making each call. + * @param calls Call[] A struct containing the target and calldata to provide + * when making each call. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @return The action ID, which will need to be prefixed, hashed and signed in + * order to construct a valid signature. + */ + function getNextGenericAtomicBatchActionID( + Call[] memory calls, + uint256 minimumActionGas + ) public view returns (bytes32 actionID) { + // Determine the actionID - this serves as a signature hash for an action. + actionID = _getActionID( + ActionType.GenericAtomicBatch, + abi.encode(calls), + _nonce, + minimumActionGas, + _userSigningKey, + _getDharmaSigningKey() + ); + } + + /** + * @notice View function that, given an action type and arguments, will return + * the action ID or message hash that will need to be prefixed (according to + * EIP-191 0x45), hashed, and signed by both the user signing key and by the + * key returned for this smart wallet by the Dharma Key Registry in order to + * construct a valid signature for a given generic atomic batch action. Any + * nonce value may be supplied, which enables constructing valid message + * hashes for multiple future actions ahead of time. Finally, note that this + * function must currently be implemented as a public function (instead of as + * an external one) due to an ABIEncoderV2 `UnimplementedFeatureError`. + * @param calls Call[] A struct containing the target and calldata to provide + * when making each call. + * @param calls Call[] A struct containing the target and calldata to provide + * when making each call. + * @param nonce uint256 The nonce to use. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @return The action ID, which will need to be prefixed, hashed and signed in + * order to construct a valid signature. + */ + function getGenericAtomicBatchActionID( + Call[] memory calls, + uint256 nonce, + uint256 minimumActionGas + ) public view returns (bytes32 actionID) { + // Determine the actionID - this serves as a signature hash for an action. + actionID = _getActionID( + ActionType.GenericAtomicBatch, + abi.encode(calls), + nonce, + minimumActionGas, + _userSigningKey, + _getDharmaSigningKey() + ); + } + + /** + * @notice Internal function for setting a new user signing key. Called by the + * initializer, by the `setUserSigningKey` function, and by the `recover` + * function. A `NewUserSigningKey` event will also be emitted. + * @param userSigningKey address The new user signing key to set on this smart + * wallet. + */ + function _setUserSigningKey(address userSigningKey) internal { + // Ensure that a user signing key is set on this smart wallet. + require(userSigningKey != address(0), "No user signing key provided."); + + _userSigningKey = userSigningKey; + emit NewUserSigningKey(userSigningKey); + } + + /** + * @notice Internal function for converting a Sai balance to Dai. The total + * amount of received Dai must be greater than or equal to the total amount of + * swapped Sai. + * @param saiToSwap uint256 The amount of Sai to swap. + * @return The amount of Dai received as part of the swap. + */ + function _swapSaiForDai(uint256 saiToSwap) internal returns (uint256 dai) { + // If the balance is non-zero, check if migrator has adequate approval. + if (saiToSwap > 0) { + uint256 allowance = _SAI.allowance(address(this), address(_MIGRATOR)); + + // Ensure that allowance is sufficient before calling the migrator. + if (saiToSwap > allowance) { + // Approve migrator contract to transfer Sai on behalf of this wallet. + require( + _SAI.approve(address(_MIGRATOR), uint256(-1)), "Sai approval failed." + ); + } + + // Get the current Dai balance on this contract. + uint256 currentDaiBalance = _DAI.balanceOf(address(this)); + + // Call migrator contract to swap the supplied Sai balance for Dai. + _MIGRATOR.swapSaiToDai(saiToSwap); + + // Return the difference between the pre-swap and post-swap Dai balances. + dai = _DAI.balanceOf(address(this)) - currentDaiBalance; + + // Ensure that the Sai-to-Dai exchange rate was at least 1-to-1. + require(dai >= saiToSwap, "Exchange rate cannot be below 1:1."); + } else { + // Explicitly specify a change in balance of zero if no swap occurred. + dai = 0; + } + } + + /** + * @notice Internal function for setting the allowance of a given ERC20 asset + * to the maximum value. This enables the corresponding dToken for the asset + * to pull in tokens in order to make deposits. + * @param asset uint256 The ID of the asset, either Dai (0) or USDC (1). + * @return True if the approval succeeded, otherwise false. + */ + function _setFullApproval(AssetType asset) internal returns (bool ok) { + // Get asset's underlying token address and corresponding dToken address. + address token; + address dToken; + if (asset == AssetType.DAI) { + token = address(_DAI); + dToken = address(_DDAI); + } else { + token = address(_USDC); + dToken = address(_DUSDC); + } + + // Approve dToken contract to transfer underlying on behalf of this wallet. + (ok, ) = address(token).call(abi.encodeWithSelector( + // Note: since both Tokens have the same interface, just use DAI's. + _DAI.approve.selector, dToken, uint256(-1) + )); + + // Emit a corresponding event if the approval failed. + if (!ok) { + if (asset == AssetType.DAI) { + emit ExternalError(address(_DAI), "DAI contract reverted on approval."); + } else { + // Find out why USDC transfer reverted (it doesn't give revert reasons). + _diagnoseAndEmitUSDCSpecificError(_USDC.approve.selector); + } + } + } + + /** + * @notice Internal function for depositing a given ERC20 asset and balance on + * the corresponding dToken. No value is returned, as no additional steps need + * to be conditionally performed after the deposit. + * @param asset uint256 The ID of the asset, either Dai (0) or USDC (1). + * @param balance uint256 The amount of the asset to deposit. Note that an + * attempt to deposit "dust" (i.e. very small amounts) may result in 0 dTokens + * being minted, or in fewer dTokens being minted than is implied by the + * current exchange rate (due to lack of sufficient precision on the tokens). + */ + function _depositDharmaToken(AssetType asset, uint256 balance) internal { + // Only perform a deposit if the balance is at least .001 Dai or USDC. + if ( + asset == AssetType.DAI && balance > _JUST_UNDER_ONE_1000th_DAI || + asset == AssetType.USDC && balance > _JUST_UNDER_ONE_1000th_USDC + ) { + // Get dToken address for the asset type. + address dToken = asset == AssetType.DAI ? address(_DDAI) : address(_DUSDC); + + // Attempt to mint the balance on the dToken contract. + (bool ok, bytes memory data) = dToken.call(abi.encodeWithSelector( + // Note: since both dTokens have the same interface, just use dDai's. + _DDAI.mint.selector, balance + )); + + // Log an external error if something went wrong with the attempt. + _checkDharmaTokenInteractionAndLogAnyErrors( + asset, _DDAI.mint.selector, ok, data + ); + } + } + + /** + * @notice Internal function for withdrawing a given underlying asset balance + * from the corresponding dToken. Note that the requested balance may not be + * currently available on Compound, which will cause the withdrawal to fail. + * @param asset uint256 The asset's ID, either Dai (0) or USDC (1). + * @param balance uint256 The amount of the asset to withdraw, denominated in + * the underlying token. Note that an attempt to withdraw "dust" (i.e. very + * small amounts) may result in 0 underlying tokens being redeemed, or in + * fewer tokens being redeemed than is implied by the current exchange rate + * (due to lack of sufficient precision on the tokens). + * @return True if the withdrawal succeeded, otherwise false. + */ + function _withdrawFromDharmaToken( + AssetType asset, uint256 balance + ) internal returns (bool success) { + // Get dToken address for the asset type. (No custom ETH withdrawal action.) + address dToken = asset == AssetType.DAI ? address(_DDAI) : address(_DUSDC); + + // Attempt to redeem the underlying balance from the dToken contract. + (bool ok, bytes memory data) = dToken.call(abi.encodeWithSelector( + // Note: function selector is the same for each dToken so just use dDai's. + _DDAI.redeemUnderlying.selector, balance + )); + + // Log an external error if something went wrong with the attempt. + success = _checkDharmaTokenInteractionAndLogAnyErrors( + asset, _DDAI.redeemUnderlying.selector, ok, data + ); + } + + /** + * @notice Internal function for withdrawing the total underlying asset + * balance from the corresponding dToken. Note that the requested balance may + * not be currently available on Compound, which will cause the withdrawal to + * fail. + * @param asset uint256 The asset's ID, either Dai (0) or USDC (1). + */ + function _withdrawMaxFromDharmaToken(AssetType asset) internal { + // Get dToken address for the asset type. (No custom ETH withdrawal action.) + address dToken = asset == AssetType.DAI ? address(_DDAI) : address(_DUSDC); + + // Get the current dToken balance for this account. + uint256 redeemAmount = IERC20(dToken).balanceOf(address(this)); + + // Only perform the call to redeem if there is a non-zero balance. + if (redeemAmount > 0) { + // Attempt to redeem the underlying balance from the dToken contract. + (bool ok, bytes memory data) = dToken.call(abi.encodeWithSelector( + // Function selector is the same for all dTokens, so just use dDai's. + _DDAI.redeem.selector, redeemAmount + )); + + // Log an external error if something went wrong with the attempt. + _checkDharmaTokenInteractionAndLogAnyErrors( + asset, _DDAI.redeem.selector, ok, data + ); + } + } + + /** + * @notice Internal function for transferring the total underlying balance of + * the corresponding token to a designated recipient. It will return true if + * tokens were successfully transferred (or there is no balance), signified by + * the boolean returned by the transfer function, or the call status if the + * `suppressRevert` boolean is set to true. + * @param token IERC20 The interface of the token in question. + * @param recipient address The account that will receive the tokens. + * @param suppressRevert bool A boolean indicating whether reverts should be + * suppressed or not. Used by the escape hatch so that a problematic transfer + * will not block the rest of the call from executing. + * @return True if tokens were successfully transferred or if there is no + * balance, else false. + */ + function _transferMax( + IERC20 token, address recipient, bool suppressRevert + ) internal returns (bool success) { + // Get the current balance on the smart wallet for the supplied ERC20 token. + uint256 transferAmount = token.balanceOf(address(this)); + + // Only perform the call to transfer if there is a non-zero balance. + if (transferAmount > 0) { + if (!suppressRevert) { + // Perform the transfer and pass along the returned boolean (or revert). + success = token.transfer(recipient, transferAmount); + } else { + // Attempt transfer with 1/2 gas, allow reverts, and return call status. + (success, ) = address(token).call.gas(gasleft() / 2)( + abi.encodeWithSelector( + token.transfer.selector, recipient, transferAmount + ) + ); + } + } else { + // Skip the transfer and return true. + success = true; + } + } + + /** + * @notice Internal function for transferring Ether to a designated recipient. + * It will return true and emit an `EthWithdrawal` event if Ether was + * successfully transferred - otherwise, it will return false and emit an + * `ExternalError` event. + * @param recipient address payable The account that will receive the Ether. + * @param amount uint256 The amount of Ether to transfer. + * @return True if Ether was successfully transferred, else false. + */ + function _transferETH( + address payable recipient, uint256 amount + ) internal returns (bool success) { + // Attempt to transfer any Ether to caller and emit an event if it fails. + (success, ) = recipient.call.gas(_ETH_TRANSFER_GAS).value(amount)(""); + if (!success) { + emit ExternalError(recipient, "Recipient rejected ether transfer."); + } else { + emit EthWithdrawal(amount, recipient); + } + } + + /** + * @notice Internal function for validating supplied gas (if specified), + * retrieving the signer's public key from the Dharma Key Registry, deriving + * the action ID, validating the provided caller and/or signatures using that + * action ID, and incrementing the nonce. This function serves as the + * entrypoint for all protected "actions" on the smart wallet, and is the only + * area where these functions should revert (other than due to out-of-gas + * errors, which can be guarded against by supplying a minimum action gas + * requirement). + * @param action uint8 The type of action, designated by it's index. Valid + * actions in V6 include Cancel (0), SetUserSigningKey (1), Generic (2), + * GenericAtomicBatch (3), DAIWithdrawal (10), USDCWithdrawal (5), + * ETHWithdrawal (6), SetEscapeHatch (7), RemoveEscapeHatch (8), and + * DisableEscapeHatch (9). + * @param arguments bytes ABI-encoded arguments for the action. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @param userSignature bytes A signature that resolves to the public key + * set for this account in storage slot zero, `_userSigningKey`. If the user + * signing key is not a contract, ecrecover will be used; otherwise, ERC1271 + * will be used. A unique hash returned from `getCustomActionID` is prefixed + * and hashed to create the message hash for the signature. + * @param dharmaSignature bytes A signature that resolves to the public key + * returned for this account from the Dharma Key Registry. A unique hash + * returned from `getCustomActionID` is prefixed and hashed to create the + * signed message. + * @return The nonce of the current action (prior to incrementing it). + */ + function _validateActionAndIncrementNonce( + ActionType action, + bytes memory arguments, + uint256 minimumActionGas, + bytes memory userSignature, + bytes memory dharmaSignature + ) internal returns (bytes32 actionID, uint256 actionNonce) { + // Ensure that the current gas exceeds the minimum required action gas. + // This prevents griefing attacks where an attacker can invalidate a + // signature without providing enough gas for the action to succeed. Also + // note that some gas will be spent before this check is reached - supplying + // ~30,000 additional gas should suffice when submitting transactions. To + // skip this requirement, supply zero for the minimumActionGas argument. + if (minimumActionGas != 0) { + require( + gasleft() >= minimumActionGas, + "Invalid action - insufficient gas supplied by transaction submitter." + ); + } + + // Get the current nonce for the action to be performed. + actionNonce = _nonce; + + // Get the user signing key that will be used to verify their signature. + address userSigningKey = _userSigningKey; + + // Get the Dharma signing key that will be used to verify their signature. + address dharmaSigningKey = _getDharmaSigningKey(); + + // Determine the actionID - this serves as the signature hash. + actionID = _getActionID( + action, + arguments, + actionNonce, + minimumActionGas, + userSigningKey, + dharmaSigningKey + ); + + // Compute the message hash - the hashed, EIP-191-0x45-prefixed action ID. + bytes32 messageHash = actionID.toEthSignedMessageHash(); + + // Actions other than Cancel require both signatures; Cancel only needs one. + if (action != ActionType.Cancel) { + // Validate user signing key signature unless it is `msg.sender`. + if (msg.sender != userSigningKey) { + require( + _validateUserSignature( + messageHash, action, arguments, userSigningKey, userSignature + ), + "Invalid action - invalid user signature." + ); + } + + // Validate Dharma signing key signature unless it is `msg.sender`. + if (msg.sender != dharmaSigningKey) { + require( + dharmaSigningKey == messageHash.recover(dharmaSignature), + "Invalid action - invalid Dharma signature." + ); + } + } else { + // Validate signing key signature unless user or Dharma is `msg.sender`. + if (msg.sender != userSigningKey && msg.sender != dharmaSigningKey) { + require( + dharmaSigningKey == messageHash.recover(dharmaSignature) || + _validateUserSignature( + messageHash, action, arguments, userSigningKey, userSignature + ), + "Invalid action - invalid signature." + ); + } + } + + // Increment nonce in order to prevent reuse of signatures after the call. + _nonce++; + } + + /** + * @notice Use all available cTokens to mint the respective dTokens. If any + * step in the process fails, the call will revert and prior steps will be + * rolled back. Also note that existing underlying tokens are not included as + * part of this operation. + */ + function _migrateCTokenToDToken(AssetType token) internal { + CTokenInterface cToken; + DTokenInterface dToken; + + if (token == AssetType.DAI) { + cToken = _CDAI; + dToken = _DDAI; + } else { + cToken = _CUSDC; + dToken = _DUSDC; + } + + // Get the current cToken balance for this account. + uint256 balance = cToken.balanceOf(address(this)); + + // Only perform the conversion if there is a non-zero balance. + if (balance > 0) { + // If the allowance is insufficient, set it before depositing. + if (cToken.allowance(address(this), address(dToken)) < balance) { + require( + cToken.approve(address(dToken), uint256(-1)), "Approval failed." + ); + } + + // Deposit the new balance on the Dharma Token. + dToken.mintViaCToken(balance); + } + } + + /** + * @notice Internal function to determine whether a call to a given dToken + * succeeded, and to emit a relevant ExternalError event if it failed. + * @param asset uint256 The ID of the asset, either Dai (0) or USDC (1). + * @param functionSelector bytes4 The function selector that was called on the + * corresponding dToken of the asset type. + * @param ok bool A boolean representing whether the call returned or + * reverted. + * @param data bytes The data provided by the returned or reverted call. + * @return True if the interaction was successful, otherwise false. This will + * be used to determine if subsequent steps in the action should be attempted + * or not, specifically a transfer following a withdrawal. + */ + function _checkDharmaTokenInteractionAndLogAnyErrors( + AssetType asset, + bytes4 functionSelector, + bool ok, + bytes memory data + ) internal returns (bool success) { + // Log an external error if something went wrong with the attempt. + if (ok) { + success = true; + } else { + // Get called contract address, name of contract, and function name. + (address account, string memory name, string memory functionName) = ( + _getDharmaTokenDetails(asset, functionSelector) + ); + + // Decode the revert reason in the event one was returned. + string memory revertReason = _decodeRevertReason(data); + + emit ExternalError( + account, + string( + abi.encodePacked( + name, + " contract reverted while attempting to call ", + functionName, + ": ", + revertReason + ) + ) + ); + } + } + + /** + * @notice Internal function to diagnose the reason that a call to the USDC + * contract failed and to emit a corresponding ExternalError event. USDC can + * blacklist accounts and pause the contract, which can both cause a transfer + * or approval to fail. + * @param functionSelector bytes4 The function selector that was called on the + * USDC contract. + */ + function _diagnoseAndEmitUSDCSpecificError(bytes4 functionSelector) internal { + // Determine the name of the function that was called on USDC. + string memory functionName; + if (functionSelector == _USDC.transfer.selector) { + functionName = "transfer"; + } else { + functionName = "approve"; + } + + // Find out why USDC transfer reverted (it doesn't give revert reasons). + if (_USDC_NAUGHTY.isBlacklisted(address(this))) { + emit ExternalError( + address(_USDC), + string( + abi.encodePacked( + functionName, " failed - USDC has blacklisted this user." + ) + ) + ); + } else { // Note: `else if` breaks coverage. + if (_USDC_NAUGHTY.paused()) { + emit ExternalError( + address(_USDC), + string( + abi.encodePacked( + functionName, " failed - USDC contract is currently paused." + ) + ) + ); + } else { + emit ExternalError( + address(_USDC), + string( + abi.encodePacked( + "USDC contract reverted on ", functionName, "." + ) + ) + ); + } + } + } + + /** + * @notice Internal function to ensure that protected functions can only be + * called from this contract and that they have the appropriate context set. + * The self-call context is then cleared. It is used as an additional guard + * against reentrancy, especially once generic actions are supported by the + * smart wallet in future versions. + * @param selfCallContext bytes4 The expected self-call context, equal to the + * function selector of the approved calling function. + */ + function _enforceSelfCallFrom(bytes4 selfCallContext) internal { + // Ensure caller is this contract and self-call context is correctly set. + require( + msg.sender == address(this) && + _selfCallContext == selfCallContext, + "External accounts or unapproved internal functions cannot call this." + ); + + // Clear the self-call context. + delete _selfCallContext; + } + + /** + * @notice Internal view function for validating a user's signature. If the + * user's signing key does not have contract code, it will be validated via + * ecrecover; otherwise, it will be validated using ERC-1271, passing the + * message hash that was signed, the action type, and the arguments as data. + * @param messageHash bytes32 The message hash that is signed by the user. It + * is derived by prefixing (according to EIP-191 0x45) and hashing an actionID + * returned from `getCustomActionID`. + * @param action uint8 The type of action, designated by it's index. Valid + * actions in V6 include Cancel (0), SetUserSigningKey (1), Generic (2), + * GenericAtomicBatch (3), DAIWithdrawal (10), USDCWithdrawal (5), + * ETHWithdrawal (6), SetEscapeHatch (7), RemoveEscapeHatch (8), and + * DisableEscapeHatch (9). + * @param arguments bytes ABI-encoded arguments for the action. + * @param userSignature bytes A signature that resolves to the public key + * set for this account in storage slot zero, `_userSigningKey`. If the user + * signing key is not a contract, ecrecover will be used; otherwise, ERC1271 + * will be used. + * @return A boolean representing the validity of the supplied user signature. + */ + function _validateUserSignature( + bytes32 messageHash, + ActionType action, + bytes memory arguments, + address userSigningKey, + bytes memory userSignature + ) internal view returns (bool valid) { + if (!userSigningKey.isContract()) { + valid = userSigningKey == messageHash.recover(userSignature); + } else { + bytes memory data = abi.encode(messageHash, action, arguments); + valid = ( + ERC1271(userSigningKey).isValidSignature( + data, userSignature + ) == _ERC_1271_MAGIC_VALUE + ); + } + } + + /** + * @notice Internal view function to get the Dharma signing key for the smart + * wallet from the Dharma Key Registry. This key can be set for each specific + * smart wallet - if none has been set, a global fallback key will be used. + * @return The address of the Dharma signing key, or public key corresponding + * to the secondary signer. + */ + function _getDharmaSigningKey() internal view returns ( + address dharmaSigningKey + ) { + dharmaSigningKey = _DHARMA_KEY_REGISTRY.getKey(); + } + + /** + * @notice Internal view function that, given an action type and arguments, + * will return the action ID or message hash that will need to be prefixed + * (according to EIP-191 0x45), hashed, and signed by the key designated by + * the Dharma Key Registry in order to construct a valid signature for the + * corresponding action. The current nonce will be supplied to this function + * when reconstructing an action ID during protected function execution based + * on the supplied parameters. + * @param action uint8 The type of action, designated by it's index. Valid + * actions in V6 include Cancel (0), SetUserSigningKey (1), Generic (2), + * GenericAtomicBatch (3), DAIWithdrawal (10), USDCWithdrawal (5), + * ETHWithdrawal (6), SetEscapeHatch (7), RemoveEscapeHatch (8), and + * DisableEscapeHatch (9). + * @param arguments bytes ABI-encoded arguments for the action. + * @param nonce uint256 The nonce to use. + * @param minimumActionGas uint256 The minimum amount of gas that must be + * provided to this call - be aware that additional gas must still be included + * to account for the cost of overhead incurred up until the start of this + * function call. + * @param dharmaSigningKey address The address of the secondary key, or public + * key corresponding to the secondary signer. + * @return The action ID, which will need to be prefixed, hashed and signed in + * order to construct a valid signature. + */ + function _getActionID( + ActionType action, + bytes memory arguments, + uint256 nonce, + uint256 minimumActionGas, + address userSigningKey, + address dharmaSigningKey + ) internal view returns (bytes32 actionID) { + // actionID is constructed according to EIP-191-0x45 to prevent replays. + actionID = keccak256( + abi.encodePacked( + address(this), + _DHARMA_SMART_WALLET_VERSION, + userSigningKey, + dharmaSigningKey, + nonce, + minimumActionGas, + action, + arguments + ) + ); + } + + /** + * @notice Internal pure function to get the dToken address, it's name, and + * the name of the called function, based on a supplied asset type and + * function selector. It is used to help construct ExternalError events. + * @param asset uint256 The ID of the asset, either Dai (0) or USDC (1). + * @param functionSelector bytes4 The function selector that was called on the + * corresponding dToken of the asset type. + * @return The dToken address, it's name, and the name of the called function. + */ + function _getDharmaTokenDetails( + AssetType asset, + bytes4 functionSelector + ) internal pure returns ( + address account, + string memory name, + string memory functionName + ) { + if (asset == AssetType.DAI) { + account = address(_DDAI); + name = "Dharma Dai"; + } else { + account = address(_DUSDC); + name = "Dharma USD Coin"; + } + + // Note: since both dTokens have the same interface, just use dDai's. + if (functionSelector == _DDAI.mint.selector) { + functionName = "mint"; + } else { + functionName = string(abi.encodePacked( + "redeem", + functionSelector == _DDAI.redeemUnderlying.selector ? "Underlying" : "" + )); + } + } + + /** + * @notice Internal view function to ensure that a given `to` address provided + * as part of a generic action is valid. Calls cannot be performed to accounts + * without code or back into the smart wallet itself. Additionally, generic + * calls cannot supply the address of the Dharma Escape Hatch registry - the + * specific, designated functions must be used in order to make calls into it. + * @param to address The address that will be targeted by the generic call. + */ + function _ensureValidGenericCallTarget(address to) internal view { + require( + to.isContract(), + "Invalid `to` parameter - must supply a contract address containing code." + ); + + require( + to != address(this), + "Invalid `to` parameter - cannot supply the address of this contract." + ); + + require( + to != address(_ESCAPE_HATCH_REGISTRY), + "Invalid `to` parameter - cannot supply the Dharma Escape Hatch Registry." + ); + } + + /** + * @notice Internal pure function to ensure that a given action type is a + * "custom" action type (i.e. is not a generic action type) and to construct + * the "arguments" input to an actionID based on that action type. + * @param action uint8 The type of action, designated by it's index. Valid + * custom actions in V6 include Cancel (0), SetUserSigningKey (1), + * DAIWithdrawal (10), USDCWithdrawal (5), ETHWithdrawal (6), + * SetEscapeHatch (7), RemoveEscapeHatch (8), and DisableEscapeHatch (9). + * @param amount uint256 The amount to withdraw for Withdrawal actions. This + * value is ignored for all non-withdrawal action types. + * @param recipient address The account to transfer withdrawn funds to or the + * new user signing key. This value is ignored for Cancel, RemoveEscapeHatch, + * and DisableEscapeHatch action types. + * @return A bytes array containing the arguments that will be provided as + * a component of the inputs when constructing a custom action ID. + */ + function _validateCustomActionTypeAndGetArguments( + ActionType action, uint256 amount, address recipient + ) internal pure returns (bytes memory arguments) { + // Ensure that the action type is a valid custom action type. + require( + action == ActionType.Cancel || + action == ActionType.SetUserSigningKey || + action == ActionType.DAIWithdrawal || + action == ActionType.USDCWithdrawal || + action == ActionType.ETHWithdrawal || + action == ActionType.SetEscapeHatch || + action == ActionType.RemoveEscapeHatch || + action == ActionType.DisableEscapeHatch, + "Invalid custom action type." + ); + + // Use action type to determine parameters to include in returned arguments. + if ( + action == ActionType.Cancel || + action == ActionType.RemoveEscapeHatch || + action == ActionType.DisableEscapeHatch + ) { + // Ignore parameters for Cancel, RemoveEscapeHatch, or DisableEscapeHatch. + arguments = abi.encode(); + } else if ( + action == ActionType.SetUserSigningKey || + action == ActionType.SetEscapeHatch + ) { + // Ignore `amount` parameter for other, non-withdrawal actions. + arguments = abi.encode(recipient); + } else { + // Use both `amount` and `recipient` parameters for withdrawals. + arguments = abi.encode(amount, recipient); + } + } + + /** + * @notice Internal pure function to decode revert reasons. The revert reason + * prefix is removed and the remaining string argument is decoded. + * @param revertData bytes The raw data supplied alongside the revert. + * @return The decoded revert reason string. + */ + function _decodeRevertReason( + bytes memory revertData + ) internal pure returns (string memory revertReason) { + // Solidity prefixes revert reason with 0x08c379a0 -> Error(string) selector + if ( + revertData.length > 68 && // prefix (4) + position (32) + length (32) + revertData[0] == byte(0x08) && + revertData[1] == byte(0xc3) && + revertData[2] == byte(0x79) && + revertData[3] == byte(0xa0) + ) { + // Get the revert reason without the prefix from the revert data. + bytes memory revertReasonBytes = new bytes(revertData.length - 4); + for (uint256 i = 4; i < revertData.length; i++) { + revertReasonBytes[i - 4] = revertData[i]; + } + + // Decode the resultant revert reason as a string. + revertReason = abi.decode(revertReasonBytes, (string)); + } else { + // Simply return the default, with no revert reason. + revertReason = "(no revert reason)"; + } + } +} \ No newline at end of file diff --git a/contracts/multisigs/DharmaSpreadRegistryMultisig.sol b/contracts/multisigs/DharmaSpreadRegistryMultisig.sol deleted file mode 100644 index 288b1be..0000000 --- a/contracts/multisigs/DharmaSpreadRegistryMultisig.sol +++ /dev/null @@ -1,4 +0,0 @@ -pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg - - -contract DharmaSpreadRegistryMultisig {} \ No newline at end of file diff --git a/contracts/multisigs/DharmaVaultMultisig.sol b/contracts/multisigs/DharmaVaultMultisig.sol deleted file mode 100644 index 89fdd1e..0000000 --- a/contracts/multisigs/DharmaVaultMultisig.sol +++ /dev/null @@ -1,4 +0,0 @@ -pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg - - -contract DharmaVaultMultisig {} \ No newline at end of file diff --git a/contracts/proxies/token/DharmaDai.sol b/contracts/proxies/token/DharmaDai.sol index df5fe73..b9c4a9d 100644 --- a/contracts/proxies/token/DharmaDai.sol +++ b/contracts/proxies/token/DharmaDai.sol @@ -1,4 +1,54 @@ pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg -contract DharmaDai {} \ No newline at end of file +/** + * @title DharmaDai + * @author 0ages + * @notice Dharma Dai delegates all logic to an implementation contract + * specified by a hard-coded "upgrade beacon" contract. + */ +contract DharmaDai { + // Set upgrade beacon address as a constant (i.e. not in contract storage). + address private constant _UPGRADE_BEACON = address( + 0x0000000000ccCf289727C20269911159a7bf9eBd + ); + + /** + * @notice In the fallback, delegate execution to the implementation set on + * the upgrade beacon. + */ + function () external payable { + // Get the current implementation address from the upgrade beacon. + (bool ok, bytes memory returnData) = _UPGRADE_BEACON.staticcall(""); + + // Revert and pass along revert message if call to upgrade beacon reverts. + if (!ok) { + assembly { + returndatacopy(0, 0, returndatasize) + revert(0, returndatasize) + } + } + + // Put implementation address returned from the upgrade beacon on the stack. + address implementation = abi.decode(returnData, (address)); + + assembly { + // Copy msg.data. We take full control of memory in this inline assembly + // block because it will not return to Solidity code. We overwrite the + // Solidity scratch pad at memory position 0. + calldatacopy(0, 0, calldatasize) + + // Delegatecall to the implementation, supplying calldata and gas. + // Out and outsize are set to zero - instead, use the return buffer. + let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0) + + // Copy the returned data from the return buffer. + returndatacopy(0, 0, returndatasize) + + switch result + // Delegatecall returns 0 on error. + case 0 { revert(0, returndatasize) } + default { return(0, returndatasize) } + } + } +} \ No newline at end of file diff --git a/contracts/proxies/token/DharmaUSDC.sol b/contracts/proxies/token/DharmaUSDC.sol index 2beded1..b0b2d71 100644 --- a/contracts/proxies/token/DharmaUSDC.sol +++ b/contracts/proxies/token/DharmaUSDC.sol @@ -1,4 +1,54 @@ pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg -contract DharmaUSDC {} \ No newline at end of file +/** + * @title DharmaUSDC + * @author 0ages + * @notice Dharma USDC delegates all logic to an implementation contract + * specified by a hard-coded "upgrade beacon" contract. + */ +contract DharmaUSDC { + // Set upgrade beacon address as a constant (i.e. not in contract storage). + address private constant _UPGRADE_BEACON = address( + 0x00000000000274bE4365Aa18CfDC9A22A947f67D + ); + + /** + * @notice In the fallback, delegate execution to the implementation set on + * the upgrade beacon. + */ + function () external payable { + // Get the current implementation address from the upgrade beacon. + (bool ok, bytes memory returnData) = _UPGRADE_BEACON.staticcall(""); + + // Revert and pass along revert message if call to upgrade beacon reverts. + if (!ok) { + assembly { + returndatacopy(0, 0, returndatasize) + revert(0, returndatasize) + } + } + + // Put implementation address returned from the upgrade beacon on the stack. + address implementation = abi.decode(returnData, (address)); + + assembly { + // Copy msg.data. We take full control of memory in this inline assembly + // block because it will not return to Solidity code. We overwrite the + // Solidity scratch pad at memory position 0. + calldatacopy(0, 0, calldatasize) + + // Delegatecall to the implementation, supplying calldata and gas. + // Out and outsize are set to zero - instead, use the return buffer. + let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0) + + // Copy the returned data from the return buffer. + returndatacopy(0, 0, returndatasize) + + switch result + // Delegatecall returns 0 on error. + case 0 { revert(0, returndatasize) } + default { return(0, returndatasize) } + } + } +} \ No newline at end of file diff --git a/contracts/registries/DharmaSpreadRegistryV1.sol b/contracts/registries/DharmaSpreadRegistryV1.sol deleted file mode 100644 index b1c1055..0000000 --- a/contracts/registries/DharmaSpreadRegistryV1.sol +++ /dev/null @@ -1,4 +0,0 @@ -pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg - - -contract DharmaSpreadRegistryV1 {} \ No newline at end of file diff --git a/contracts/upgradeability/token/DharmaDaiUpgradeBeacon.sol b/contracts/upgradeability/token/DharmaDaiUpgradeBeacon.sol index 659e336..75f7337 100644 --- a/contracts/upgradeability/token/DharmaDaiUpgradeBeacon.sol +++ b/contracts/upgradeability/token/DharmaDaiUpgradeBeacon.sol @@ -1,4 +1,38 @@ pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg -contract DharmaDaiUpgradeBeacon {} \ No newline at end of file +/** + * @title DharmaDaiUpgradeBeacon + * @author 0age + * @notice This contract holds the address of the current implementation for + * Dharma Dai and lets a controller update that address in storage. + */ +contract DharmaDaiUpgradeBeacon { + // The implementation address is held in storage slot zero. + address private _implementation; + + // The controller that can update the implementation is set as a constant. + address private constant _CONTROLLER = address( + 0x00000000001E980d286bE7f5f978f4Cc33128202 + ); + + /** + * @notice In the fallback function, allow only the controller to update the + * implementation address - for all other callers, return the current address. + * Note that this requires inline assembly, as Solidity fallback functions do + * not natively take arguments or return values. + */ + function () external { + // Return implementation address for all callers other than the controller. + if (msg.sender != _CONTROLLER) { + // Load implementation from storage slot zero into memory and return it. + assembly { + mstore(0, sload(0)) + return(0, 32) + } + } else { + // Set implementation - put first word in calldata in storage slot zero. + assembly { sstore(0, calldataload(0)) } + } + } +} \ No newline at end of file diff --git a/contracts/upgradeability/token/DharmaUSDCUpgradeBeacon.sol b/contracts/upgradeability/token/DharmaUSDCUpgradeBeacon.sol index f6cccf1..692da40 100644 --- a/contracts/upgradeability/token/DharmaUSDCUpgradeBeacon.sol +++ b/contracts/upgradeability/token/DharmaUSDCUpgradeBeacon.sol @@ -1,4 +1,38 @@ pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg -contract DharmaUSDCUpgradeBeacon {} \ No newline at end of file +/** + * @title DharmaUSDCUpgradeBeacon + * @author 0age + * @notice This contract holds the address of the current implementation for + * Dharma USD Coin and lets a controller update that address in storage. + */ +contract DharmaUSDCUpgradeBeacon { + // The implementation address is held in storage slot zero. + address private _implementation; + + // The controller that can update the implementation is set as a constant. + address private constant _CONTROLLER = address( + 0x0000000000796dC3aA12EB9FE3B6e8F4D92cc966 + ); + + /** + * @notice In the fallback function, allow only the controller to update the + * implementation address - for all other callers, return the current address. + * Note that this requires inline assembly, as Solidity fallback functions do + * not natively take arguments or return values. + */ + function () external { + // Return implementation address for all callers other than the controller. + if (msg.sender != _CONTROLLER) { + // Load implementation from storage slot zero into memory and return it. + assembly { + mstore(0, sload(0)) + return(0, 32) + } + } else { + // Set implementation - put first word in calldata in storage slot zero. + assembly { sstore(0, calldataload(0)) } + } + } +} \ No newline at end of file diff --git a/contracts/vaults/DharmaVaultV1.sol b/contracts/vaults/DharmaVaultV1.sol deleted file mode 100644 index fc38152..0000000 --- a/contracts/vaults/DharmaVaultV1.sol +++ /dev/null @@ -1,4 +0,0 @@ -pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg - - -contract DharmaVaultV1 {} \ No newline at end of file diff --git a/contracts/helpers/FactoryFactFinder.sol b/extra-contracts/helpers/FactoryFactFinder.sol similarity index 100% rename from contracts/helpers/FactoryFactFinder.sol rename to extra-contracts/helpers/FactoryFactFinder.sol diff --git a/contracts/helpers/SmartWalletFactoryV1UserSigningKeyUpdater.sol b/extra-contracts/helpers/SmartWalletFactoryV1UserSigningKeyUpdater.sol similarity index 100% rename from contracts/helpers/SmartWalletFactoryV1UserSigningKeyUpdater.sol rename to extra-contracts/helpers/SmartWalletFactoryV1UserSigningKeyUpdater.sol diff --git a/interfaces/CTokenInterface.sol b/interfaces/CTokenInterface.sol index ec9d9f6..b74babd 100644 --- a/interfaces/CTokenInterface.sol +++ b/interfaces/CTokenInterface.sol @@ -8,21 +8,23 @@ interface CTokenInterface { function redeemUnderlying(uint256 redeemAmount) external returns (uint256 err); - function balanceOf(address account) external returns (uint256 balance); + function balanceOf(address account) external view returns (uint256 balance); function balanceOfUnderlying(address account) external returns (uint256 balance); - function borrow(uint256 borrowAmount) external returns (uint256 err); + function exchangeRateCurrent() external returns (uint256 exchangeRate); - function repayBorrow(uint256 borrowAmount) external returns (uint256 err); + function transfer(address recipient, uint256 value) external returns (bool); - // NOTE: we could use borrowBalanceStored if interest has already been accrued - function borrowBalanceCurrent(address account) external returns (uint256 err); + function transferFrom(address sender, address recipient, uint256 value) external returns (bool); - function getAccountSnapshot(address account) external view returns ( - uint256 err, - uint256 cTokenBalance, - uint256 borrowBalance, - uint256 exchangeRateMantissa - ); // balanceOfUnderlying = (cTokenBalance * exchangeRateMantissa) / 1e18 + function approve(address spender, uint256 amount) external returns (bool); + + function allowance(address owner, address spender) external view returns (uint256); + + function supplyRatePerBlock() external view returns (uint256 rate); + + function exchangeRateStored() external view returns (uint256 rate); + + function accrualBlockNumber() external view returns (uint256 blockNumber); } \ No newline at end of file diff --git a/interfaces/DTokenInterface.sol b/interfaces/DTokenInterface.sol new file mode 100644 index 0000000..8e9ddc8 --- /dev/null +++ b/interfaces/DTokenInterface.sol @@ -0,0 +1,36 @@ +pragma solidity 0.5.11; + +/** + * @title DTokenInterface + * @author 0age + * @notice Interface for dTokens. + */ +interface DTokenInterface { + // Events (similar to Compound's events) + event Mint(address minter, uint256 mintAmount, uint256 mintDTokens); + event Redeem(address redeemer, uint256 redeemAmount, uint256 redeemDTokens); + event Accrue(uint256 dTokenExchangeRate, uint256 cTokenExchangeRate); + event CollectSurplus(uint256 surplusAmount, uint256 surplusCTokens); + + // external functions (trigger accrual) + function mint(uint256 underlyingToSupply) external returns (uint256 dTokensMinted); + function mintViaCToken(uint256 cTokensToSupply) external returns (uint256 dTokensMinted); + function redeem(uint256 dTokensToBurn) external returns (uint256 underlyingReceived); + function redeemToCToken(uint256 dTokensToBurn) external returns (uint256 cTokensReceived); + function redeemUnderlying(uint256 underelyingToReceive) external returns (uint256 dTokensBurned); + function redeemUnderlyingToCToken(uint256 underlyingToReceive) external returns (uint256 dTokensBurned); + function transferUnderlying(address recipient, uint256 amount) external returns (bool); + function transferUnderlyingFrom(address sender, address recipient, uint256 amount) external returns (bool); + function pullSurplus() external returns (uint256 cTokenSurplus); + function accrueInterest() external; + + // view functions (do not trigger accrual) + function totalSupplyUnderlying() external view returns (uint256); + function balanceOfUnderlying(address account) external view returns (uint256 underlyingBalance); + function getSurplus() external view returns (uint256 cTokenSurplus); + function getSurplusUnderlying() external view returns (uint256 underlyingSurplus); + function exchangeRateCurrent() external view returns (uint256 dTokenExchangeRate); + function supplyRatePerBlock() external view returns (uint256 dTokenInterestRate); + function getSpreadPerBlock() external view returns (uint256 rateSpread); + function getVersion() external pure returns (uint256 version); +} \ No newline at end of file diff --git a/interfaces/DharmaSmartWalletImplementationV7Interface.sol b/interfaces/DharmaSmartWalletImplementationV7Interface.sol new file mode 100644 index 0000000..d3206ae --- /dev/null +++ b/interfaces/DharmaSmartWalletImplementationV7Interface.sol @@ -0,0 +1,9 @@ +pragma solidity 0.5.11; + + +interface DharmaSmartWalletImplementationV7Interface { + function migrateSaiToDai() external; + function migrateCSaiToDDai() external; + function migrateCDaiToDDai() external; + function migrateCUSDCToDUSDC() external; +} \ No newline at end of file diff --git a/scripts/test/constants.js b/scripts/test/constants.js index 03d8364..c786ba1 100644 --- a/scripts/test/constants.js +++ b/scripts/test/constants.js @@ -171,14 +171,23 @@ module.exports = Object.freeze({ KEY_RING_UPGRADE_BEACON_CONTROLLER_METADATA: ( ['20446861726d614b657952696e67426561636f6e436f6e74726f6c6c65722020'] ), - KEY_RING_UPGRADE_BEACON_ADDRESS: ( - '0x0000000000BDA2152794ac8c76B2dc86cbA57cad' + DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_ADDRESS: ( + '0x00000000001E980d286bE7f5f978f4Cc33128202' ), - KEY_RING_UPGRADE_BEACON_SALT: ( - '0x0000000000000000000000000000000000000000ca2bc7ce5bd506089c100000' + DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_SALT : ( + '0x00000000000000000000000000000000000000003fcbb8f03bf3de073e010000' ), - KEY_RING_UPGRADE_BEACON_METADATA: ( - ['202020446861726d614b657952696e6755706772616465426561636f6e202020'] + DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA : ( + ['446861726d6144616955706772616465426561636f6e436f6e74726f6c6c6572'] + ), + DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_ADDRESS: ( + '0x0000000000796dC3aA12EB9FE3B6e8F4D92cc966' + ), + DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_SALT : ( + '0x00000000000000000000000000000000000000000fc2eed291fd750bd0020000' + ), + DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA : ( + ['446861726d615553444355706772616465426561636f6e436f6e74726f6c6c72'] ), UPGRADE_BEACON_ADDRESS: ( '0x000000000026750c571ce882B17016557279ADaa' @@ -189,6 +198,51 @@ module.exports = Object.freeze({ UPGRADE_BEACON_METADATA: ( ['202020202020446861726d6155706772616465426561636f6e20202020202020'] ), + KEY_RING_UPGRADE_BEACON_ADDRESS: ( + '0x0000000000BDA2152794ac8c76B2dc86cbA57cad' + ), + KEY_RING_UPGRADE_BEACON_SALT: ( + '0x0000000000000000000000000000000000000000ca2bc7ce5bd506089c100000' + ), + KEY_RING_UPGRADE_BEACON_METADATA: ( + ['202020446861726d614b657952696e6755706772616465426561636f6e202020'] + ), + DHARMA_DAI_UPGRADE_BEACON_ADDRESS: ( + '0x0000000000ccCf289727C20269911159a7bf9eBd' + ), + DHARMA_DAI_UPGRADE_BEACON_SALT: ( + '0x000000000000000000000000000000000000000030229e8953db57001f000000' + ), + DHARMA_DAI_UPGRADE_BEACON_METADATA : ( + ['2020202020446861726d6144616955706772616465426561636f6e2020202020'] + ), + DHARMA_USDC_UPGRADE_BEACON_ADDRESS: ( + '0x00000000000274bE4365Aa18CfDC9A22A947f67D' + ), + DHARMA_USDC_UPGRADE_BEACON_SALT: ( + '0x00000000000000000000000000000000000000004961b57384658b027f080000' + ), + DHARMA_USDC_UPGRADE_BEACON_METADATA : ( + ['20202020446861726d615553444355706772616465426561636f6e2020202020'] + ), + DHARMA_DAI_ADDRESS: ( + '0x00000000001876eB1444c986fD502e618c587430' + ), + DHARMA_DAI_SALT: ( + '0x00000000000000000000000000000000000000004ed68ad580a29b000c0a0000' + ), + DHARMA_DAI_METADATA : ( + ['20202020202020446861726d6120446169202864446169292020202020202020'] + ), + DHARMA_USDC_ADDRESS: ( + '0x0000000000946A7848C50C8f0AE1BB2792602Cb7' + ), + DHARMA_USDC_SALT: ( + '0x00000000000000000000000000000000000000001cde6de5d233ca09540d0000' + ), + DHARMA_USDC_METADATA : ( + ['20202020446861726d612055534420436f696e20286455534443292020202020'] + ), KEY_REGISTRY_ADDRESS: ( '0x000000005D7065eB9716a410070Ee62d51092C98' ), @@ -372,7 +426,9 @@ module.exports = Object.freeze({ '0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643': 'CDAI', '0x39AA39c021dfbaE8faC545936693aC917d5E7563': 'CUSDC', '0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5': 'CETH', - '0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B': 'Comptroller' + '0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B': 'Comptroller', + '0x00000000001876eB1444c986fD502e618c587430': 'DDAI', + '0x0000000000946A7848C50C8f0AE1BB2792602Cb7': 'DUSDC' }, EVENT_DETAILS: { // keccak256 of NewUserSigningKey(address) -> userSigningKey diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index dc4b26c..305840f 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -7,6 +7,8 @@ let DharmaUpgradeBeaconArtifact; let DharmaUpgradeBeaconControllerArtifact; let DharmaUpgradeBeaconEnvoyArtifact; let DharmaKeyRingUpgradeBeaconArtifact; +let DharmaDaiUpgradeBeaconArtifact; +let DharmaUSDCUpgradeBeaconArtifact; let DharmaKeyRegistryV1Artifact; let DharmaKeyRegistryV2Artifact; let DharmaAccountRecoveryManagerV2Artifact; @@ -17,6 +19,8 @@ let AdharmaKeyRingImplementationArtifact; let DharmaUpgradeBeaconControllerManagerArtifact; let DharmaKeyRingFactoryV2Artifact; let DharmaEscapeHatchRegistryArtifact; +let DharmaDaiArtifact; +let DharmaUSDCArtifact; const DharmaUpgradeMultisigArtifact = require('../../build/contracts/DharmaUpgradeMultisig.json') const DharmaAccountRecoveryMultisigArtifact = require('../../build/contracts/DharmaAccountRecoveryMultisig.json') @@ -84,6 +88,8 @@ module.exports = {test: async function (provider, testingContext) { DharmaUpgradeBeaconControllerArtifact = require('../../../build/contracts/DharmaUpgradeBeaconController.json') DharmaUpgradeBeaconArtifact = require('../../../build/contracts/DharmaUpgradeBeacon.json') DharmaKeyRingUpgradeBeaconArtifact = require('../../../build/contracts/DharmaKeyRingUpgradeBeacon.json') + DharmaDaiUpgradeBeaconArtifact = require('../../../build/contracts/DharmaDaiUpgradeBeacon.json') + DharmaUSDCUpgradeBeaconArtifact = require('../../../build/contracts/DharmaUSDCUpgradeBeacon.json') DharmaKeyRegistryV1Artifact = require('../../../build/contracts/DharmaKeyRegistryV1.json') DharmaKeyRegistryV2Artifact = require('../../../build/contracts/DharmaKeyRegistryV2.json') DharmaSmartWalletFactoryV1Artifact = require('../../../build/contracts/DharmaSmartWalletFactoryV1.json') @@ -94,11 +100,15 @@ module.exports = {test: async function (provider, testingContext) { AdharmaKeyRingImplementationArtifact = require('../../../build/contracts/AdharmaKeyRingImplementation.json') DharmaUpgradeBeaconControllerManagerArtifact = require('../../../build/contracts/DharmaUpgradeBeaconControllerManager.json') DharmaEscapeHatchRegistryArtifact = require('../../../build/contracts/DharmaEscapeHatchRegistry.json') + DharmaDaiArtifact = require('../../../build/contracts/DharmaDai.json') + DharmaUSDCArtifact = require('../../../build/contracts/DharmaUSDC.json') } else { DharmaUpgradeBeaconEnvoyArtifact = require('../../build/contracts/DharmaUpgradeBeaconEnvoy.json') DharmaUpgradeBeaconControllerArtifact = require('../../build/contracts/DharmaUpgradeBeaconController.json') DharmaUpgradeBeaconArtifact = require('../../build/contracts/DharmaUpgradeBeacon.json') DharmaKeyRingUpgradeBeaconArtifact = require('../../build/contracts/DharmaKeyRingUpgradeBeacon.json') + DharmaDaiUpgradeBeaconArtifact = require('../../build/contracts/DharmaDaiUpgradeBeacon.json') + DharmaUSDCUpgradeBeaconArtifact = require('../../build/contracts/DharmaUSDCUpgradeBeacon.json') DharmaKeyRegistryV1Artifact = require('../../build/contracts/DharmaKeyRegistryV1.json') DharmaKeyRegistryV2Artifact = require('../../build/contracts/DharmaKeyRegistryV2.json') DharmaSmartWalletFactoryV1Artifact = require('../../build/contracts/DharmaSmartWalletFactoryV1.json') @@ -109,6 +119,8 @@ module.exports = {test: async function (provider, testingContext) { AdharmaKeyRingImplementationArtifact = require('../../build/contracts/AdharmaKeyRingImplementation.json') DharmaUpgradeBeaconControllerManagerArtifact = require('../../build/contracts/DharmaUpgradeBeaconControllerManager.json') DharmaEscapeHatchRegistryArtifact = require('../../build/contracts/DharmaEscapeHatchRegistry.json') + DharmaDaiArtifact = require('../../build/contracts/DharmaDai.json') + DharmaUSDCArtifact = require('../../build/contracts/DharmaUSDC.json') } var web3 = provider @@ -120,12 +132,12 @@ module.exports = {test: async function (provider, testingContext) { /* console.log( swapMetadataHash( - DharmaSmartWalletImplementationV5Artifact.bytecode, - constants.DHARMA_SMART_WALLET_IMPLEMENTATION_V5_METADATA + DharmaUSDCArtifact.bytecode, + constants.DHARMA_DAI_METADATA ), web3.utils.keccak256(swapMetadataHash( - DharmaSmartWalletImplementationV5Artifact.bytecode, - constants.DHARMA_SMART_WALLET_IMPLEMENTATION_V5_METADATA + DharmaUSDCArtifact.bytecode, + constants.DHARMA_DAI_METADATA ), {encoding: 'hex'}) ) process.exit(0) From 23fdd2050a71dc8ad0151d83c16446fb03d042f6 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Sat, 1 Feb 2020 22:30:12 -0500 Subject: [PATCH 03/47] include ERC-1271 interface on DSWv7 --- .../DharmaSmartWalletImplementationV7.sol | 106 +++++++++++++++--- contracts/proxies/token/DharmaDai.sol | 2 +- contracts/proxies/token/DharmaUSDC.sol | 2 +- ...maSmartWalletImplementationV0Interface.sol | 1 + 4 files changed, 91 insertions(+), 20 deletions(-) diff --git a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol index f6e6b44..446cf30 100644 --- a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol +++ b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol @@ -42,7 +42,8 @@ contract DharmaSmartWalletImplementationV7 is DharmaSmartWalletImplementationV1Interface, DharmaSmartWalletImplementationV3Interface, DharmaSmartWalletImplementationV4Interface, - DharmaSmartWalletImplementationV7Interface { + DharmaSmartWalletImplementationV7Interface, + ERC1271 { using Address for address; using ECDSA for bytes32; // WARNING: DO NOT REMOVE OR REORDER STORAGE WHEN WRITING NEW IMPLEMENTATIONS! @@ -85,19 +86,7 @@ contract DharmaSmartWalletImplementationV7 is DharmaEscapeHatchRegistryInterface(0x00000000005280B515004B998a944630B6C663f8) ); - // Interface with Sai, Dai, USDC, related CompoundV2 contracts, and migrator. - CTokenInterface internal constant _CSAI = CTokenInterface( - 0xF5DCe57282A584D2746FaF1593d3121Fcac444dC // mainnet - ); - - CTokenInterface internal constant _CDAI = CTokenInterface( - 0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643 // mainnet - ); - - CTokenInterface internal constant _CUSDC = CTokenInterface( - 0x39AA39c021dfbaE8faC545936693aC917d5E7563 // mainnet - ); - + // Interface with dDai, dUSDC, Dai, USDC, Sai, cSai, cDai, cUSDC, & migrator. DTokenInterface internal constant _DDAI = DTokenInterface( 0x00000000001876eB1444c986fD502e618c587430 // mainnet ); @@ -106,10 +95,6 @@ contract DharmaSmartWalletImplementationV7 is 0x0000000000946A7848C50C8f0AE1BB2792602Cb7 // mainnet ); - IERC20 internal constant _SAI = IERC20( - 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359 // mainnet - ); - IERC20 internal constant _DAI = IERC20( 0x6B175474E89094C44Da98b954EedeAC495271d0F // mainnet ); @@ -118,6 +103,22 @@ contract DharmaSmartWalletImplementationV7 is 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 // mainnet ); + IERC20 internal constant _SAI = IERC20( + 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359 // mainnet + ); + + CTokenInterface internal constant _CSAI = CTokenInterface( + 0xF5DCe57282A584D2746FaF1593d3121Fcac444dC // mainnet + ); + + CTokenInterface internal constant _CDAI = CTokenInterface( + 0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643 // mainnet + ); + + CTokenInterface internal constant _CUSDC = CTokenInterface( + 0x39AA39c021dfbaE8faC545936693aC917d5E7563 // mainnet + ); + SaiToDaiMigratorInterface internal constant _MIGRATOR = SaiToDaiMigratorInterface( 0xc73e0383F3Aff3215E6f04B0331D58CeCf0Ab849 // mainnet ); @@ -1101,6 +1102,75 @@ contract DharmaSmartWalletImplementationV7 is ); } + /** + * @notice View function that implements ERC-1271 and validates a set of + * signatures, one from the owner (using ERC-1271 as well if the user signing + * key is a contract) and one from the Dharma Key Registry against the + * supplied data. The data must be ABI encoded as (bytes32, bytes), where the + * first bytes32 parameter represents the hash digest for validating the + * supplied signatures and the second bytes parameter contains context for the + * requested validation. + * @param data bytes The data used to validate the signature. + * @param signatures bytes The two signatures, each 65 bytes - one from the + * owner (using ERC-1271 as well if the user signing key is a contract) and + * one from the Dharma Key Registry. + * @return The 4-byte magic value to signify a valid signature in ERC-1271, if + * the signatures are both valid. + */ + function isValidSignature( + bytes calldata data, bytes calldata signatures + ) external view returns (bytes4 magicValue) { + // Get message hash digest and any additional context from data argument. + bytes32 digest; + bytes memory context; + if (data.length == 32) { + digest = abi.decode(data, (bytes32)); + } else { + (digest, context) = abi.decode(data, (bytes32, bytes)); + } + + // Get user signature & Dharma signature from combined signatures argument. + require(signatures.length == 130, "Must supply two 65-byte signatures."); + bytes memory signaturesInMemory = signatures; + bytes32 r; + bytes32 s; + uint8 v; + assembly { + r := mload(add(signaturesInMemory, 0x20)) + s := mload(add(signaturesInMemory, 0x40)) + v := byte(0, mload(add(signaturesInMemory, 0x60))) + } + bytes memory userSignature = abi.encodePacked(r, s, v); + + assembly { + r := mload(add(signaturesInMemory, 0x61)) + s := mload(add(signaturesInMemory, 0x81)) + v := byte(0, mload(add(signaturesInMemory, 0xa1))) + } + bytes memory dharmaSignature = abi.encodePacked(r, s, v); + + // Validate user signature with `SignatureVerification` as the action type. + require( + _validateUserSignature( + digest, + ActionType.SignatureVerification, + context, + _userSigningKey, + userSignature + ), + "Verification failed - invalid user signature." + ); + + // Recover Dharma signature against key returned from Dharma Key Registry. + require( + _getDharmaSigningKey() == digest.recover(dharmaSignature), + "Verification failed - invalid Dharma signature." + ); + + // Return the ERC-1271 magic value to indicate success. + magicValue = _ERC_1271_MAGIC_VALUE; + } + /** * @notice Pure function for getting the current Dharma Smart Wallet version. * @return The current Dharma Smart Wallet version. diff --git a/contracts/proxies/token/DharmaDai.sol b/contracts/proxies/token/DharmaDai.sol index b9c4a9d..0df9937 100644 --- a/contracts/proxies/token/DharmaDai.sol +++ b/contracts/proxies/token/DharmaDai.sol @@ -3,7 +3,7 @@ pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg /** * @title DharmaDai - * @author 0ages + * @author 0age * @notice Dharma Dai delegates all logic to an implementation contract * specified by a hard-coded "upgrade beacon" contract. */ diff --git a/contracts/proxies/token/DharmaUSDC.sol b/contracts/proxies/token/DharmaUSDC.sol index b0b2d71..363a51c 100644 --- a/contracts/proxies/token/DharmaUSDC.sol +++ b/contracts/proxies/token/DharmaUSDC.sol @@ -3,7 +3,7 @@ pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg /** * @title DharmaUSDC - * @author 0ages + * @author 0age * @notice Dharma USDC delegates all logic to an implementation contract * specified by a hard-coded "upgrade beacon" contract. */ diff --git a/interfaces/DharmaSmartWalletImplementationV0Interface.sol b/interfaces/DharmaSmartWalletImplementationV0Interface.sol index d8c24ee..f1814f6 100644 --- a/interfaces/DharmaSmartWalletImplementationV0Interface.sol +++ b/interfaces/DharmaSmartWalletImplementationV0Interface.sol @@ -29,6 +29,7 @@ interface DharmaSmartWalletImplementationV0Interface { RemoveEscapeHatch, DisableEscapeHatch, DAIWithdrawal, + SignatureVerification, DAIBorrow, USDCBorrow } From 4024a9a4a6710350bece8658aa3683b1d966033c Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Mon, 3 Feb 2020 22:59:30 -0500 Subject: [PATCH 04/47] begin dToken deployment --- .../token/DharmaDaiImplementationV0.sol | 4 - .../token/DharmaDaiImplementationV1.sol | 155 +++ .../DharmaDaiInitializationImplementation.sol | 4 - .../token/DharmaDaiInitializer.sol | 70 ++ .../token/DharmaTokenHelpers.sol | 237 ++++ .../token/DharmaTokenOverrides.sol | 36 + .../implementations/token/DharmaTokenV1.sol | 1022 +++++++++++++++++ .../token/DharmaUSDCImplementationV0.sol | 4 - .../token/DharmaUSDCImplementationV1.sol | 126 ++ ...DharmaUSDCInitializationImplementation.sol | 4 - .../token/DharmaUSDCInitializer.sol | 71 ++ contracts/proxies/token/DharmaDai.sol | 5 +- scripts/test/constants.js | 18 + scripts/test/deploy.js | 8 +- 14 files changed, 1742 insertions(+), 22 deletions(-) delete mode 100644 contracts/implementations/token/DharmaDaiImplementationV0.sol create mode 100644 contracts/implementations/token/DharmaDaiImplementationV1.sol delete mode 100644 contracts/implementations/token/DharmaDaiInitializationImplementation.sol create mode 100644 contracts/implementations/token/DharmaDaiInitializer.sol create mode 100644 contracts/implementations/token/DharmaTokenHelpers.sol create mode 100644 contracts/implementations/token/DharmaTokenOverrides.sol create mode 100644 contracts/implementations/token/DharmaTokenV1.sol delete mode 100644 contracts/implementations/token/DharmaUSDCImplementationV0.sol create mode 100644 contracts/implementations/token/DharmaUSDCImplementationV1.sol delete mode 100644 contracts/implementations/token/DharmaUSDCInitializationImplementation.sol create mode 100644 contracts/implementations/token/DharmaUSDCInitializer.sol diff --git a/contracts/implementations/token/DharmaDaiImplementationV0.sol b/contracts/implementations/token/DharmaDaiImplementationV0.sol deleted file mode 100644 index c655dfe..0000000 --- a/contracts/implementations/token/DharmaDaiImplementationV0.sol +++ /dev/null @@ -1,4 +0,0 @@ -pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg - - -contract DharmaDaiImplementationV0 {} \ No newline at end of file diff --git a/contracts/implementations/token/DharmaDaiImplementationV1.sol b/contracts/implementations/token/DharmaDaiImplementationV1.sol new file mode 100644 index 0000000..89b22b0 --- /dev/null +++ b/contracts/implementations/token/DharmaDaiImplementationV1.sol @@ -0,0 +1,155 @@ +pragma solidity 0.5.11; + +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "./DharmaTokenV1.sol"; +import "../../interfaces/CTokenInterface.sol"; +import "../../interfaces/ERC20Interface.sol"; +import "../../interfaces/CDaiInterestRateModelInterface.sol"; +import "../../interfaces/PotInterface.sol"; + + +/** + * @title DharmaDaiImplementationV1 + * @author 0age (dToken mechanics derived from Compound cTokens, ERC20 methods + * derived from Open Zeppelin's ERC20 contract) + * @notice Dharma Dai is an interest-bearing token, with cDai as the backing + * token and Dai as the underlying token. The dDai exchange rate will initially + * increase at 90% the rate of the cDai exchange rate. + */ +contract DharmaDaiImplementationV1 is DharmaTokenV1 { + string internal constant _NAME = "Dharma Dai"; + string internal constant _SYMBOL = "dDai"; + string internal constant _UNDERLYING_NAME = "Dai"; + string internal constant _CTOKEN_SYMBOL = "cDai"; + + CTokenInterface internal constant _CDAI = CTokenInterface( + 0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643 // mainnet + ); + + ERC20Interface internal constant _DAI = ERC20Interface( + 0x6B175474E89094C44Da98b954EedeAC495271d0F // mainnet + ); + + PotInterface internal constant _POT = PotInterface( + 0x197E90f9FAD81970bA7976f33CbD77088E5D7cf7 // mainnet + ); + + // Note: this is just an EOA for the initial prototype. + address internal constant _VAULT = 0x7e4A8391C728fEd9069B2962699AB416628B19Fa; + + /** + * @notice Internal view function to get the current cDai exchange rate and + * supply rate per block. + * @return The current cDai exchange rate, or amount of Dai that is redeemable + * for each cDai, and the cDai supply rate per block (with 18 decimal places + * added to each returned rate). + */ + function _getCurrentCTokenRates() internal view returns ( + uint256 exchangeRate, uint256 supplyRate + ) { + // Determine the number of blocks that have elapsed since last cDai accrual. + uint256 blockDelta = block.number.sub(_CDAI.accrualBlockNumber()); + + // Return stored values if accrual has already been performed this block. + if (blockDelta == 0) return ( + _CDAI.exchangeRateStored(), _CDAI.supplyRatePerBlock() + ); + + // Determine total "cash" held by cDai contract by calculating DSR interest. + uint256 cash = ( // solhint-disable-next-line not-rely-on-time + _rpow(_POT.dsr(), now.sub(_POT.rho()), 1e27).mul(_POT.chi()) / 1e27 // chi + ).mul(_POT.pie(address(_CDAI))) / 1e27; + + // Get the latest interest rate model from the cDai contract. + CDaiInterestRateModelInterface interestRateModel = ( + CDaiInterestRateModelInterface(_CDAI.interestRateModel()) + ); + + // Get the current stored total borrows, reserves, and reserve factor. + uint256 borrows = _CDAI.totalBorrows(); + uint256 reserves = _CDAI.totalReserves(); + uint256 reserveFactor = _CDAI.reserveFactorMantissa(); + + // Get accumulated borrow interest via interest rate model and block delta. + uint256 interest = interestRateModel.getBorrowRate( + cash, borrows, reserves + ).mul(blockDelta).mul(borrows) / _SCALING_FACTOR; + + // Update total borrows and reserves using calculated accumulated interest. + borrows = borrows.add(interest); + reserves = reserves.add(reserveFactor.mul(interest) / _SCALING_FACTOR); + + // Determine cDai exchange rate: (cash + borrows - reserves) / total supply + exchangeRate = ( + ((cash.add(borrows)).sub(reserves)).mul(_SCALING_FACTOR) + ).div(_CDAI.totalSupply()); + + // Get supply rate via interest rate model and calculated parameters. + supplyRate = interestRateModel.getSupplyRate( + cash, borrows, reserves, reserveFactor + ); + } + + function _getUnderlyingName() internal pure returns (string memory underlyingName) { + underlyingName = _UNDERLYING_NAME; + } + + function _getUnderlying() internal pure returns (address underlying) { + underlying = address(_DAI); + } + + function _getCTokenSymbol() internal pure returns (string memory cTokenSymbol) { + cTokenSymbol = _CTOKEN_SYMBOL; + } + + function _getCToken() internal pure returns (address cToken) { + cToken = address(_CDAI); + } + + function _getDTokenName() internal pure returns (string memory dTokenName) { + dTokenName = _NAME; + } + + function _getDTokenSymbol() internal pure returns (string memory dTokenSymbol) { + dTokenSymbol = _SYMBOL; + } + + function _getVault() internal pure returns (address vault) { + vault = _VAULT; + } + + /** + * @notice Internal pure function to emulate exponentiation performed by the + * Dai Savings Rate contract. + * @param x uint256 The number that will be raised to the given power. + * @param n uint256 The power to raise that number by. + * @param base uint256 The scaling factor that will be applied to n and z. + * @return The number raised to the given power. + */ + function _rpow( + uint256 x, uint256 n, uint256 base + ) internal pure returns (uint256 z) { + // solhint-disable-next-line no-inline-assembly + assembly { + switch x case 0 {switch n case 0 {z := base} default {z := 0}} + default { + switch mod(n, 2) case 0 { z := base } default { z := x } + let half := div(base, 2) // for rounding. + for { n := div(n, 2) } n { n := div(n, 2) } { + let xx := mul(x, x) + if iszero(eq(div(xx, x), x)) { revert(0, 0) } + let xxRound := add(xx, half) + if lt(xxRound, xx) { revert(0, 0) } + x := div(xxRound, base) + if mod(n, 2) { + let zx := mul(z, x) + if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0, 0) } + let zxRound := add(zx, half) + if lt(zxRound, zx) { revert(0, 0) } + z := div(zxRound, base) + } + } + } + } + } +} \ No newline at end of file diff --git a/contracts/implementations/token/DharmaDaiInitializationImplementation.sol b/contracts/implementations/token/DharmaDaiInitializationImplementation.sol deleted file mode 100644 index f865245..0000000 --- a/contracts/implementations/token/DharmaDaiInitializationImplementation.sol +++ /dev/null @@ -1,4 +0,0 @@ -pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg - - -contract DharmaDaiInitializationImplementation {} \ No newline at end of file diff --git a/contracts/implementations/token/DharmaDaiInitializer.sol b/contracts/implementations/token/DharmaDaiInitializer.sol new file mode 100644 index 0000000..00bf0bb --- /dev/null +++ b/contracts/implementations/token/DharmaDaiInitializer.sol @@ -0,0 +1,70 @@ +pragma solidity 0.5.11; + +import "../../interfaces/CTokenInterface.sol"; +import "../../interfaces/ERC20Interface.sol"; + + +/** + * @title DharmaDaiInitializer + * @author 0age + * @notice Initializer implementation for the Dharma Dai token. + */ +contract DharmaDaiInitializer { + event Accrue(uint256 dTokenExchangeRate, uint256 cTokenExchangeRate); + + // The block number and cToken + dToken exchange rates are updated on accrual. + struct AccrualIndex { + uint112 dTokenExchangeRate; + uint112 cTokenExchangeRate; + uint32 block; + } + + CTokenInterface internal constant _CDAI = CTokenInterface( + 0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643 // mainnet + ); + + ERC20Interface internal constant _DAI = ERC20Interface( + 0x6B175474E89094C44Da98b954EedeAC495271d0F // mainnet + ); + + uint256 internal constant _MAX_UINT_112 = 5192296858534827628530496329220095; + + // Set block number and dToken + cToken exchange rate in slot zero on accrual. + AccrualIndex private _accrualIndex; + + /** + * @notice Initialize Dharma Dai by approving cDai to transfer Dai on behalf + * of this contract and setting the initial dDai and cDai exchange rates in + * storage. + */ + function initialize() external { + // Approve cToken to transfer underlying for this contract in order to mint. + require( + _DAI.approve(address(_CDAI), uint256(-1)), "Initial cDai approval failed." + ); + + // Initial dToken exchange rate is 1-to-1 (dTokens have 8 decimals). + uint256 dTokenExchangeRate = 1e28; + + // Accrue cToken interest and retrieve the current cToken exchange rate. + uint256 cTokenExchangeRate = _CDAI.exchangeRateCurrent(); + + // Initialize accrual index with current block number and exchange rates. + AccrualIndex storage accrualIndex = _accrualIndex; + accrualIndex.dTokenExchangeRate = uint112(dTokenExchangeRate); + accrualIndex.cTokenExchangeRate = _safeUint112(cTokenExchangeRate); + accrualIndex.block = uint32(block.number); + emit Accrue(dTokenExchangeRate, cTokenExchangeRate); + } + + /** + * @notice Internal pure function to convert a uint256 to a uint112, reverting + * if the conversion would cause an overflow. + * @param input uint256 The unsigned integer to convert. + * @return The converted unsigned integer. + */ + function _safeUint112(uint256 input) internal pure returns (uint112 output) { + require(input <= _MAX_UINT_112, "Overflow on conversion to uint112."); + output = uint112(input); + } +} \ No newline at end of file diff --git a/contracts/implementations/token/DharmaTokenHelpers.sol b/contracts/implementations/token/DharmaTokenHelpers.sol new file mode 100644 index 0000000..0ca0345 --- /dev/null +++ b/contracts/implementations/token/DharmaTokenHelpers.sol @@ -0,0 +1,237 @@ +pragma solidity 0.5.11; + +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "../../interfaces/CTokenInterface.sol"; +import "./DharmaTokenOverrides.sol"; + + +/** + * @title DharmaTokenHelpers + * @author 0age + * @notice A collection of constants and internal pure functions used by Dharma + * Tokens. + */ +contract DharmaTokenHelpers is DharmaTokenOverrides { + using SafeMath for uint256; + + uint8 internal constant _DECIMALS = 8; // matches cToken decimals + uint256 internal constant _SCALING_FACTOR = 1e18; + uint256 internal constant _SCALING_FACTOR_MINUS_ONE = 999999999999999999; + uint256 internal constant _HALF_OF_SCALING_FACTOR = 5e17; + uint256 internal constant _COMPOUND_SUCCESS = 0; + uint256 internal constant _MAX_UINT_112 = 5192296858534827628530496329220095; + uint256 internal constant _MAX_UNMALLEABLE_S = ( + 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 + ); + + /** + * @notice Internal pure function to determine if a call to Compound succeeded + * and to revert, supplying the reason, if it failed. Failure can be caused by + * a call that reverts, or by a call that does not revert but returns a + * non-zero error code. + * @param functionSelector bytes4 The function selector that was called. + * @param ok bool A boolean representing whether the call returned or + * reverted. + * @param data bytes The data provided by the returned or reverted call. + */ + function _checkCompoundInteraction( + bytes4 functionSelector, bool ok, bytes memory data + ) internal pure { + CTokenInterface cToken; + if (ok) { + if ( + functionSelector == cToken.transfer.selector || + functionSelector == cToken.transferFrom.selector + ) { + require( + abi.decode(data, (bool)), string( + abi.encodePacked( + "Compound ", + _getCTokenSymbol(), + " contract returned false on calling ", + _getFunctionName(functionSelector), + "." + ) + ) + ); + } else { + uint256 compoundError = abi.decode(data, (uint256)); // throw on no data + if (compoundError != _COMPOUND_SUCCESS) { + revert( + string( + abi.encodePacked( + "Compound ", + _getCTokenSymbol(), + " contract returned error code ", + uint8((compoundError / 10) + 48), + uint8((compoundError % 10) + 48), + " on calling ", + _getFunctionName(functionSelector), + "." + ) + ) + ); + } + } + } else { + revert( + string( + abi.encodePacked( + "Compound ", + _getCTokenSymbol(), + " contract reverted while attempting to call ", + _getFunctionName(functionSelector), + ": ", + _decodeRevertReason(data) + ) + ) + ); + } + } + + /** + * @notice Internal pure function to get a Compound function name based on the + * selector. + * @param functionSelector bytes4 The function selector. + * @return The name of the function as a string. + */ + function _getFunctionName( + bytes4 functionSelector + ) internal pure returns (string memory functionName) { + CTokenInterface cToken; + if (functionSelector == cToken.mint.selector) { + functionName = "mint"; + } else if (functionSelector == cToken.redeem.selector) { + functionName = "redeem"; + } else if (functionSelector == cToken.redeemUnderlying.selector) { + functionName = "redeemUnderlying"; + } else if (functionSelector == cToken.transferFrom.selector) { + functionName = "transferFrom"; + } else if (functionSelector == cToken.transfer.selector) { + functionName = "transfer"; + } else if (functionSelector == cToken.accrueInterest.selector) { + functionName = "accrueInterest"; + } else { + functionName = "an unknown function"; + } + } + + /** + * @notice Internal pure function to decode revert reasons. The revert reason + * prefix is removed and the remaining string argument is decoded. + * @param revertData bytes The raw data supplied alongside the revert. + * @return The decoded revert reason string. + */ + function _decodeRevertReason( + bytes memory revertData + ) internal pure returns (string memory revertReason) { + // Solidity prefixes revert reason with 0x08c379a0 -> Error(string) selector + if ( + revertData.length > 68 && // prefix (4) + position (32) + length (32) + revertData[0] == byte(0x08) && + revertData[1] == byte(0xc3) && + revertData[2] == byte(0x79) && + revertData[3] == byte(0xa0) + ) { + // Get the revert reason without the prefix from the revert data. + bytes memory revertReasonBytes = new bytes(revertData.length - 4); + for (uint256 i = 4; i < revertData.length; i++) { + revertReasonBytes[i - 4] = revertData[i]; + } + + // Decode the resultant revert reason as a string. + revertReason = abi.decode(revertReasonBytes, (string)); + } else { + // Simply return the default, with no revert reason. + revertReason = "(no revert reason)"; + } + } + + /** + * @notice Internal pure function to construct a failure message string for + * the revert reason on transfers of underlying tokens that do not succeed. + * @return The failure message. + */ + function _getTransferFailureMessage() internal pure returns ( + string memory message + ) { + message = string( + abi.encodePacked(_getUnderlyingName(), " transfer failed.") + ); + } + + /** + * @notice Internal pure function to convert a uint256 to a uint112, reverting + * if the conversion would cause an overflow. + * @param input uint256 The unsigned integer to convert. + * @return The converted unsigned integer. + */ + function _safeUint112(uint256 input) internal pure returns (uint112 output) { + require(input <= _MAX_UINT_112, "Overflow on conversion to uint112."); + output = uint112(input); + } + + /** + * @notice Internal pure function to convert an underlying amount to a dToken + * or cToken amount using an exchange rate and fixed-point arithmetic. + * @param underlying uint256 The underlying amount to convert. + * @param exchangeRate uint256 The exchange rate (multiplied by 10^18). + * @param roundUp bool Whether the final amount should be rounded up - it will + * instead be truncated (rounded down) if this value is false. + * @return The cToken or dToken amount. + */ + function _fromUnderlying( + uint256 underlying, uint256 exchangeRate, bool roundUp + ) internal pure returns (uint256 amount) { + if (roundUp) { + amount = ( + (underlying.mul(_SCALING_FACTOR)).add(exchangeRate.sub(1)) + ).div(exchangeRate); + } else { + amount = (underlying.mul(_SCALING_FACTOR)).div(exchangeRate); + } + } + + /** + * @notice Internal pure function to convert a dToken or cToken amount to the + * underlying amount using an exchange rate and fixed-point arithmetic. + * @param amount uint256 The cToken or dToken amount to convert. + * @param exchangeRate uint256 The exchange rate (multiplied by 10^18). + * @param roundUp bool Whether the final amount should be rounded up - it will + * instead be truncated (rounded down) if this value is false. + * @return The underlying amount. + */ + function _toUnderlying( + uint256 amount, uint256 exchangeRate, bool roundUp + ) internal pure returns (uint256 underlying) { + if (roundUp) { + underlying = ( + (amount.mul(exchangeRate).add(_SCALING_FACTOR_MINUS_ONE) + ) / _SCALING_FACTOR); + } else { + underlying = amount.mul(exchangeRate) / _SCALING_FACTOR; + } + } + + /** + * @notice Internal pure function to convert an underlying amount to a dToken + * or cToken amount and back to the underlying, so as to properly capture + * rounding errors, by using an exchange rate and fixed-point arithmetic. + * @param underlying uint256 The underlying amount to convert. + * @param exchangeRate uint256 The exchange rate (multiplied by 10^18). + * @param roundUpOne bool Whether the intermediate dToken or cToken amount + * should be rounded up - it will instead be truncated (rounded down) if this + * value is false. + * @param roundUpTwo bool Whether the final underlying amount should be + * rounded up - it will instead be truncated (rounded down) if this value is + * false. + * @return The intermediate cToken or dToken amount and the final underlying + * amount. + */ + function _fromUnderlyingAndBack( + uint256 underlying, uint256 exchangeRate, bool roundUpOne, bool roundUpTwo + ) internal pure returns (uint256 amount, uint256 adjustedUnderlying) { + amount = _fromUnderlying(underlying, exchangeRate, roundUpOne); + adjustedUnderlying = _toUnderlying(amount, exchangeRate, roundUpTwo); + } +} \ No newline at end of file diff --git a/contracts/implementations/token/DharmaTokenOverrides.sol b/contracts/implementations/token/DharmaTokenOverrides.sol new file mode 100644 index 0000000..649f172 --- /dev/null +++ b/contracts/implementations/token/DharmaTokenOverrides.sol @@ -0,0 +1,36 @@ +pragma solidity 0.5.11; + + +/** + * @title DharmaTokenOverrides + * @author 0age + * @notice A collection of internal view and pure functions that should be + * overridden by the ultimate Dharma Token implementation. + */ +contract DharmaTokenOverrides { + /** + * @notice Internal view function to get the current cToken exchange rate and + * supply rate per block. This function is meant to be overridden by the + * dToken that inherits this contract. + * @return The current cToken exchange rate, or amount of underlying tokens + * that are redeemable for each cToken, and the cToken supply rate per block + * (with 18 decimal places added to each returned rate). + */ + function _getCurrentCTokenRates() internal view returns ( + uint256 exchangeRate, uint256 supplyRate + ); + + function _getUnderlyingName() internal pure returns (string memory underlyingName); + + function _getUnderlying() internal pure returns (address underlying); + + function _getCTokenSymbol() internal pure returns (string memory cTokenSymbol); + + function _getCToken() internal pure returns (address cToken); + + function _getDTokenName() internal pure returns (string memory dTokenName); + + function _getDTokenSymbol() internal pure returns (string memory dTokenSymbol); + + function _getVault() internal pure returns (address vault); +} \ No newline at end of file diff --git a/contracts/implementations/token/DharmaTokenV1.sol b/contracts/implementations/token/DharmaTokenV1.sol new file mode 100644 index 0000000..1aac546 --- /dev/null +++ b/contracts/implementations/token/DharmaTokenV1.sol @@ -0,0 +1,1022 @@ +pragma solidity 0.5.11; + +import "./DharmaTokenHelpers.sol"; +import "../../interfaces/CTokenInterface.sol"; +import "../../interfaces/DTokenInterface.sol"; +import "../../interfaces/ERC20Interface.sol"; +import "../../interfaces/ERC1271Interface.sol"; + + +/** + * @title DharmaTokenV1 + * @author 0age (dToken mechanics derived from Compound cTokens, ERC20 mechanics + * derived from Open Zeppelin's ERC20 contract) + * @notice A Dharma Token (or dToken) is an upgradeable ERC20 token with support + * for meta-transactions that earns interest with respect to a given stablecoin, + * and is backed by that stablecoin's respective Compound cToken. The V1 dToken + * exchange rate will grow at 90% the rate of the backing cToken exchange rate. + * This abstract contract contains functionality shared by each dToken - those + * implementations will then inherit this contract and override any relevant, + * unimplemented internal functions with implementation-specific ones. + */ +contract DharmaTokenV1 is ERC20Interface, DTokenInterface, DharmaTokenHelpers { + // Set the version of the Dharma Token as a constant. + uint256 private constant _DTOKEN_VERSION = 1; + + // Set block number and dToken + cToken exchange rate in slot zero on accrual. + AccrualIndex private _accrualIndex; + + // Slot one tracks the total issued dTokens. + uint256 private _totalSupply; + + // Slots two and three are entrypoints into balance and allowance mappings. + mapping (address => uint256) private _balances; + mapping (address => mapping (address => uint256)) private _allowances; + + // Slot four is an entrypoint into a mapping for used meta-transaction hashes. + mapping (bytes32 => bool) private _executedMetaTxs; + + /** + * @notice Transfer `underlyingToSupply` underlying tokens from `msg.sender` + * to this contract, use them to mint cTokens as backing, and mint dTokens to + * `msg.sender`. Ensure that this contract has been approved to transfer the + * underlying on behalf of the caller before calling this function. + * @param underlyingToSupply uint256 The amount of underlying to provide as + * part of minting. + * @return The amount of dTokens received in return for the supplied + * underlying tokens. + */ + function mint( + uint256 underlyingToSupply + ) external returns (uint256 dTokensMinted) { + // Instantiate interfaces for the underlying token and the backing cToken. + ERC20Interface underlying = ERC20Interface(_getUnderlying()); + CTokenInterface cToken = CTokenInterface(_getCToken()); + + // Pull in underlying - ensure that this contract has sufficient allowance. + require( + underlying.transferFrom(msg.sender, address(this), underlyingToSupply), + _getTransferFailureMessage() + ); + + // Use underlying to mint cTokens and ensure that the operation succeeds. + (bool ok, bytes memory data) = address(cToken).call(abi.encodeWithSelector( + cToken.mint.selector, underlyingToSupply + )); + _checkCompoundInteraction(cToken.mint.selector, ok, data); + + // Accrue after the Compound mint to avoid duplicating accrual calculations. + (uint256 dTokenExchangeRate, uint256 cTokenExchangeRate) = _accrue(false); + + // Get underlying equivalent of minted cTokens to prevent "dust" griefing. + (, uint256 underlyingEquivalent) = _fromUnderlyingAndBack( + underlyingToSupply, cTokenExchangeRate, false, false + ); + + // Determine dTokens to mint using underlying equivalent and exchange rate. + dTokensMinted = _fromUnderlying( + underlyingEquivalent, dTokenExchangeRate, false + ); + + // Mint dTokens to the caller. + _mint(msg.sender, underlyingToSupply, dTokensMinted); + } + + /** + * @notice Transfer `cTokensToSupply` cTokens from `msg.sender` to this + * contract and mint dTokens to `msg.sender`. Ensure that this contract has + * been approved to transfer the cTokens on behalf of the caller before + * calling this function. + * @param cTokensToSupply uint256 The amount of cTokens to provide as part of + * minting. + * @return The amount of dTokens received in return for the supplied cTokens. + */ + function mintViaCToken( + uint256 cTokensToSupply + ) external returns (uint256 dTokensMinted) { + // Instantiate the interface for the backing cToken. + CTokenInterface cToken = CTokenInterface(_getCToken()); + + // Pull in cTokens - ensure that this contract has sufficient allowance. + (bool ok, bytes memory data) = address(cToken).call(abi.encodeWithSelector( + cToken.transferFrom.selector, msg.sender, address(this), cTokensToSupply + )); + _checkCompoundInteraction(cToken.transferFrom.selector, ok, data); + + // Accrue interest and retrieve current cToken and dToken exchange rates. + (uint256 dTokenExchangeRate, uint256 cTokenExchangeRate) = _accrue(true); + + // Determine the underlying equivalent of the supplied cToken amount. + uint256 underlyingEquivalent = _toUnderlying( + cTokensToSupply, cTokenExchangeRate, false + ); + + // Determine dTokens to mint using underlying equivalent and exchange rate. + dTokensMinted = _fromUnderlying( + underlyingEquivalent, dTokenExchangeRate, false + ); + + // Mint dTokens to the caller. + _mint(msg.sender, underlyingEquivalent, dTokensMinted); + } + + /** + * @notice Redeem `dTokensToBurn` dTokens from `msg.sender`, use the + * corresponding cTokens to redeem the required underlying, and transfer the + * redeemed underlying tokens to `msg.sender`. + * @param dTokensToBurn uint256 The amount of dTokens to provide in exchange + * for underlying tokens. + * @return The amount of underlying received in return for the provided + * dTokens. + */ + function redeem( + uint256 dTokensToBurn + ) external returns (uint256 underlyingReceived) { + // Instantiate interfaces for the underlying token and the backing cToken. + ERC20Interface underlying = ERC20Interface(_getUnderlying()); + CTokenInterface cToken = CTokenInterface(_getCToken()); + + // Accrue interest and retrieve current dToken and cToken exchange rates. + (uint256 dTokenExchangeRate, uint256 cTokenExchangeRate) = _accrue(true); + + // Determine the equivalent underlying value of the dTokens to be burned. + uint256 underlyingEquivalent = _toUnderlying( + dTokensToBurn, dTokenExchangeRate, false + ); + + // Get minted cTokens and underlying equivalent to prevent "dust" griefing. + uint256 cTokenEquivalent; + (cTokenEquivalent, underlyingReceived) = _fromUnderlyingAndBack( + underlyingEquivalent, cTokenExchangeRate, false, false + ); + + // Burn the dTokens. + _burn(msg.sender, underlyingReceived, dTokensToBurn); + + // Use cTokens to redeem underlying and ensure that the operation succeeds. + (bool ok, bytes memory data) = address(cToken).call(abi.encodeWithSelector( + cToken.redeem.selector, cTokenEquivalent + )); + _checkCompoundInteraction(cToken.redeem.selector, ok, data); + + // Send the redeemed underlying tokens to the caller. + require( + underlying.transfer(msg.sender, underlyingReceived), + _getTransferFailureMessage() + ); + } + + /** + * @notice Redeem `dTokensToBurn` dTokens from `msg.sender` and transfer the + * corresponding amount of cTokens to `msg.sender`. + * @param dTokensToBurn uint256 The amount of dTokens to provide in exchange + * for the cTokens. + * @return The amount of cTokens received in return for the provided dTokens. + */ + function redeemToCToken( + uint256 dTokensToBurn + ) external returns (uint256 cTokensReceived) { + // Instantiate the interface for the backing cToken. + CTokenInterface cToken = CTokenInterface(_getCToken()); + + // Accrue interest and retrieve current cToken and dToken exchange rates. + (uint256 dTokenExchangeRate, uint256 cTokenExchangeRate) = _accrue(true); + + // Determine the underlying token value of the dTokens to be burned. + uint256 underlyingEquivalent = _toUnderlying( + dTokensToBurn, dTokenExchangeRate, false + ); + + // Determine amount of cTokens corresponding to underlying equivalent value. + cTokensReceived = _fromUnderlying( + underlyingEquivalent, cTokenExchangeRate, false + ); + + // Burn the dTokens. + _burn(msg.sender, underlyingEquivalent, dTokensToBurn); + + // Transfer cTokens to the caller and ensure that the operation succeeds. + (bool ok, bytes memory data) = address(cToken).call(abi.encodeWithSelector( + cToken.transfer.selector, msg.sender, cTokensReceived + )); + _checkCompoundInteraction(cToken.transfer.selector, ok, data); + } + + /** + * @notice Redeem the dToken equivalent value of the underlying token amount + * `underlyingToReceive` from `msg.sender`, use the corresponding cTokens to + * redeem the underlying, and transfer the underlying to `msg.sender`. + * @param underlyingToReceive uint256 The amount, denominated in the + * underlying token, of the cToken to redeem in exchange for the received + * underlying token. + * @return The amount of dTokens burned in exchange for the returned + * underlying tokens. + */ + function redeemUnderlying( + uint256 underlyingToReceive + ) external returns (uint256 dTokensBurned) { + // Instantiate interfaces for the underlying token and the backing cToken. + ERC20Interface underlying = ERC20Interface(_getUnderlying()); + CTokenInterface cToken = CTokenInterface(_getCToken()); + + // Use cTokens to redeem underlying and ensure that the operation succeeds. + (bool ok, bytes memory data) = address(cToken).call(abi.encodeWithSelector( + cToken.redeemUnderlying.selector, underlyingToReceive + )); + _checkCompoundInteraction(cToken.redeemUnderlying.selector, ok, data); + + // Accrue after the Compound redeem to avoid duplicating calculations. + (uint256 dTokenExchangeRate, uint256 cTokenExchangeRate) = _accrue(false); + + // Get underlying equivalent of redeemed cTokens to prevent "dust" griefing. + (, uint256 underlyingEquivalent) = _fromUnderlyingAndBack( + underlyingToReceive, cTokenExchangeRate, true, true // rounding up both + ); + + // Determine the dTokens to redeem using the exchange rate, rounding up. + dTokensBurned = _fromUnderlying( + underlyingEquivalent, dTokenExchangeRate, true + ); + + // Burn the dTokens. + _burn(msg.sender, underlyingToReceive, dTokensBurned); + + // Send the redeemed underlying tokens to the caller. + require( + underlying.transfer(msg.sender, underlyingToReceive), + _getTransferFailureMessage() + ); + } + + /** + * @notice Redeem the dToken equivalent value of the underlying tokens of + * amount `underlyingToReceive` from `msg.sender` and transfer the + * corresponding amount of cTokens to `msg.sender`. + * @param underlyingToReceive uint256 The amount, denominated in the + * underlying token, of cTokens to receive. + * @return The amount of dTokens burned in exchange for the returned cTokens. + */ + function redeemUnderlyingToCToken( + uint256 underlyingToReceive + ) external returns (uint256 dTokensBurned) { + // Instantiate the interface for the backing cToken. + CTokenInterface cToken = CTokenInterface(_getCToken()); + + // Accrue interest and retrieve current cToken and dToken exchange rates. + (uint256 dTokenExchangeRate, uint256 cTokenExchangeRate) = _accrue(true); + + // Get received cTokens and underlying equivalent (prevent "dust" griefing). + ( + uint256 cTokensToReceive, uint256 underlyingEquivalent + ) = _fromUnderlyingAndBack( + underlyingToReceive, cTokenExchangeRate, false, true // round down cTokens + ); + + // Determine redeemed dTokens using equivalent underlying value, rounded up. + dTokensBurned = _fromUnderlying( + underlyingEquivalent, dTokenExchangeRate, true + ); + + // Burn the dTokens. + _burn(msg.sender, underlyingToReceive, dTokensBurned); + + // Transfer cTokens to the caller and ensure that the operation succeeds. + (bool ok, bytes memory data) = address(cToken).call(abi.encodeWithSelector( + cToken.transfer.selector, msg.sender, cTokensToReceive + )); + _checkCompoundInteraction(cToken.transfer.selector, ok, data); + } + + /** + * @notice Transfer cTokens with underlying value in excess of the total + * underlying dToken value to a dedicated "vault" account. A "hard" accrual + * will first be performed, triggering an accrual on both the cToken and the + * dToken. + * @return The amount of cTokens transferred to the vault account. + */ + function pullSurplus() external returns (uint256 cTokenSurplus) { + // Instantiate the interface for the backing cToken. + CTokenInterface cToken = CTokenInterface(_getCToken()); + + // Accrue interest on the cToken and ensure that the operation succeeds. + (bool ok, bytes memory data) = address(cToken).call(abi.encodeWithSelector( + cToken.accrueInterest.selector + )); + _checkCompoundInteraction(cToken.accrueInterest.selector, ok, data); + + // Accrue interest on the dToken, reusing the stored cToken exchange rate. + _accrue(false); + + // Determine cToken surplus in underlying (cToken value - dToken value). + uint256 underlyingSurplus; + (underlyingSurplus, cTokenSurplus) = _getSurplus(); + + // Transfer cToken surplus to vault and ensure that the operation succeeds. + (ok, data) = address(cToken).call(abi.encodeWithSelector( + cToken.transfer.selector, _getVault(), cTokenSurplus + )); + _checkCompoundInteraction(cToken.transfer.selector, ok, data); + + emit CollectSurplus(underlyingSurplus, cTokenSurplus); + } + + /** + * @notice Manually advance the dToken exchange rate and cToken exchange rate + * to that of the current block. Note that dToken accrual does not trigger + * cToken accrual - instead, the updated exchange rate will be calculated + * internally. + */ + function accrueInterest() external { + // Accrue interest on the dToken. + _accrue(true); + } + + /** + * @notice Transfer `amount` dTokens from `msg.sender` to `recipient`. + * @param recipient address The account to transfer the dTokens to. + * @param amount uint256 The amount of dTokens to transfer. + * @return A boolean indicating whether the transfer was successful. + */ + function transfer( + address recipient, uint256 amount + ) external returns (bool success) { + _transfer(msg.sender, recipient, amount); + success = true; + } + + /** + * @notice Transfer dTokens equivalent to `underlyingEquivalentAmount` + * underlying from `msg.sender` to `recipient`. + * @param recipient address The account to transfer the dTokens to. + * @param underlyingEquivalentAmount uint256 The underlying equivalent amount + * of dTokens to transfer. + * @return A boolean indicating whether the transfer was successful. + */ + function transferUnderlying( + address recipient, uint256 underlyingEquivalentAmount + ) external returns (bool success) { + // Accrue interest and retrieve the current dToken exchange rate. + (uint256 dTokenExchangeRate, ) = _accrue(true); + + // Determine dToken amount to transfer using the exchange rate, rounded up. + uint256 dTokenAmount = _fromUnderlying( + underlyingEquivalentAmount, dTokenExchangeRate, true + ); + + // Transfer the dTokens. + _transfer(msg.sender, recipient, dTokenAmount); + success = true; + } + + /** + * @notice Approve `spender` to transfer up to `value` dTokens on behalf of + * `msg.sender`. + * @param spender address The account to grant the allowance. + * @param value uint256 The size of the allowance to grant. + * @return A boolean indicating whether the approval was successful. + */ + function approve( + address spender, uint256 value + ) external returns (bool success) { + _approve(msg.sender, spender, value); + success = true; + } + + /** + * @notice Transfer `amount` dTokens from `sender` to `recipient` as long as + * `msg.sender` has sufficient allowance. + * @param sender address The account to transfer the dTokens from. + * @param recipient address The account to transfer the dTokens to. + * @param amount uint256 The amount of dTokens to transfer. + * @return A boolean indicating whether the transfer was successful. + */ + function transferFrom( + address sender, address recipient, uint256 amount + ) external returns (bool success) { + _transferFrom(sender, recipient, amount); + success = true; + } + + /** + * @notice Transfer dTokens eqivalent to `underlyingEquivalentAmount` + * underlying from `sender` to `recipient` as long as `msg.sender` has + * sufficient allowance. + * @param sender address The account to transfer the dTokens from. + * @param recipient address The account to transfer the dTokens to. + * @param underlyingEquivalentAmount uint256 The underlying equivalent amount + * of dTokens to transfer. + * @return A boolean indicating whether the transfer was successful. + */ + function transferUnderlyingFrom( + address sender, address recipient, uint256 underlyingEquivalentAmount + ) external returns (bool success) { + // Accrue interest and retrieve the current dToken exchange rate. + (uint256 dTokenExchangeRate, ) = _accrue(true); + + // Determine dToken amount to transfer using the exchange rate, rounded up. + uint256 dTokenAmount = _fromUnderlying( + underlyingEquivalentAmount, dTokenExchangeRate, true + ); + + // Transfer the dTokens and adjust allowance accordingly. + _transferFrom(sender, recipient, dTokenAmount); + success = true; + } + + /** + * @notice Increase the current allowance of `spender` by `value` dTokens. + * @param spender address The account to grant the additional allowance. + * @param addedValue uint256 The amount to increase the allowance by. + * @return A boolean indicating whether the modification was successful. + */ + function increaseAllowance( + address spender, uint256 addedValue + ) external returns (bool success) { + _approve( + msg.sender, spender, _allowances[msg.sender][spender].add(addedValue) + ); + success = true; + } + + /** + * @notice Decrease the current allowance of `spender` by `value` dTokens. + * @param spender address The account to decrease the allowance for. + * @param subtractedValue uint256 The amount to subtract from the allowance. + * @return A boolean indicating whether the modification was successful. + */ + function decreaseAllowance( + address spender, uint256 subtractedValue + ) external returns (bool success) { + _approve( + msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue) + ); + success = true; + } + + /** + * @notice Modify the current allowance of `spender` for `owner` by `value` + * dTokens, increasing it if `increase` is true otherwise decreasing it, via a + * meta-transaction that expires at `expiration` (or does not expire if the + * value is zero) and uses `salt` as an additional input, validated using + * `signatures`. + * @param owner address The account granting the modified allowance. + * @param spender address The account to modify the allowance for. + * @param value uint256 The amount to modify the allowance by. + * @param increase bool A flag that indicates whether the allowance will be + * increased by the specified value (if true) or decreased by it (if false). + * @param expiration uint256 A timestamp indicating how long the modification + * meta-transaction is valid for - a value of zero will signify no expiration. + * @param salt bytes32 An arbitrary salt to be provided as an additional input + * to the hash digest used to validate the signatures. + * @param signatures bytes A signature, or collection of signatures, that the + * owner must provide in order to authorize the meta-transaction. If the + * account of the owner does not have any runtime code deployed to it, the + * signature will be verified using ecrecover; otherwise, it will be supplied + * to the owner along with the message digest and context via ERC-1271 for + * validation. + * @return A boolean indicating whether the modification was successful. + */ + function modifyAllowanceViaMetaTransaction( + address owner, + address spender, + uint256 value, + bool increase, + uint256 expiration, + bytes32 salt, + bytes calldata signatures + ) external returns (bool success) { + require(expiration == 0 || now <= expiration, "Meta-transaction expired."); + + // Construct the meta-transaction's message hash based on relevant context. + bytes memory context = abi.encodePacked( + address(this), + // _DTOKEN_VERSION, + this.modifyAllowanceViaMetaTransaction.selector, + expiration, + salt, + abi.encode(owner, spender, value, increase) + ); + bytes32 messageHash = keccak256(context); + + // Ensure message hash has never been used before and register it as used. + require(!_executedMetaTxs[messageHash], "Meta-transaction already used."); + _executedMetaTxs[messageHash] = true; + + // Construct the digest to compare signatures against using EIP-191 0x45. + bytes32 digest = keccak256( + abi.encodePacked("\x19Ethereum Signed Message:\n32", messageHash) + ); + + // Calculate new allowance by applying modification to current allowance. + uint256 currentAllowance = _allowances[owner][spender]; + uint256 newAllowance = ( + increase ? currentAllowance.add(value) : currentAllowance.sub(value) + ); + + // Use EIP-1271 if owner is a contract - otherwise, use ecrecover. + if (_isContract(owner)) { + // Validate via ERC-1271 against the owner account. + bytes memory data = abi.encode(digest, context); + bytes4 magic = ERC1271Interface(owner).isValidSignature(data, signatures); + require(magic == bytes4(0x20c13b0b), "Invalid signatures."); + } else { + // Validate via ecrecover against the owner account. + _verifyRecover(owner, digest, signatures); + } + + // Modify the allowance. + _approve(owner, spender, newAllowance); + success = true; + } + + /** + * @notice View function to determine a meta-transaction message hash, and to + * determine if it is still valid (i.e. it has not yet been used and is not + * expired). The returned message hash will need to be prefixed using EIP-191 + * 0x45 and hashed again in order to generate a final digest for the required + * signature - in other words, the same procedure utilized by `eth_Sign`. + * @param functionSelector bytes4 The function selector for the given + * meta-transaction. There is only one function selector available for V1: + * `0x2d657fa5` (the selector for `modifyAllowanceViaMetaTransaction`). + * @param arguments bytes The abi-encoded function arguments (aside from the + * `expiration`, `salt`, and `signatures` arguments) that should be supplied + * to the given function. + * @param expiration uint256 A timestamp indicating how long the given + * meta-transaction is valid for - a value of zero will signify no expiration. + * @param salt bytes32 An arbitrary salt to be provided as an additional input + * to the hash digest used to validate the signatures. + * @return The total supply. + */ + function getMetaTransactionMessageHash( + bytes4 functionSelector, + bytes calldata arguments, + uint256 expiration, + bytes32 salt + ) external view returns (bytes32 messageHash, bool valid) { + // Construct the meta-transaction's message hash based on relevant context. + messageHash = keccak256( + abi.encodePacked( + address(this), functionSelector, expiration, salt, arguments + ) + ); + + // The meta-transaction is valid if it has not been used and is not expired. + valid = ( + !_executedMetaTxs[messageHash] && (expiration == 0 || now <= expiration) + ); + } + + /** + * @notice View function to get the total dToken supply. + * @return The total supply. + */ + function totalSupply() external view returns (uint256 dTokenTotalSupply) { + dTokenTotalSupply = _totalSupply; + } + + /** + * @notice View function to get the total dToken supply, denominated in the + * underlying token. + * @return The total supply. + */ + function totalSupplyUnderlying() external view returns ( + uint256 dTokenTotalSupplyInUnderlying + ) { + (uint256 dTokenExchangeRate, ,) = _getExchangeRates(true); + + // Determine total value of all issued dTokens, denominated as underlying. + dTokenTotalSupplyInUnderlying = _toUnderlying( + _totalSupply, dTokenExchangeRate, false + ); + } + + /** + * @notice View function to get the total dToken balance of an account. + * @param account address The account to check the dToken balance for. + * @return The balance of the given account. + */ + function balanceOf(address account) external view returns (uint256 dTokens) { + dTokens = _balances[account]; + } + + /** + * @notice View function to get the dToken balance of an account, denominated + * in the underlying equivalent value. + * @param account address The account to check the balance for. + * @return The total underlying-equivalent dToken balance. + */ + function balanceOfUnderlying( + address account + ) external view returns (uint256 underlyingBalance) { + // Get most recent dToken exchange rate by determining accrued interest. + (uint256 dTokenExchangeRate, ,) = _getExchangeRates(true); + + // Convert account balance to underlying equivalent using the exchange rate. + underlyingBalance = _toUnderlying( + _balances[account], dTokenExchangeRate, false + ); + } + + /** + * @notice View function to get the total allowance that `spender` has to + * transfer dTokens from the `owner` account using `transferFrom`. + * @param owner address The account that is granting the allowance. + * @param spender address The account that has been granted the allowance. + * @return The allowance of the given spender for the given owner. + */ + function allowance( + address owner, address spender + ) external view returns (uint256 dTokenAllowance) { + dTokenAllowance = _allowances[owner][spender]; + } + + /** + * @notice View function to get the current dToken exchange rate (multiplied + * by 10^18). + * @return The current exchange rate. + */ + function exchangeRateCurrent() external view returns ( + uint256 dTokenExchangeRate + ) { + // Get most recent dToken exchange rate by determining accrued interest. + (dTokenExchangeRate, ,) = _getExchangeRates(true); + } + + /** + * @notice View function to get the current dToken interest earned per block + * (multiplied by 10^18). + * @return The current interest rate. + */ + function supplyRatePerBlock() external view returns ( + uint256 dTokenInterestRate + ) { + (dTokenInterestRate,) = _getRatePerBlock(); + } + + /** + * @notice View function to get the block number where accrual was last + * performed. + * @return The block number where accrual was last performed. + */ + function accrualBlockNumber() external view returns (uint256 blockNumber) { + blockNumber = _accrualIndex.block; + } + + /** + * @notice View function to get the total surplus, or the cToken balance that + * exceeds the aggregate underlying value of the total dToken supply. + * @return The total surplus in cTokens. + */ + function getSurplus() external view returns (uint256 cTokenSurplus) { + // Determine the cToken (cToken underlying value - dToken underlying value). + (, cTokenSurplus) = _getSurplus(); + } + + /** + * @notice View function to get the total surplus in the underlying, or the + * underlying equivalent of the cToken balance that exceeds the aggregate + * underlying value of the total dToken supply. + * @return The total surplus, denominated in the underlying. + */ + function getSurplusUnderlying() external view returns ( + uint256 underlyingSurplus + ) { + // Determine cToken surplus in underlying (cToken value - dToken value). + (underlyingSurplus, ) = _getSurplus(); + } + + /** + * @notice View function to get the interest rate spread taken by the dToken + * from the current cToken supply rate per block (multiplied by 10^18). + * @return The current interest rate spread. + */ + function getSpreadPerBlock() external view returns (uint256 rateSpread) { + ( + uint256 dTokenInterestRate, uint256 cTokenInterestRate + ) = _getRatePerBlock(); + rateSpread = cTokenInterestRate.sub(dTokenInterestRate); + } + + /** + * @notice Pure function to get the name of the dToken. + * @return The name of the dToken. + */ + function name() external pure returns (string memory dTokenName) { + dTokenName = _getDTokenName(); + } + + /** + * @notice Pure function to get the symbol of the dToken. + * @return The symbol of the dToken. + */ + function symbol() external pure returns (string memory dTokenSymbol) { + dTokenSymbol = _getDTokenSymbol(); + } + + /** + * @notice Pure function to get the number of decimals of the dToken. + * @return The number of decimals of the dToken. + */ + function decimals() external pure returns (uint8 dTokenDecimals) { + dTokenDecimals = _DECIMALS; + } + + /** + * @notice Pure function to get the dToken version. + * @return The version of the dToken. + */ + function getVersion() external pure returns (uint256 version) { + version = _DTOKEN_VERSION; + } + + /** + * @notice Pure function to get the address of the cToken backing this dToken. + * @return The address of the cToken backing this dToken. + */ + function getCToken() external pure returns (address cToken) { + cToken = _getCToken(); + } + + /** + * @notice Pure function to get the address of the underlying token of this + * dToken. + * @return The address of the underlying token for this dToken. + */ + function getUnderlying() external pure returns (address underlying) { + underlying = _getUnderlying(); + } + + /** + * @notice Private function to trigger accrual and to update the dToken and + * cToken exchange rates in storage if necessary. The `compute` argument can + * be set to false if an accrual has already taken place on the cToken before + * calling this function. + * @param compute bool A flag to indicate whether the cToken exchange rate + * needs to be computed - if false, it will simply be read from storage on the + * cToken in question. + * @return The current dToken and cToken exchange rates. + */ + function _accrue(bool compute) private returns ( + uint256 dTokenExchangeRate, uint256 cTokenExchangeRate + ) { + bool alreadyAccrued; + ( + dTokenExchangeRate, cTokenExchangeRate, alreadyAccrued + ) = _getExchangeRates(compute); + + if (!alreadyAccrued) { + // Update storage with dToken + cToken exchange rates as of current block. + AccrualIndex storage accrualIndex = _accrualIndex; + accrualIndex.dTokenExchangeRate = _safeUint112(dTokenExchangeRate); + accrualIndex.cTokenExchangeRate = _safeUint112(cTokenExchangeRate); + accrualIndex.block = uint32(block.number); + emit Accrue(dTokenExchangeRate, cTokenExchangeRate); + } + } + + /** + * @notice Private function to mint `amount` tokens by exchanging `exchanged` + * tokens to `account` and emit corresponding `Mint` & `Transfer` events. + * @param account address The account to mint tokens to. + * @param exchanged uint256 The amount of underlying tokens used to mint. + * @param amount uint256 The amount of tokens to mint. + */ + function _mint(address account, uint256 exchanged, uint256 amount) private { + require( + exchanged > 0 && amount > 0, "Mint failed: insufficient funds supplied." + ); + _totalSupply = _totalSupply.add(amount); + _balances[account] = _balances[account].add(amount); + + emit Mint(account, exchanged, amount); + emit Transfer(address(0), account, amount); + } + + /** + * @notice Private function to burn `amount` tokens by exchanging `exchanged` + * tokens from `account` and emit corresponding `Redeeem` & `Transfer` events. + * @param account address The account to burn tokens from. + * @param exchanged uint256 The amount of underlying tokens given for burning. + * @param amount uint256 The amount of tokens to burn. + */ + function _burn(address account, uint256 exchanged, uint256 amount) private { + require( + exchanged > 0 && amount > 0, "Redeem failed: insufficient funds supplied." + ); + + uint256 balancePriorToBurn = _balances[account]; + require( + balancePriorToBurn >= amount, "Supplied amount exceeds account balance." + ); + + _totalSupply = _totalSupply.sub(amount); + _balances[account] = balancePriorToBurn - amount; // overflow checked above + + emit Transfer(account, address(0), amount); + emit Redeem(account, exchanged, amount); + } + + /** + * @notice Private function to move `amount` tokens from `sender` to + * `recipient` and emit a corresponding `Transfer` event. + * @param sender address The account to transfer tokens from. + * @param recipient address The account to transfer tokens to. + * @param amount uint256 The amount of tokens to transfer. + */ + function _transfer( + address sender, address recipient, uint256 amount + ) private { + require(sender != address(0), "ERC20: transfer from the zero address"); + require(recipient != address(0), "ERC20: transfer to the zero address"); + + uint256 senderBalance = _balances[sender]; + require(senderBalance >= amount, "Insufficient funds."); + + _balances[sender] = senderBalance - amount; // overflow checked above. + _balances[recipient] = _balances[recipient].add(amount); + + emit Transfer(sender, recipient, amount); + } + + /** + * @notice Private function to transfer `amount` tokens from `sender` to + * `recipient` and to deduct the transferred amount from the allowance of the + * caller unless the allowance is set to the maximum amount. + * @param sender address The account to transfer tokens from. + * @param recipient address The account to transfer tokens to. + * @param amount uint256 The amount of tokens to transfer. + */ + function _transferFrom( + address sender, address recipient, uint256 amount + ) private { + _transfer(sender, recipient, amount); + uint256 callerAllowance = _allowances[sender][msg.sender]; + if (callerAllowance != uint256(-1)) { + require(callerAllowance >= amount, "Insufficient allowance."); + _approve(sender, msg.sender, callerAllowance - amount); // overflow safe. + } + } + + /** + * @notice Private function to set the allowance for `spender` to transfer up + * to `value` tokens on behalf of `owner`. + * @param owner address The account that has granted the allowance. + * @param spender address The account to grant the allowance. + * @param value uint256 The size of the allowance to grant. + */ + function _approve(address owner, address spender, uint256 value) private { + require(owner != address(0), "ERC20: approve for the zero address"); + require(spender != address(0), "ERC20: approve to the zero address"); + + _allowances[owner][spender] = value; + emit Approval(owner, spender, value); + } + + /** + * @notice Private view function to get the latest dToken and cToken exchange + * rates and provide the value for each. The `compute` argument can be set to + * false if an accrual has already taken place on the cToken before calling + * this function. + * @param compute bool A flag to indicate whether the cToken exchange rate + * needs to be computed - if false, it will simply be read from storage on the + * cToken in question. + * @return The dToken and cToken exchange rate, as well as a boolean + * indicating if interest accrual has been processed already or needs to be + * calculated and placed in storage. + */ + function _getExchangeRates(bool compute) private view returns ( + uint256 dTokenExchangeRate, uint256 cTokenExchangeRate, bool fullyAccrued + ) { + // Get the stored accrual block and dToken + cToken exhange rates. + AccrualIndex memory accrualIndex = _accrualIndex; + uint256 storedDTokenExchangeRate = uint256(accrualIndex.dTokenExchangeRate); + uint256 storedCTokenExchangeRate = uint256(accrualIndex.cTokenExchangeRate); + uint256 accrualBlock = uint256(accrualIndex.block); + + // Use stored exchange rates if an accrual has already occurred this block. + fullyAccrued = (accrualBlock == block.number); + if (fullyAccrued) { + dTokenExchangeRate = storedDTokenExchangeRate; + cTokenExchangeRate = storedCTokenExchangeRate; + } else { + // Only compute cToken exchange rate if it has not accrued this block. + if (compute) { + // Get current cToken exchange rate; inheriting contract overrides this. + (cTokenExchangeRate,) = _getCurrentCTokenRates(); + } else { + // Otherwise, get the stored cToken exchange rate. + cTokenExchangeRate = CTokenInterface(_getCToken()).exchangeRateStored(); + } + + // Determine the cToken interest earned during the period. + uint256 cTokenInterest = ( + (cTokenExchangeRate.mul(_SCALING_FACTOR)).div(storedCTokenExchangeRate) + ).sub(_SCALING_FACTOR); + + // Calculate dToken exchange rate by applying 90% of the cToken interest. + dTokenExchangeRate = storedDTokenExchangeRate.mul( + _SCALING_FACTOR.add(cTokenInterest.mul(9) / 10) + ) / _SCALING_FACTOR; + } + } + + /** + * @notice Private view function to get the total surplus, or cToken + * balance that exceeds the total dToken balance. + * @return The total surplus, denominated in both the underlying and in the + * cToken. + */ + function _getSurplus() private view returns ( + uint256 underlyingSurplus, uint256 cTokenSurplus + ) { + // Instantiate the interface for the backing cToken. + CTokenInterface cToken = CTokenInterface(_getCToken()); + + ( + uint256 dTokenExchangeRate, uint256 cTokenExchangeRate, + ) = _getExchangeRates(true); + + // Determine value of all issued dTokens in the underlying, rounded up. + uint256 dTokenUnderlying = _toUnderlying( + _totalSupply, dTokenExchangeRate, true + ); + + // Determine value of all retained cTokens in the underlying, rounded down. + uint256 cTokenUnderlying = _toUnderlying( + cToken.balanceOf(address(this)), cTokenExchangeRate, false + ); + + // Determine the size of the surplus in terms of underlying amount. + underlyingSurplus = cTokenUnderlying > dTokenUnderlying + ? cTokenUnderlying - dTokenUnderlying // overflow checked above + : 0; + + // Determine the cToken equivalent of this surplus amount. + cTokenSurplus = underlyingSurplus == 0 + ? 0 + : _fromUnderlying(underlyingSurplus, cTokenExchangeRate, false); + } + + /** + * @notice Private view function to get the current dToken and cToken interest + * supply rate per block (multiplied by 10^18). + * @return The current dToken and cToken interest rates. + */ + function _getRatePerBlock() private view returns ( + uint256 dTokenSupplyRate, uint256 cTokenSupplyRate + ) { + (, cTokenSupplyRate) = _getCurrentCTokenRates(); + dTokenSupplyRate = cTokenSupplyRate.mul(9) / 10; + } + + /** + * @notice Private view function to determine if a given account has runtime + * code or not - in other words, whether or not a contract is deployed to the + * account in question. Note that contracts that are in the process of being + * deployed will return false on this check. + * @param account address The account to check for contract runtime code. + * @return Whether or not there is contract runtime code at the account. + */ + function _isContract(address account) private view returns (bool isContract) { + uint256 size; + assembly { size := extcodesize(account) } + isContract = size > 0; + } + + /** + * @notice Private pure function to verify that a given signature of a digest + * resolves to the supplied account. Any error, including incorrect length, + * malleable signature types, or unsupported `v` values, will cause a revert. + * @param account address The account to validate against. + * @param digest bytes32 The digest to use. + * @param signature bytes The signature to verify. + */ + function _verifyRecover( + address account, bytes32 digest, bytes memory signature + ) private pure { + // Ensure the signature length is correct. + require( + signature.length == 65, + "Must supply a single 65-byte signature when owner is not a contract." + ); + + // Divide the signature in r, s and v variables. + bytes32 r; + bytes32 s; + uint8 v; + assembly { + r := mload(add(signature, 0x20)) + s := mload(add(signature, 0x40)) + v := byte(0, mload(add(signature, 0x60))) + } + + require( + uint256(s) <= _MAX_UNMALLEABLE_S, + "Signature `s` value cannot be potentially malleable." + ); + + require(v == 27 || v == 28, "Signature `v` value not permitted."); + + require(account == ecrecover(digest, v, r, s), "Invalid signature."); + } +} \ No newline at end of file diff --git a/contracts/implementations/token/DharmaUSDCImplementationV0.sol b/contracts/implementations/token/DharmaUSDCImplementationV0.sol deleted file mode 100644 index cb3fbcb..0000000 --- a/contracts/implementations/token/DharmaUSDCImplementationV0.sol +++ /dev/null @@ -1,4 +0,0 @@ -pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg - - -contract DharmaUSDCImplementationV0 {} \ No newline at end of file diff --git a/contracts/implementations/token/DharmaUSDCImplementationV1.sol b/contracts/implementations/token/DharmaUSDCImplementationV1.sol new file mode 100644 index 0000000..fce272b --- /dev/null +++ b/contracts/implementations/token/DharmaUSDCImplementationV1.sol @@ -0,0 +1,126 @@ +pragma solidity 0.5.11; + +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "./DharmaTokenV1.sol"; +import "../../interfaces/CTokenInterface.sol"; +import "../../interfaces/ERC20Interface.sol"; +import "../../interfaces/CUSDCInterestRateModelInterface.sol"; + + +/** + * @title DharmaUSDCImplementationV1 + * @author 0age (dToken mechanics derived from Compound cTokens, ERC20 methods + * derived from Open Zeppelin's ERC20 contract) + * @notice Dharma USD Coin is an interest-bearing token, with cUSDC as the + * backing token and USD Coin as the underlying token. The dUSDC exchange rate + * will initially increase at 90% the rate of the cUSDC exchange rate. + */ +contract DharmaUSDCImplementationV1 is DharmaTokenV1 { + string internal constant _NAME = "Dharma USD Coin"; + string internal constant _SYMBOL = "dUSDC"; + string internal constant _UNDERLYING_NAME = "USD Coin"; + string internal constant _CTOKEN_SYMBOL = "cUSDC"; + + CTokenInterface internal constant _CUSDC = CTokenInterface( + 0x39AA39c021dfbaE8faC545936693aC917d5E7563 // mainnet + ); + + ERC20Interface internal constant _USDC = ERC20Interface( + 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 // mainnet + ); + + // Note: this is just an EOA for the initial prototype. + address internal constant _VAULT = 0x7e4A8391C728fEd9069B2962699AB416628B19Fa; + + uint256 internal constant _SCALING_FACTOR_SQUARED = 1e36; + + /** + * @notice Internal view function to get the current cUSDC exchange rate and + * supply rate per block. + * @return The current cUSDC exchange rate, or amount of USDC that is + * redeemable for each cUSDC, and the cUSDC supply rate per block (with 18 + * decimal places added to each returned rate). + */ + function _getCurrentCTokenRates() internal view returns ( + uint256 exchangeRate, uint256 supplyRate + ) { + // Determine number of blocks that have elapsed since last cUSDC accrual. + uint256 blockDelta = block.number.sub(_CUSDC.accrualBlockNumber()); + + // Return stored values if accrual has already been performed this block. + if (blockDelta == 0) return ( + _CUSDC.exchangeRateStored(), _CUSDC.supplyRatePerBlock() + ); + + // Determine total "cash" held by cUSDC contract. + uint256 cash = _USDC.balanceOf(address(_CUSDC)); + + // Get the latest interest rate model from the cUSDC contract. + CUSDCInterestRateModelInterface interestRateModel = ( + CUSDCInterestRateModelInterface(_CUSDC.interestRateModel()) + ); + + // Get the current stored total borrows, reserves, and reserve factor. + uint256 borrows = _CUSDC.totalBorrows(); + uint256 reserves = _CUSDC.totalReserves(); + uint256 reserveFactor = _CUSDC.reserveFactorMantissa(); + + // Get accumulated borrow interest via interest rate model and block delta. + (uint256 err, uint256 borrowRate) = interestRateModel.getBorrowRate( + cash, borrows, reserves + ); + require( + err == _COMPOUND_SUCCESS, "Interest Rate Model borrow rate check failed." + ); + + uint256 interest = borrowRate.mul(blockDelta).mul(borrows) / _SCALING_FACTOR; + + // Update total borrows and reserves using calculated accumulated interest. + borrows = borrows.add(interest); + reserves = reserves.add(reserveFactor.mul(interest) / _SCALING_FACTOR); + + // Get "underlying": (cash + borrows - reserves) + uint256 underlying = (cash.add(borrows)).sub(reserves); + + // Determine cUSDC exchange rate: underlying / total supply + exchangeRate = (underlying.mul(_SCALING_FACTOR)).div(_CUSDC.totalSupply()); + + // Get "borrows per" by dividing total borrows by underlying and scaling up. + uint256 borrowsPer = ( + borrows.mul(_SCALING_FACTOR_SQUARED) + ).div(underlying); + + // Supply rate is borrow interest * (1 - reserveFactor) * borrowsPer + supplyRate = ( + interest.mul(_SCALING_FACTOR.sub(reserveFactor)).mul(borrowsPer) + ) / _SCALING_FACTOR_SQUARED; + } + + function _getUnderlyingName() internal pure returns (string memory underlyingName) { + underlyingName = _UNDERLYING_NAME; + } + + function _getUnderlying() internal pure returns (address underlying) { + underlying = address(_USDC); + } + + function _getCTokenSymbol() internal pure returns (string memory cTokenSymbol) { + cTokenSymbol = _CTOKEN_SYMBOL; + } + + function _getCToken() internal pure returns (address cToken) { + cToken = address(_CUSDC); + } + + function _getDTokenName() internal pure returns (string memory dTokenName) { + dTokenName = _NAME; + } + + function _getDTokenSymbol() internal pure returns (string memory dTokenSymbol) { + dTokenSymbol = _SYMBOL; + } + + function _getVault() internal pure returns (address vault) { + vault = _VAULT; + } +} \ No newline at end of file diff --git a/contracts/implementations/token/DharmaUSDCInitializationImplementation.sol b/contracts/implementations/token/DharmaUSDCInitializationImplementation.sol deleted file mode 100644 index 258da35..0000000 --- a/contracts/implementations/token/DharmaUSDCInitializationImplementation.sol +++ /dev/null @@ -1,4 +0,0 @@ -pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg - - -contract DharmaUSDCInitializationImplementation {} \ No newline at end of file diff --git a/contracts/implementations/token/DharmaUSDCInitializer.sol b/contracts/implementations/token/DharmaUSDCInitializer.sol new file mode 100644 index 0000000..a83582b --- /dev/null +++ b/contracts/implementations/token/DharmaUSDCInitializer.sol @@ -0,0 +1,71 @@ +pragma solidity 0.5.11; + +import "../../interfaces/CTokenInterface.sol"; +import "../../interfaces/ERC20Interface.sol"; + + +/** + * @title DharmaUSDCInitializer + * @author 0age + * @notice Initializer for the Dharma USD Coin token. + */ +contract DharmaUSDCInitializer { + event Accrue(uint256 dTokenExchangeRate, uint256 cTokenExchangeRate); + + // The block number and cToken + dToken exchange rates are updated on accrual. + struct AccrualIndex { + uint112 dTokenExchangeRate; + uint112 cTokenExchangeRate; + uint32 block; + } + + CTokenInterface internal constant _CUSDC = CTokenInterface( + 0x39AA39c021dfbaE8faC545936693aC917d5E7563 // mainnet + ); + + ERC20Interface internal constant _USDC = ERC20Interface( + 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 // mainnet + ); + + uint256 internal constant _MAX_UINT_112 = 5192296858534827628530496329220095; + + // Set block number and dToken + cToken exchange rate in slot zero on accrual. + AccrualIndex private _accrualIndex; + + /** + * @notice Initialize Dharma USD Coin by approving cUSDC to transfer USDC on + * behalf of this contract and setting the initial dUSDC and cUSDC exchange + * rates in storage. + */ + function initialize() public { + // Approve cToken to transfer underlying for this contract in order to mint. + require( + _USDC.approve(address(_CUSDC), uint256(-1)), + "Initial cUSDC approval failed." + ); + + // Initial dToken exchange rate is 1-to-1 (dTokens have 8 decimals). + uint256 dTokenExchangeRate = 1e16; + + // Accrue cToken interest and retrieve the current cToken exchange rate. + uint256 cTokenExchangeRate = _CUSDC.exchangeRateCurrent(); + + // Initialize accrual index with current block number and exchange rates. + AccrualIndex storage accrualIndex = _accrualIndex; + accrualIndex.dTokenExchangeRate = uint112(dTokenExchangeRate); + accrualIndex.cTokenExchangeRate = _safeUint112(cTokenExchangeRate); + accrualIndex.block = uint32(block.number); + emit Accrue(dTokenExchangeRate, cTokenExchangeRate); + } + + /** + * @notice Internal pure function to convert a uint256 to a uint112, reverting + * if the conversion would cause an overflow. + * @param input uint256 The unsigned integer to convert. + * @return The converted unsigned integer. + */ + function _safeUint112(uint256 input) internal pure returns (uint112 output) { + require(input <= _MAX_UINT_112, "Overflow on conversion to uint112."); + output = uint112(input); + } +} \ No newline at end of file diff --git a/contracts/proxies/token/DharmaDai.sol b/contracts/proxies/token/DharmaDai.sol index 0df9937..ee7a4fe 100644 --- a/contracts/proxies/token/DharmaDai.sol +++ b/contracts/proxies/token/DharmaDai.sol @@ -4,8 +4,9 @@ pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg /** * @title DharmaDai * @author 0age - * @notice Dharma Dai delegates all logic to an implementation contract - * specified by a hard-coded "upgrade beacon" contract. + * @notice Dharma Dai is an upgradeable ERC20 token that delegates all logic to + * an implementation contract specified by a hard-coded "upgrade beacon" + * contract. */ contract DharmaDai { // Set upgrade beacon address as a constant (i.e. not in contract storage). diff --git a/scripts/test/constants.js b/scripts/test/constants.js index c786ba1..f0aa365 100644 --- a/scripts/test/constants.js +++ b/scripts/test/constants.js @@ -234,6 +234,24 @@ module.exports = Object.freeze({ DHARMA_DAI_METADATA : ( ['20202020202020446861726d6120446169202864446169292020202020202020'] ), + DHARMA_DAI_IMPLEMENTATION_V1_ADDRESS: ( + '0x00000000580090B7b5B593AB408000b1AbB5f78d' + ), + DHARMA_DAI_IMPLEMENTATION_V1_SALT: ( + '0x0000000000000000000000000000000000000000e576fa39d46b480fd5010000' + ), + DHARMA_DAI_IMPLEMENTATION_V1_METADATA : ( + ['2020446861726d612044616920496d706c656d656e746174696f6e2056312020'] + ), + DHARMA_USDC_IMPLEMENTATION_V1_ADDRESS: ( + '0x00000000de26576A3700bb87d61BFbEE335C8b56' + ), + DHARMA_USDC_IMPLEMENTATION_V1_SALT: ( + '0x00000000000000000000000000000000000000002e6250385076920b57000000' + ), + DHARMA_USDC_IMPLEMENTATION_V1_METADATA : ( + ['446861726d612055534420436f696e20496d706c656d656e746174696f6e2031'] + ), DHARMA_USDC_ADDRESS: ( '0x0000000000946A7848C50C8f0AE1BB2792602Cb7' ), diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index 305840f..5524843 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -129,19 +129,19 @@ module.exports = {test: async function (provider, testingContext) { let gasUsage = {} let counts = {} - /* + console.log( swapMetadataHash( DharmaUSDCArtifact.bytecode, - constants.DHARMA_DAI_METADATA + constants.DHARMA_USDC_METADATA ), web3.utils.keccak256(swapMetadataHash( DharmaUSDCArtifact.bytecode, - constants.DHARMA_DAI_METADATA + constants.DHARMA_USDC_METADATA ), {encoding: 'hex'}) ) process.exit(0) - */ + const DharmaUpgradeBeaconController = new web3.eth.Contract( DharmaUpgradeBeaconControllerArtifact.abi, From b624e525ec9b363772d9877e5376f23046a2d8b8 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Tue, 4 Feb 2020 03:01:28 -0500 Subject: [PATCH 05/47] finished initial dToken deployment --- .../DharmaSmartWalletImplementationV7.sol | 2 +- contracts/proxies/token/DharmaUSDC.sol | 11 ++++++----- scripts/test/constants.js | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol index 446cf30..d270a09 100644 --- a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol +++ b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol @@ -92,7 +92,7 @@ contract DharmaSmartWalletImplementationV7 is ); DTokenInterface internal constant _DUSDC = DTokenInterface( - 0x0000000000946A7848C50C8f0AE1BB2792602Cb7 // mainnet + 0x00000000008943c65cAf789FFFCF953bE156f6f8 // mainnet ); IERC20 internal constant _DAI = IERC20( diff --git a/contracts/proxies/token/DharmaUSDC.sol b/contracts/proxies/token/DharmaUSDC.sol index 363a51c..f4d6007 100644 --- a/contracts/proxies/token/DharmaUSDC.sol +++ b/contracts/proxies/token/DharmaUSDC.sol @@ -2,15 +2,16 @@ pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg /** - * @title DharmaUSDC + * @title DharmaUSDC (staging version) * @author 0age - * @notice Dharma USDC delegates all logic to an implementation contract - * specified by a hard-coded "upgrade beacon" contract. + * @notice Dharma USD Coin is an upgradeable ERC20 token that delegates all + * logic to an implementation contract specified by a hard-coded "upgrade + * beacon" contract. */ -contract DharmaUSDC { +contract DharmaUSDCStaging { // Set upgrade beacon address as a constant (i.e. not in contract storage). address private constant _UPGRADE_BEACON = address( - 0x00000000000274bE4365Aa18CfDC9A22A947f67D + 0xe9DDDA6C56bFD31725D118E7F13a3eb4f3A82226 ); /** diff --git a/scripts/test/constants.js b/scripts/test/constants.js index f0aa365..c0dc4a9 100644 --- a/scripts/test/constants.js +++ b/scripts/test/constants.js @@ -253,10 +253,10 @@ module.exports = Object.freeze({ ['446861726d612055534420436f696e20496d706c656d656e746174696f6e2031'] ), DHARMA_USDC_ADDRESS: ( - '0x0000000000946A7848C50C8f0AE1BB2792602Cb7' + '0x00000000008943c65cAf789FFFCF953bE156f6f8' ), DHARMA_USDC_SALT: ( - '0x00000000000000000000000000000000000000001cde6de5d233ca09540d0000' + '0x0000000000000000000000000000000000000000f1507216069e1c0f60090000' ), DHARMA_USDC_METADATA : ( ['20202020446861726d612055534420436f696e20286455534443292020202020'] From d8db2c38d1d3f1c391e9711a719f441adbe66bc1 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Thu, 6 Feb 2020 09:46:56 -0500 Subject: [PATCH 06/47] add in dharma token v1 contracts --- .soliumignore | 3 ++ .../token/DharmaDaiImplementationV1.sol | 8 ++-- .../token/DharmaDaiInitializer.sol | 4 +- .../token/DharmaTokenHelpers.sol | 2 +- .../implementations/token/DharmaTokenV1.sol | 8 ++-- .../token/DharmaUSDCImplementationV1.sol | 6 +-- .../token/DharmaUSDCInitializer.sol | 4 +- contracts/proxies/token/DharmaUSDC.sol | 8 ++-- interfaces/CDaiInterestRateModelInterface.sol | 12 +++++ interfaces/CTokenInterface.sol | 26 +++++----- .../CUSDCInterestRateModelInterface.sol | 8 ++++ interfaces/DTokenInterface.sol | 48 ++++++++++++++----- interfaces/ERC1271Interface.sol | 8 ++++ interfaces/ERC20Interface.sol | 14 ++++++ interfaces/PotInterface.sol | 9 ++++ scripts/test/constants.js | 3 ++ scripts/test/deploy.js | 14 +++--- 17 files changed, 133 insertions(+), 52 deletions(-) create mode 100644 interfaces/CDaiInterestRateModelInterface.sol create mode 100644 interfaces/CUSDCInterestRateModelInterface.sol create mode 100644 interfaces/ERC1271Interface.sol create mode 100644 interfaces/ERC20Interface.sol create mode 100644 interfaces/PotInterface.sol diff --git a/.soliumignore b/.soliumignore index 715d65c..d92a017 100644 --- a/.soliumignore +++ b/.soliumignore @@ -8,6 +8,7 @@ interfaces/RelayContractInterface.sol extra-contracts/helpers/FactoryFactFinder.sol contracts/upgradeability/DharmaUpgradeBeaconController.sol contracts/implementations/smart-wallet/AdharmaSmartWalletImplementation.sol +contracts/implementations/token/DharmaTokenOverrides.sol # parsing error due to dynamic abi.decode - try again in later version contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV0.sol @@ -20,6 +21,8 @@ contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV6.sol contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol contracts/implementations/smart-wallet/DharmaSmartWalletImplementationVX.sol +contracts/implementations/token/DharmaDaiImplementationV1.sol + extra-contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV0.sol extra-contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV1.sol extra-contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV2.sol diff --git a/contracts/implementations/token/DharmaDaiImplementationV1.sol b/contracts/implementations/token/DharmaDaiImplementationV1.sol index 89b22b0..1022d23 100644 --- a/contracts/implementations/token/DharmaDaiImplementationV1.sol +++ b/contracts/implementations/token/DharmaDaiImplementationV1.sol @@ -2,10 +2,10 @@ pragma solidity 0.5.11; import "@openzeppelin/contracts/math/SafeMath.sol"; import "./DharmaTokenV1.sol"; -import "../../interfaces/CTokenInterface.sol"; -import "../../interfaces/ERC20Interface.sol"; -import "../../interfaces/CDaiInterestRateModelInterface.sol"; -import "../../interfaces/PotInterface.sol"; +import "../../../interfaces/CTokenInterface.sol"; +import "../../../interfaces/ERC20Interface.sol"; +import "../../../interfaces/CDaiInterestRateModelInterface.sol"; +import "../../../interfaces/PotInterface.sol"; /** diff --git a/contracts/implementations/token/DharmaDaiInitializer.sol b/contracts/implementations/token/DharmaDaiInitializer.sol index 00bf0bb..d723c1f 100644 --- a/contracts/implementations/token/DharmaDaiInitializer.sol +++ b/contracts/implementations/token/DharmaDaiInitializer.sol @@ -1,7 +1,7 @@ pragma solidity 0.5.11; -import "../../interfaces/CTokenInterface.sol"; -import "../../interfaces/ERC20Interface.sol"; +import "../../../interfaces/CTokenInterface.sol"; +import "../../../interfaces/ERC20Interface.sol"; /** diff --git a/contracts/implementations/token/DharmaTokenHelpers.sol b/contracts/implementations/token/DharmaTokenHelpers.sol index 0ca0345..e812c8a 100644 --- a/contracts/implementations/token/DharmaTokenHelpers.sol +++ b/contracts/implementations/token/DharmaTokenHelpers.sol @@ -1,7 +1,7 @@ pragma solidity 0.5.11; import "@openzeppelin/contracts/math/SafeMath.sol"; -import "../../interfaces/CTokenInterface.sol"; +import "../../../interfaces/CTokenInterface.sol"; import "./DharmaTokenOverrides.sol"; diff --git a/contracts/implementations/token/DharmaTokenV1.sol b/contracts/implementations/token/DharmaTokenV1.sol index 1aac546..08617bf 100644 --- a/contracts/implementations/token/DharmaTokenV1.sol +++ b/contracts/implementations/token/DharmaTokenV1.sol @@ -1,10 +1,10 @@ pragma solidity 0.5.11; import "./DharmaTokenHelpers.sol"; -import "../../interfaces/CTokenInterface.sol"; -import "../../interfaces/DTokenInterface.sol"; -import "../../interfaces/ERC20Interface.sol"; -import "../../interfaces/ERC1271Interface.sol"; +import "../../../interfaces/CTokenInterface.sol"; +import "../../../interfaces/DTokenInterface.sol"; +import "../../../interfaces/ERC20Interface.sol"; +import "../../../interfaces/ERC1271Interface.sol"; /** diff --git a/contracts/implementations/token/DharmaUSDCImplementationV1.sol b/contracts/implementations/token/DharmaUSDCImplementationV1.sol index fce272b..ec612ae 100644 --- a/contracts/implementations/token/DharmaUSDCImplementationV1.sol +++ b/contracts/implementations/token/DharmaUSDCImplementationV1.sol @@ -2,9 +2,9 @@ pragma solidity 0.5.11; import "@openzeppelin/contracts/math/SafeMath.sol"; import "./DharmaTokenV1.sol"; -import "../../interfaces/CTokenInterface.sol"; -import "../../interfaces/ERC20Interface.sol"; -import "../../interfaces/CUSDCInterestRateModelInterface.sol"; +import "../../../interfaces/CTokenInterface.sol"; +import "../../../interfaces/ERC20Interface.sol"; +import "../../../interfaces/CUSDCInterestRateModelInterface.sol"; /** diff --git a/contracts/implementations/token/DharmaUSDCInitializer.sol b/contracts/implementations/token/DharmaUSDCInitializer.sol index a83582b..d109468 100644 --- a/contracts/implementations/token/DharmaUSDCInitializer.sol +++ b/contracts/implementations/token/DharmaUSDCInitializer.sol @@ -1,7 +1,7 @@ pragma solidity 0.5.11; -import "../../interfaces/CTokenInterface.sol"; -import "../../interfaces/ERC20Interface.sol"; +import "../../../interfaces/CTokenInterface.sol"; +import "../../../interfaces/ERC20Interface.sol"; /** diff --git a/contracts/proxies/token/DharmaUSDC.sol b/contracts/proxies/token/DharmaUSDC.sol index f4d6007..8c0f395 100644 --- a/contracts/proxies/token/DharmaUSDC.sol +++ b/contracts/proxies/token/DharmaUSDC.sol @@ -2,16 +2,16 @@ pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg /** - * @title DharmaUSDC (staging version) + * @title DharmaUSDC * @author 0age * @notice Dharma USD Coin is an upgradeable ERC20 token that delegates all * logic to an implementation contract specified by a hard-coded "upgrade - * beacon" contract. + *beacon" contract. */ -contract DharmaUSDCStaging { +contract DharmaUSDC { // Set upgrade beacon address as a constant (i.e. not in contract storage). address private constant _UPGRADE_BEACON = address( - 0xe9DDDA6C56bFD31725D118E7F13a3eb4f3A82226 + 0x00000000000274bE4365Aa18CfDC9A22A947f67D ); /** diff --git a/interfaces/CDaiInterestRateModelInterface.sol b/interfaces/CDaiInterestRateModelInterface.sol new file mode 100644 index 0000000..23e10cc --- /dev/null +++ b/interfaces/CDaiInterestRateModelInterface.sol @@ -0,0 +1,12 @@ +pragma solidity 0.5.11; + + +interface CDaiInterestRateModelInterface { + function getBorrowRate( + uint256 cash, uint256 borrows, uint256 reserves + ) external view returns (uint256 borrowRate); + + function getSupplyRate( + uint256 cash, uint256 borrows, uint256 reserves, uint256 reserveFactor + ) external view returns (uint256 supplyRate); +} \ No newline at end of file diff --git a/interfaces/CTokenInterface.sol b/interfaces/CTokenInterface.sol index b74babd..2757e5b 100644 --- a/interfaces/CTokenInterface.sol +++ b/interfaces/CTokenInterface.sol @@ -3,28 +3,24 @@ pragma solidity 0.5.11; interface CTokenInterface { function mint(uint256 mintAmount) external returns (uint256 err); - function redeem(uint256 redeemAmount) external returns (uint256 err); - function redeemUnderlying(uint256 redeemAmount) external returns (uint256 err); - - function balanceOf(address account) external view returns (uint256 balance); - - function balanceOfUnderlying(address account) external returns (uint256 balance); - - function exchangeRateCurrent() external returns (uint256 exchangeRate); - + function accrueInterest() external returns (uint256 err); function transfer(address recipient, uint256 value) external returns (bool); - function transferFrom(address sender, address recipient, uint256 value) external returns (bool); - function approve(address spender, uint256 amount) external returns (bool); + function balanceOfUnderlying(address account) external returns (uint256 balance); + function exchangeRateCurrent() external returns (uint256 exchangeRate); - function allowance(address owner, address spender) external view returns (uint256); - + function getCash() external view returns (uint256); + function totalSupply() external view returns (uint256 supply); + function totalBorrows() external view returns (uint256 borrows); + function totalReserves() external view returns (uint256 reserves); + function interestRateModel() external view returns (address model); + function reserveFactorMantissa() external view returns (uint256 factor); function supplyRatePerBlock() external view returns (uint256 rate); - function exchangeRateStored() external view returns (uint256 rate); - function accrualBlockNumber() external view returns (uint256 blockNumber); + function balanceOf(address account) external view returns (uint256 balance); + function allowance(address owner, address spender) external view returns (uint256); } \ No newline at end of file diff --git a/interfaces/CUSDCInterestRateModelInterface.sol b/interfaces/CUSDCInterestRateModelInterface.sol new file mode 100644 index 0000000..57b679f --- /dev/null +++ b/interfaces/CUSDCInterestRateModelInterface.sol @@ -0,0 +1,8 @@ +pragma solidity 0.5.11; + + +interface CUSDCInterestRateModelInterface { + function getBorrowRate( + uint256 cash, uint256 borrows, uint256 reserves + ) external view returns (uint256 err, uint256 borrowRate); +} \ No newline at end of file diff --git a/interfaces/DTokenInterface.sol b/interfaces/DTokenInterface.sol index 8e9ddc8..9869295 100644 --- a/interfaces/DTokenInterface.sol +++ b/interfaces/DTokenInterface.sol @@ -3,34 +3,60 @@ pragma solidity 0.5.11; /** * @title DTokenInterface * @author 0age - * @notice Interface for dTokens. + * @notice Interface for dTokens (in addition to the standard ERC20 interface). */ interface DTokenInterface { - // Events (similar to Compound's events) + // Events bear similarity to Compound's supply-related events. event Mint(address minter, uint256 mintAmount, uint256 mintDTokens); event Redeem(address redeemer, uint256 redeemAmount, uint256 redeemDTokens); event Accrue(uint256 dTokenExchangeRate, uint256 cTokenExchangeRate); event CollectSurplus(uint256 surplusAmount, uint256 surplusCTokens); - // external functions (trigger accrual) + // The block number and cToken + dToken exchange rates are updated on accrual. + struct AccrualIndex { + uint112 dTokenExchangeRate; + uint112 cTokenExchangeRate; + uint32 block; + } + + // These external functions trigger accrual on the dToken and backing cToken. function mint(uint256 underlyingToSupply) external returns (uint256 dTokensMinted); - function mintViaCToken(uint256 cTokensToSupply) external returns (uint256 dTokensMinted); function redeem(uint256 dTokensToBurn) external returns (uint256 underlyingReceived); + function redeemUnderlying(uint256 underlyingToReceive) external returns (uint256 dTokensBurned); + function pullSurplus() external returns (uint256 cTokenSurplus); + + // These external functions only trigger accrual on the dToken. + function mintViaCToken(uint256 cTokensToSupply) external returns (uint256 dTokensMinted); function redeemToCToken(uint256 dTokensToBurn) external returns (uint256 cTokensReceived); - function redeemUnderlying(uint256 underelyingToReceive) external returns (uint256 dTokensBurned); function redeemUnderlyingToCToken(uint256 underlyingToReceive) external returns (uint256 dTokensBurned); - function transferUnderlying(address recipient, uint256 amount) external returns (bool); - function transferUnderlyingFrom(address sender, address recipient, uint256 amount) external returns (bool); - function pullSurplus() external returns (uint256 cTokenSurplus); function accrueInterest() external; + function transferUnderlying(address recipient, uint256 underlyingEquivalentAmount) external returns (bool success); + function transferUnderlyingFrom(address sender, address recipient, uint256 underlyingEquivalentAmount) external returns (bool success); - // view functions (do not trigger accrual) + // This function provides basic meta-tx support and does not trigger accrual. + function modifyAllowanceViaMetaTransaction( + address owner, + address spender, + uint256 value, + bool increase, + uint256 expiration, + bytes32 salt, + bytes calldata signatures + ) external returns (bool success); + + // View and pure functions do not trigger accrual on the dToken or the cToken. + function getMetaTransactionMessageHash( + bytes4 functionSelector, bytes calldata arguments, uint256 expiration, bytes32 salt + ) external view returns (bytes32 digest, bool valid); function totalSupplyUnderlying() external view returns (uint256); function balanceOfUnderlying(address account) external view returns (uint256 underlyingBalance); - function getSurplus() external view returns (uint256 cTokenSurplus); - function getSurplusUnderlying() external view returns (uint256 underlyingSurplus); function exchangeRateCurrent() external view returns (uint256 dTokenExchangeRate); function supplyRatePerBlock() external view returns (uint256 dTokenInterestRate); + function accrualBlockNumber() external view returns (uint256 blockNumber); + function getSurplus() external view returns (uint256 cTokenSurplus); + function getSurplusUnderlying() external view returns (uint256 underlyingSurplus); function getSpreadPerBlock() external view returns (uint256 rateSpread); function getVersion() external pure returns (uint256 version); + function getCToken() external pure returns (address cToken); + function getUnderlying() external pure returns (address underlying); } \ No newline at end of file diff --git a/interfaces/ERC1271Interface.sol b/interfaces/ERC1271Interface.sol new file mode 100644 index 0000000..a14fd0c --- /dev/null +++ b/interfaces/ERC1271Interface.sol @@ -0,0 +1,8 @@ +pragma solidity 0.5.11; + + +interface ERC1271Interface { + function isValidSignature( + bytes calldata data, bytes calldata signature + ) external view returns (bytes4 magicValue); +} \ No newline at end of file diff --git a/interfaces/ERC20Interface.sol b/interfaces/ERC20Interface.sol new file mode 100644 index 0000000..fa9afe4 --- /dev/null +++ b/interfaces/ERC20Interface.sol @@ -0,0 +1,14 @@ +pragma solidity 0.5.11; + +interface ERC20Interface { + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); + + function transfer(address recipient, uint256 amount) external returns (bool); + function allowance(address owner, address spender) external view returns (uint256); + function approve(address spender, uint256 amount) external returns (bool); + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); + + function totalSupply() external view returns (uint256); + function balanceOf(address account) external view returns (uint256); +} diff --git a/interfaces/PotInterface.sol b/interfaces/PotInterface.sol new file mode 100644 index 0000000..7af173d --- /dev/null +++ b/interfaces/PotInterface.sol @@ -0,0 +1,9 @@ +pragma solidity 0.5.11; + + +interface PotInterface { + function chi() external view returns (uint256); + function dsr() external view returns (uint256); + function rho() external view returns (uint256); + function pie(address account) external view returns (uint256); +} \ No newline at end of file diff --git a/scripts/test/constants.js b/scripts/test/constants.js index c0dc4a9..d158ebd 100644 --- a/scripts/test/constants.js +++ b/scripts/test/constants.js @@ -366,6 +366,9 @@ module.exports = Object.freeze({ DHARMA_SMART_WALLET_IMPLEMENTATION_V5_METADATA: ( ['446861726d61536d61727457616c6c6574496d706c656d656e746174696f6e35'] ), + DHARMA_SMART_WALLET_IMPLEMENTATION_V7_METADATA: ( + ['446861726d61536d61727457616c6c6574496d706c656d656e746174696f6e37'] + ), ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS: ( '0x00000000009f22dA6fEB6735614563B9Af0339fB' ), diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index 5524843..5a1a100 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -34,6 +34,8 @@ const DharmaSmartWalletImplementationV2Artifact = require('../../build/contracts //const DharmaSmartWalletImplementationV3Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV3.json') //const DharmaSmartWalletImplementationV4Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV4.json') const DharmaSmartWalletImplementationV5Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV5.json') +const DharmaSmartWalletImplementationV6Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV6.json') +const DharmaSmartWalletImplementationV7Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV7.json') //const DharmaKeyRingImplementationV0Artifact = require('../../build/contracts/DharmaKeyRingImplementationV0.json') const DharmaKeyRingImplementationV1Artifact = require('../../build/contracts/DharmaKeyRingImplementationV1.json') @@ -129,19 +131,19 @@ module.exports = {test: async function (provider, testingContext) { let gasUsage = {} let counts = {} - + /* console.log( swapMetadataHash( - DharmaUSDCArtifact.bytecode, - constants.DHARMA_USDC_METADATA + DharmaSmartWalletImplementationV7Artifact.bytecode, + constants.DHARMA_SMART_WALLET_IMPLEMENTATION_V7_METADATA ), web3.utils.keccak256(swapMetadataHash( - DharmaUSDCArtifact.bytecode, - constants.DHARMA_USDC_METADATA + DharmaSmartWalletImplementationV7Artifact.bytecode, + constants.DHARMA_SMART_WALLET_IMPLEMENTATION_V7_METADATA ), {encoding: 'hex'}) ) process.exit(0) - + */ const DharmaUpgradeBeaconController = new web3.eth.Contract( DharmaUpgradeBeaconControllerArtifact.abi, From 643e8f3c1e3c17c165872380bbde5d9f97a52d18 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Thu, 6 Feb 2020 12:53:57 -0500 Subject: [PATCH 07/47] use defensive balanceOf and externalize revert reasons --- .solcover.js | 7 + .../SmartWalletRevertReasonHelperV1.sol | 49 + .../DharmaSmartWalletImplementationV7.sol | 213 +- scripts/test/constants.js | 1 + scripts/test/deploy.js | 113 + scripts/test/test.js | 3076 ++++++++++++++++- 6 files changed, 3225 insertions(+), 234 deletions(-) create mode 100644 contracts/helpers/SmartWalletRevertReasonHelperV1.sol diff --git a/.solcover.js b/.solcover.js index f576192..34837de 100644 --- a/.solcover.js +++ b/.solcover.js @@ -29,6 +29,13 @@ module.exports = { 'implementations/smart-wallet/DharmaSmartWalletImplementationV6.sol', //'implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol' 'implementations/smart-wallet/DharmaSmartWalletImplementationVX.sol', + 'implementations/token/DharmaDaiImplementationV1.sol', + 'implementations/token/DharmaDaiInitializer.sol', + 'implementations/token/DharmaTokenHelpers.sol', + 'implementations/token/DharmaTokenOverrides.sol', + 'implementations/token/DharmaTokenV1.sol', + 'implementations/token/DharmaUSDCImplementationV1.sol', + 'implementations/token/DharmaUSDCInitializer.sol', 'mock/MockSaiToDaiMigrator.sol', 'mock/MockCodeCheck.sol', 'mock/RelayContract.sol', diff --git a/contracts/helpers/SmartWalletRevertReasonHelperV1.sol b/contracts/helpers/SmartWalletRevertReasonHelperV1.sol new file mode 100644 index 0000000..bce98ed --- /dev/null +++ b/contracts/helpers/SmartWalletRevertReasonHelperV1.sol @@ -0,0 +1,49 @@ +pragma solidity 0.5.11; + + +/** + * @title SmartWalletRevertReasonHelperV1 + * @author 0age + * @notice This contract takes revert reason "codes" and returns revert reason + * strings for use in handling failures on the Dharma Smart Wallet. + */ +contract SmartWalletRevertReasonHelperV1 { + /** + * @notice Pure function to retrieve a revert reason string for a given code. + * @param code uint256 The code for the revert reason. + * @return A string with the revert reason. + */ + function reason(uint256 code) external pure returns (string memory) { + if (code == 0) return "Insufficient Dai supplied."; + if (code == 1) return "No recipient supplied."; + if (code == 2) return "Could not transfer Dai."; + if (code == 3) return "Insufficient USDC supplied."; + if (code == 4) return "Must supply a non-zero amount of Ether."; + if (code == 5) return "Must supply an escape hatch account."; + if (code == 6) return "No escape hatch is currently set for this smart wallet."; + if (code == 7) return "Only the escape hatch account may call this function."; + if (code == 8) return "Only the account recovery manager may call this function."; + if (code == 9) return "cSai redeem failed."; + if (code == 10) return "Dai approval failed."; + if (code == 11) return "Must supply two 65-byte signatures."; + if (code == 12) return "Verification failed - invalid user signature."; + if (code == 13) return "Verification failed - invalid Dharma signature."; + if (code == 14) return "No user signing key provided."; + if (code == 15) return "Sai approval failed."; + if (code == 16) return "Exchange rate cannot be below 1:1."; + if (code == 17) return "DAI contract reverted on approval."; + if (code == 18) return "Recipient rejected ether transfer."; + if (code == 19) return "Invalid action - insufficient gas supplied by transaction submitter."; + if (code == 20) return "Invalid action - invalid user signature."; + if (code == 21) return "Invalid action - invalid Dharma signature."; + if (code == 22) return "Invalid action - invalid signature."; + if (code == 23) return "CToken approval failed."; + if (code == 24) return "Failed to mint any dTokens using the cToken balance on this contract."; + if (code == 25) return "External accounts or unapproved internal functions cannot call this."; + if (code == 26) return "Invalid `to` parameter - must supply a contract address containing code."; + if (code == 27) return "Invalid `to` parameter - cannot supply the address of this contract."; + if (code == 28) return "Invalid `to` parameter - cannot supply the Dharma Escape Hatch Registry."; + if (code == 29) return "Invalid custom action type."; + return "(no revert reason)"; + } +} \ No newline at end of file diff --git a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol index d270a09..4ad7a83 100644 --- a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol +++ b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol @@ -18,6 +18,7 @@ import "../../../interfaces/DharmaKeyRegistryInterface.sol"; import "../../../interfaces/DharmaEscapeHatchRegistryInterface.sol"; import "../../../interfaces/ERC1271.sol"; import "../../../interfaces/SaiToDaiMigratorInterface.sol"; +import "../../helpers/SmartWalletRevertReasonHelperV1.sol"; /** @@ -127,6 +128,10 @@ contract DharmaSmartWalletImplementationV7 is 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 // mainnet ); + SmartWalletRevertReasonHelperV1 internal constant _REVERT_REASON_HELPER = ( + SmartWalletRevertReasonHelperV1(0x13821c0129FB9e2CC16dE2660783Ff4E4861e92d) + ); + // Compound returns a value of 0 to indicate success, or lack of an error. uint256 internal constant _COMPOUND_SUCCESS = 0; @@ -272,10 +277,10 @@ contract DharmaSmartWalletImplementationV7 is ); // Ensure that an amount of at least 0.001 Dai has been supplied. - require(amount > _JUST_UNDER_ONE_1000th_DAI, "Insufficient Dai supplied."); + require(amount > _JUST_UNDER_ONE_1000th_DAI, _revertReason(0)); // Ensure that a non-zero recipient has been supplied. - require(recipient != address(0), "No recipient supplied."); + require(recipient != address(0), _revertReason(1)); // Set the self-call context in order to call _withdrawDaiAtomic. _selfCallContext = this.withdrawDai.selector; @@ -292,7 +297,7 @@ contract DharmaSmartWalletImplementationV7 is // If the atomic call failed, emit an event signifying a transfer failure. if (!ok) { - emit ExternalError(address(_DAI), "Could not transfer Dai."); + emit ExternalError(address(_DAI), _revertReason(2)); } else { // Set ok to false if the call succeeded but the withdrawal failed. ok = abi.decode(returnData, (bool)); @@ -388,10 +393,10 @@ contract DharmaSmartWalletImplementationV7 is ); // Ensure that an amount of at least 0.001 USDC has been supplied. - require(amount > _JUST_UNDER_ONE_1000th_USDC, "Insufficient USDC supplied."); + require(amount > _JUST_UNDER_ONE_1000th_USDC, _revertReason(3)); // Ensure that a non-zero recipient has been supplied. - require(recipient != address(0), "No recipient supplied."); + require(recipient != address(0), _revertReason(1)); // Set the self-call context in order to call _withdrawUSDCAtomic. _selfCallContext = this.withdrawUSDC.selector; @@ -491,10 +496,10 @@ contract DharmaSmartWalletImplementationV7 is ); // Ensure that a non-zero amount of Ether has been supplied. - require(amount > 0, "Must supply a non-zero amount of Ether."); + require(amount > 0, _revertReason(4)); // Ensure that a non-zero recipient has been supplied. - require(recipient != address(0), "No recipient supplied."); + require(recipient != address(0), _revertReason(1)); // Attempt to transfer Ether to the recipient and emit an appropriate event. ok = _transferETH(recipient, amount); @@ -677,7 +682,7 @@ contract DharmaSmartWalletImplementationV7 is ); // Ensure that an escape hatch account has been provided. - require(account != address(0), "Must supply an escape hatch account."); + require(account != address(0), _revertReason(5)); // Set a new escape hatch for the smart wallet unless it has been disabled. _ESCAPE_HATCH_REGISTRY.setEscapeHatch(account); @@ -775,13 +780,10 @@ contract DharmaSmartWalletImplementationV7 is (bool exists, address escapeHatch) = _ESCAPE_HATCH_REGISTRY.getEscapeHatch(); // Ensure that an escape hatch is currently set for this smart wallet. - require(exists, "No escape hatch is currently set for this smart wallet."); + require(exists, _revertReason(6)); // Ensure that the escape hatch account is the caller. - require( - msg.sender == escapeHatch, - "Only the escape hatch account may call this function." - ); + require(msg.sender == escapeHatch, _revertReason(7)); // Attempt to redeem all dDai for Dai on Dharma Dai. _withdrawMaxFromDharmaToken(AssetType.DAI); @@ -831,10 +833,7 @@ contract DharmaSmartWalletImplementationV7 is * smart wallet. */ function recover(address newUserSigningKey) external { - require( - msg.sender == _ACCOUNT_RECOVERY_MANAGER, - "Only the account recovery manager may call this function." - ); + require(msg.sender == _ACCOUNT_RECOVERY_MANAGER, _revertReason(8)); // Increment nonce to prevent signature reuse should original key be reset. _nonce++; @@ -869,9 +868,7 @@ contract DharmaSmartWalletImplementationV7 is uint256 currentSaiBalance = _SAI.balanceOf(address(this)); // Redeem underlying balance from cSai and revert if unsuccessful. - require( - _CSAI.redeem(redeemAmount) == _COMPOUND_SUCCESS, "cSai redeem failed." - ); + require(_CSAI.redeem(redeemAmount) == _COMPOUND_SUCCESS, _revertReason(9)); // Calculate difference between pre-redeem and post-redeem Sai balances. uint256 saiBalance = _SAI.balanceOf(address(this)) - currentSaiBalance; @@ -881,9 +878,7 @@ contract DharmaSmartWalletImplementationV7 is // If the dDai allowance is insufficient, set it before depositing. if (_DAI.allowance(address(this), address(_DDAI)) < daiBalance) { - require( - _DAI.approve(address(_DDAI), uint256(-1)), "Dai approval failed." - ); + require(_DAI.approve(address(_DDAI), uint256(-1)), _revertReason(10)); } // Deposit the new Dai balance on Dharma Dai. @@ -1130,7 +1125,7 @@ contract DharmaSmartWalletImplementationV7 is } // Get user signature & Dharma signature from combined signatures argument. - require(signatures.length == 130, "Must supply two 65-byte signatures."); + require(signatures.length == 130, _revertReason(11)); bytes memory signaturesInMemory = signatures; bytes32 r; bytes32 s; @@ -1158,13 +1153,13 @@ contract DharmaSmartWalletImplementationV7 is _userSigningKey, userSignature ), - "Verification failed - invalid user signature." + _revertReason(12) ); // Recover Dharma signature against key returned from Dharma Key Registry. require( _getDharmaSigningKey() == digest.recover(dharmaSignature), - "Verification failed - invalid Dharma signature." + _revertReason(13) ); // Return the ERC-1271 magic value to indicate success. @@ -1416,7 +1411,7 @@ contract DharmaSmartWalletImplementationV7 is */ function _setUserSigningKey(address userSigningKey) internal { // Ensure that a user signing key is set on this smart wallet. - require(userSigningKey != address(0), "No user signing key provided."); + require(userSigningKey != address(0), _revertReason(14)); _userSigningKey = userSigningKey; emit NewUserSigningKey(userSigningKey); @@ -1438,7 +1433,7 @@ contract DharmaSmartWalletImplementationV7 is if (saiToSwap > allowance) { // Approve migrator contract to transfer Sai on behalf of this wallet. require( - _SAI.approve(address(_MIGRATOR), uint256(-1)), "Sai approval failed." + _SAI.approve(address(_MIGRATOR), uint256(-1)), _revertReason(15) ); } @@ -1452,7 +1447,7 @@ contract DharmaSmartWalletImplementationV7 is dai = _DAI.balanceOf(address(this)) - currentDaiBalance; // Ensure that the Sai-to-Dai exchange rate was at least 1-to-1. - require(dai >= saiToSwap, "Exchange rate cannot be below 1:1."); + require(dai >= saiToSwap, _revertReason(16)); } else { // Explicitly specify a change in balance of zero if no swap occurred. dai = 0; @@ -1487,7 +1482,7 @@ contract DharmaSmartWalletImplementationV7 is // Emit a corresponding event if the approval failed. if (!ok) { if (asset == AssetType.DAI) { - emit ExternalError(address(_DAI), "DAI contract reverted on approval."); + emit ExternalError(address(_DAI), _revertReason(17)); } else { // Find out why USDC transfer reverted (it doesn't give revert reasons). _diagnoseAndEmitUSDCSpecificError(_USDC.approve.selector); @@ -1568,13 +1563,26 @@ contract DharmaSmartWalletImplementationV7 is // Get dToken address for the asset type. (No custom ETH withdrawal action.) address dToken = asset == AssetType.DAI ? address(_DDAI) : address(_DUSDC); - // Get the current dToken balance for this account. - uint256 redeemAmount = IERC20(dToken).balanceOf(address(this)); + // Try to retrieve the current dToken balance for this account. + IERC20 dTokenBalance; + (bool ok, bytes memory data) = dToken.call(abi.encodeWithSelector( + dTokenBalance.balanceOf.selector, address(this) + )); + + uint256 redeemAmount = 0; + if (ok && data.length == 32) { + redeemAmount = abi.decode(data, (uint256)); + } else { + // Something went wrong with the balance check - log an ExternalError. + _checkDharmaTokenInteractionAndLogAnyErrors( + asset, dTokenBalance.balanceOf.selector, ok, data + ); + } // Only perform the call to redeem if there is a non-zero balance. if (redeemAmount > 0) { // Attempt to redeem the underlying balance from the dToken contract. - (bool ok, bytes memory data) = dToken.call(abi.encodeWithSelector( + (ok, data) = dToken.call(abi.encodeWithSelector( // Function selector is the same for all dTokens, so just use dDai's. _DDAI.redeem.selector, redeemAmount )); @@ -1604,24 +1612,38 @@ contract DharmaSmartWalletImplementationV7 is IERC20 token, address recipient, bool suppressRevert ) internal returns (bool success) { // Get the current balance on the smart wallet for the supplied ERC20 token. - uint256 transferAmount = token.balanceOf(address(this)); + uint256 balance = 0; + bool balanceCheckWorked = true; + if (!suppressRevert) { + balance = token.balanceOf(address(this)); + } else { + // Try to retrieve current token balance for this account with 1/2 gas. + (bool ok, bytes memory data) = address(token).call.gas(gasleft() / 2)( + abi.encodeWithSelector(token.balanceOf.selector, address(this)) + ); + + if (ok && data.length == 32) { + balance = abi.decode(data, (uint256)); + } else { + // Something went wrong with the balance check. + balanceCheckWorked = false; + } + } // Only perform the call to transfer if there is a non-zero balance. - if (transferAmount > 0) { + if (balance > 0) { if (!suppressRevert) { // Perform the transfer and pass along the returned boolean (or revert). - success = token.transfer(recipient, transferAmount); + success = token.transfer(recipient, balance); } else { // Attempt transfer with 1/2 gas, allow reverts, and return call status. (success, ) = address(token).call.gas(gasleft() / 2)( - abi.encodeWithSelector( - token.transfer.selector, recipient, transferAmount - ) + abi.encodeWithSelector(token.transfer.selector, recipient, balance) ); } } else { - // Skip the transfer and return true. - success = true; + // Skip the transfer and return true as long as the balance check worked. + success = balanceCheckWorked; } } @@ -1640,7 +1662,7 @@ contract DharmaSmartWalletImplementationV7 is // Attempt to transfer any Ether to caller and emit an event if it fails. (success, ) = recipient.call.gas(_ETH_TRANSFER_GAS).value(amount)(""); if (!success) { - emit ExternalError(recipient, "Recipient rejected ether transfer."); + emit ExternalError(recipient, _revertReason(18)); } else { emit EthWithdrawal(amount, recipient); } @@ -1690,10 +1712,7 @@ contract DharmaSmartWalletImplementationV7 is // ~30,000 additional gas should suffice when submitting transactions. To // skip this requirement, supply zero for the minimumActionGas argument. if (minimumActionGas != 0) { - require( - gasleft() >= minimumActionGas, - "Invalid action - insufficient gas supplied by transaction submitter." - ); + require(gasleft() >= minimumActionGas, _revertReason(19)); } // Get the current nonce for the action to be performed. @@ -1726,7 +1745,7 @@ contract DharmaSmartWalletImplementationV7 is _validateUserSignature( messageHash, action, arguments, userSigningKey, userSignature ), - "Invalid action - invalid user signature." + _revertReason(20) ); } @@ -1734,7 +1753,7 @@ contract DharmaSmartWalletImplementationV7 is if (msg.sender != dharmaSigningKey) { require( dharmaSigningKey == messageHash.recover(dharmaSignature), - "Invalid action - invalid Dharma signature." + _revertReason(21) ); } } else { @@ -1745,7 +1764,7 @@ contract DharmaSmartWalletImplementationV7 is _validateUserSignature( messageHash, action, arguments, userSigningKey, userSignature ), - "Invalid action - invalid signature." + _revertReason(22) ); } } @@ -1779,13 +1798,11 @@ contract DharmaSmartWalletImplementationV7 is if (balance > 0) { // If the allowance is insufficient, set it before depositing. if (cToken.allowance(address(this), address(dToken)) < balance) { - require( - cToken.approve(address(dToken), uint256(-1)), "Approval failed." - ); + require(cToken.approve(address(dToken), uint256(-1)), _revertReason(23)); } // Deposit the new balance on the Dharma Token. - dToken.mintViaCToken(balance); + require(dToken.mintViaCToken(balance) > 0, _revertReason(24)); } } @@ -1810,7 +1827,47 @@ contract DharmaSmartWalletImplementationV7 is ) internal returns (bool success) { // Log an external error if something went wrong with the attempt. if (ok) { - success = true; + if (data.length == 32) { + uint256 amount = abi.decode(data, (uint256)); + if (amount > 0) { + success = true; + } else { + // Get called contract address, name of contract, and function name. + (address account, string memory name, string memory functionName) = ( + _getDharmaTokenDetails(asset, functionSelector) + ); + + emit ExternalError( + account, + string( + abi.encodePacked( + name, + " contract did not provide any tokens when calling ", + functionName, + "." + ) + ) + ); + } + } else { + // Get called contract address, name of contract, and function name. + (address account, string memory name, string memory functionName) = ( + _getDharmaTokenDetails(asset, functionSelector) + ); + + emit ExternalError( + account, + string( + abi.encodePacked( + name, + " contract returned malformed data while attempting to call ", + functionName, + "." + ) + ) + ); + } + } else { // Get called contract address, name of contract, and function name. (address account, string memory name, string memory functionName) = ( @@ -1897,9 +1954,8 @@ contract DharmaSmartWalletImplementationV7 is function _enforceSelfCallFrom(bytes4 selfCallContext) internal { // Ensure caller is this contract and self-call context is correctly set. require( - msg.sender == address(this) && - _selfCallContext == selfCallContext, - "External accounts or unapproved internal functions cannot call this." + msg.sender == address(this) && _selfCallContext == selfCallContext, + _revertReason(25) ); // Clear the self-call context. @@ -2034,10 +2090,14 @@ contract DharmaSmartWalletImplementationV7 is if (functionSelector == _DDAI.mint.selector) { functionName = "mint"; } else { - functionName = string(abi.encodePacked( - "redeem", - functionSelector == _DDAI.redeemUnderlying.selector ? "Underlying" : "" - )); + if (functionSelector == IERC20(account).balanceOf.selector) { + functionName = "balanceOf"; + } else { + functionName = string(abi.encodePacked( + "redeem", + functionSelector == _DDAI.redeem.selector ? "" : "Underlying" + )); + } } } @@ -2050,20 +2110,11 @@ contract DharmaSmartWalletImplementationV7 is * @param to address The address that will be targeted by the generic call. */ function _ensureValidGenericCallTarget(address to) internal view { - require( - to.isContract(), - "Invalid `to` parameter - must supply a contract address containing code." - ); + require(to.isContract(), _revertReason(26)); - require( - to != address(this), - "Invalid `to` parameter - cannot supply the address of this contract." - ); + require(to != address(this), _revertReason(27)); - require( - to != address(_ESCAPE_HATCH_REGISTRY), - "Invalid `to` parameter - cannot supply the Dharma Escape Hatch Registry." - ); + require(to != address(_ESCAPE_HATCH_REGISTRY), _revertReason(28)); } /** @@ -2095,7 +2146,7 @@ contract DharmaSmartWalletImplementationV7 is action == ActionType.SetEscapeHatch || action == ActionType.RemoveEscapeHatch || action == ActionType.DisableEscapeHatch, - "Invalid custom action type." + _revertReason(29) ); // Use action type to determine parameters to include in returned arguments. @@ -2145,7 +2196,19 @@ contract DharmaSmartWalletImplementationV7 is revertReason = abi.decode(revertReasonBytes, (string)); } else { // Simply return the default, with no revert reason. - revertReason = "(no revert reason)"; + revertReason = _revertReason(30); } } + + /** + * @notice Internal pure function call the revert reason helper contract, + * supplying a revert "code" and receiving back a revert reason string. + * @param code uint256 The code for the revert reason. + * @return The revert reason string. + */ + function _revertReason( + uint256 code + ) internal pure returns (string memory reason) { + reason = _REVERT_REASON_HELPER.reason(code); + } } \ No newline at end of file diff --git a/scripts/test/constants.js b/scripts/test/constants.js index d158ebd..d1949c6 100644 --- a/scripts/test/constants.js +++ b/scripts/test/constants.js @@ -402,6 +402,7 @@ module.exports = Object.freeze({ INDESTRUCTIBLE_REGISTRY_RUNTIME_HASH: ( '0xadca137a47625f8ad1da20be107380101474374dc6c31ad0b8c1807558ea3c29' ), + REVERT_REASON_HELPER_ADDRESS: '0x13821c0129FB9e2CC16dE2660783Ff4E4861e92d', INDESTRUCTIBLE_REGISTRY_CREATION_TX: ( '0x64e030870000000000000000000000000000000000000000a4ab82b860e6cb06780400' + '000000000000000000000000000000000000000000000000000000000000000040000000' + diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index 5a1a100..a0438a3 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -21,6 +21,7 @@ let DharmaKeyRingFactoryV2Artifact; let DharmaEscapeHatchRegistryArtifact; let DharmaDaiArtifact; let DharmaUSDCArtifact; +let SmartWalletRevertReasonHelperV1Artifact; const DharmaUpgradeMultisigArtifact = require('../../build/contracts/DharmaUpgradeMultisig.json') const DharmaAccountRecoveryMultisigArtifact = require('../../build/contracts/DharmaAccountRecoveryMultisig.json') @@ -104,6 +105,7 @@ module.exports = {test: async function (provider, testingContext) { DharmaEscapeHatchRegistryArtifact = require('../../../build/contracts/DharmaEscapeHatchRegistry.json') DharmaDaiArtifact = require('../../../build/contracts/DharmaDai.json') DharmaUSDCArtifact = require('../../../build/contracts/DharmaUSDC.json') + SmartWalletRevertReasonHelperV1Artifact = require('../../../build/contracts/SmartWalletRevertReasonHelperV1.json') } else { DharmaUpgradeBeaconEnvoyArtifact = require('../../build/contracts/DharmaUpgradeBeaconEnvoy.json') DharmaUpgradeBeaconControllerArtifact = require('../../build/contracts/DharmaUpgradeBeaconController.json') @@ -123,6 +125,7 @@ module.exports = {test: async function (provider, testingContext) { DharmaEscapeHatchRegistryArtifact = require('../../build/contracts/DharmaEscapeHatchRegistry.json') DharmaDaiArtifact = require('../../build/contracts/DharmaDai.json') DharmaUSDCArtifact = require('../../build/contracts/DharmaUSDC.json') + SmartWalletRevertReasonHelperV1Artifact = require('../../build/contracts/SmartWalletRevertReasonHelperV1.json') } var web3 = provider @@ -200,6 +203,11 @@ module.exports = {test: async function (provider, testingContext) { constants.INDESTRUCTIBLE_REGISTRY_ADDRESS ) + const SmartWalletRevertReasonHelperV1 = new web3.eth.Contract( + SmartWalletRevertReasonHelperV1Artifact.abi, + constants.REVERT_REASON_HELPER_ADDRESS + ) + const IndestructibleRegistryDeployer = new web3.eth.Contract( IndestructibleRegistryArtifact.abi ) @@ -430,6 +438,26 @@ module.exports = {test: async function (provider, testingContext) { ) ) + const DharmaSmartWalletImplementationV6Deployer = new web3.eth.Contract( + DharmaSmartWalletImplementationV6Artifact.abi + ) + DharmaSmartWalletImplementationV6Deployer.options.data = ( + swapMetadataHash( + DharmaSmartWalletImplementationV6Artifact.bytecode, + ['0000000000000000000000000000000000000000000000000000000000000000'] + ) + ) + + const DharmaSmartWalletImplementationV7Deployer = new web3.eth.Contract( + DharmaSmartWalletImplementationV7Artifact.abi + ) + DharmaSmartWalletImplementationV7Deployer.options.data = ( + swapMetadataHash( + DharmaSmartWalletImplementationV7Artifact.bytecode, + ['0000000000000000000000000000000000000000000000000000000000000000'] + ) + ) + /* const DharmaKeyRingImplementationV0Deployer = new web3.eth.Contract( DharmaKeyRingImplementationV0Artifact.abi @@ -1623,6 +1651,61 @@ module.exports = {test: async function (provider, testingContext) { } ) + let currentRevertReasonHelperCode; + await runTest( + 'Checking Revert Reason Helper runtime code', + MockCodeCheck, + 'code', + 'call', + [constants.REVERT_REASON_HELPER_ADDRESS], + true, + value => { + currentRevertReasonHelperCode = value; + } + ) + + if ( + currentRevertReasonHelperCode !== SmartWalletRevertReasonHelperV1Artifact.deployedBytecode + ) { + await runTest( + `SmartWalletRevertReasonHelperV1 Code contract address check through immutable create2 factory`, + ImmutableCreate2Factory, + 'findCreate2Address', + 'call', + [ + constants.NULL_BYTES_32, + SmartWalletRevertReasonHelperV1Artifact.bytecode + ], + true, + value => { + assert.strictEqual(value, constants.REVERT_REASON_HELPER_ADDRESS) + } + ) + + await runTest( + `SmartWalletRevertReasonHelperV1 contract deployment through immutable create2 factory`, + ImmutableCreate2Factory, + 'safeCreate2', + 'send', + [ + constants.NULL_BYTES_32, + SmartWalletRevertReasonHelperV1Artifact.bytecode + ] + ) + } + + await runTest( + 'Deployed Revert Reason Helper code is correct', + MockCodeCheck, + 'code', + 'call', + [SmartWalletRevertReasonHelperV1.options.address], + true, + value => { + assert.strictEqual(value, SmartWalletRevertReasonHelperV1Artifact.deployedBytecode) + } + ) + let currentEscapeHatchRegistryCode; await runTest( 'Checking Escape Hatch Registry runtime code', @@ -1734,6 +1817,20 @@ module.exports = {test: async function (provider, testingContext) { 'deploy' ) + const DharmaSmartWalletImplementationV6 = await runTest( + `DharmaSmartWalletImplementationV6 contract deployment`, + DharmaSmartWalletImplementationV6Deployer, + '', + 'deploy' + ) + + const DharmaSmartWalletImplementationV7 = await runTest( + `DharmaSmartWalletImplementationV7 contract deployment`, + DharmaSmartWalletImplementationV7Deployer, + '', + 'deploy' + ) + /* const DharmaKeyRingImplementationV0 = await runTest( `DharmaKeyRingImplementationV0 contract deployment`, @@ -2470,6 +2567,22 @@ module.exports = {test: async function (provider, testingContext) { [DharmaSmartWalletImplementationV5.options.address] ) + await runTest( + 'IndestructibleRegistry can register V6 implementation as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [DharmaSmartWalletImplementationV6.options.address] + ) + + await runTest( + 'IndestructibleRegistry can register V7 implementation as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [DharmaSmartWalletImplementationV7.options.address] + ) + await runTest( 'IndestructibleRegistry can register V1 key ring implementation as indestructible', IndestructibleRegistry, diff --git a/scripts/test/test.js b/scripts/test/test.js index c4ea878..a8a1cc3 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -23,6 +23,7 @@ const DharmaSmartWalletImplementationV1Artifact = require('../../build/contracts const DharmaSmartWalletImplementationV2Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV2.json') const DharmaSmartWalletImplementationV5Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV5.json') const DharmaSmartWalletImplementationV6Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV6.json') +const DharmaSmartWalletImplementationV7Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV7.json') const DharmaKeyRingImplementationV1Artifact = require('../../build/contracts/DharmaKeyRingImplementationV1.json') const DharmaKeyRingFactoryV1Artifact = require('../../build/contracts/DharmaKeyRingFactoryV1.json') @@ -199,6 +200,13 @@ module.exports = {test: async function (provider, testingContext) { DharmaSmartWalletImplementationV6Artifact.bytecode ) + const DharmaSmartWalletImplementationV7Deployer = new web3.eth.Contract( + DharmaSmartWalletImplementationV7Artifact.abi + ) + DharmaSmartWalletImplementationV7Deployer.options.data = ( + DharmaSmartWalletImplementationV7Artifact.bytecode + ) + const AdharmaKeyRingImplementationDeployer = new web3.eth.Contract( AdharmaKeyRingImplementationArtifact.abi ) @@ -1104,6 +1112,13 @@ module.exports = {test: async function (provider, testingContext) { 'deploy' ) + const DharmaSmartWalletImplementationV7 = await runTest( + `DharmaSmartWalletImplementationV7 contract deployment`, + DharmaSmartWalletImplementationV7Deployer, + '', + 'deploy' + ) + const DharmaKeyRingImplementationV1 = await runTest( `DharmaKeyRingImplementationV1 contract deployment`, DharmaKeyRingImplementationV1Deployer, @@ -1672,6 +1687,11 @@ module.exports = {test: async function (provider, testingContext) { targetWalletAddress ) + const UserSmartWalletV7 = new web3.eth.Contract( + DharmaSmartWalletImplementationV7Artifact.abi, + targetWalletAddress + ) + await runTest( 'DharmaSmartWalletFactoryV1 gets a new smart wallet address with same key', DharmaSmartWalletFactoryV1, @@ -8113,9 +8133,6 @@ module.exports = {test: async function (provider, testingContext) { originalAddress ) - - - await runTest( 'V6 UserSmartWallet can get an escape hatch action ID', UserSmartWalletV6, @@ -8143,185 +8160,175 @@ module.exports = {test: async function (provider, testingContext) { addressTwo ) - await runTest( - 'V6 UserSmartWallet relay cannot set an escape hatch with no account', - UserSmartWalletV6, - 'setEscapeHatch', - 'send', - [ - constants.NULL_ADDRESS, - 0, - escapeHatchUserSignature, - escapeHatchSignature - ], - false, - receipt => { - // TODO: verify logs - }, - originalAddress - ) + // YYYYY await runTest( - 'V6 UserSmartWallet can get an escape hatch action ID', + 'UserSmartWalletV6 can get the nonce prior to upgrade', UserSmartWalletV6, - 'getNextCustomActionID', + 'getNonce', 'call', - [ - 7, // SetEscapeHatch, - 0, - address, - 0 - ], + [], true, value => { - customActionId = value + originalNonce = value } ) - escapeHatchSignature = signHashedPrefixedHexString( - customActionId, - address - ) - - escapeHatchUserSignature = signHashedPrefixedHexString( - customActionId, - addressTwo - ) - await runTest( - 'V6 UserSmartWallet cannot call escape before escape hatch is set', + 'UserSmartWalletV6 can check the user signing key prior to upgrade', UserSmartWalletV6, - 'escape', - 'send', + 'getUserSigningKey', + 'call', [], - false, - receipt => { - // TODO: verify logs + true, + value => { + assert.strictEqual(value, addressTwo) } ) await runTest( - 'V6 UserSmartWallet relay can set an escape hatch', - UserSmartWalletV6, - 'setEscapeHatch', + 'Dharma Upgrade Beacon Controller can upgrade to V7 implementation', + DharmaUpgradeBeaconController, + 'upgrade', 'send', [ - address, - 0, - escapeHatchUserSignature, - escapeHatchSignature + DharmaUpgradeBeacon.options.address, + DharmaSmartWalletImplementationV7.options.address ], true, receipt => { - // TODO: verify logs - }, - originalAddress + if (testingContext !== 'coverage') { + assert.strictEqual( + receipt.events.Upgraded.returnValues.upgradeBeacon, + DharmaUpgradeBeacon.options.address + ) + assert.strictEqual( + receipt.events.Upgraded.returnValues.oldImplementation, + DharmaSmartWalletImplementationV6.options.address + ) + /* TODO + assert.strictEqual( + receipt.events.Upgraded.returnValues.oldImplementationCodeHash, + constants.EMPTY_HASH + ) + */ + assert.strictEqual( + receipt.events.Upgraded.returnValues.newImplementation, + DharmaSmartWalletImplementationV7.options.address + ) + /* TODO + assert.strictEqual( + receipt.events.Upgraded.returnValues.newImplementationCodeHash, + ... + ) + */ + } + } ) await runTest( - 'V6 UserSmartWallet non-escape hatch account cannot call escape', - UserSmartWalletV6, - 'escape', - 'send', - [], - false, - receipt => { - // TODO: verify logs - }, - originalAddress + 'DharmaUpgradeBeacon has the implementation set', + DharmaUpgradeBeaconController, + 'getImplementation', + 'call', + [DharmaUpgradeBeacon.options.address], + true, + value => { + assert.strictEqual(value, DharmaSmartWalletImplementationV7.options.address) + } + ) + + const UpgradeBeaconImplementationCheckV7 = await runTest( + `UpgradeBeaconImplementationCheck deployment`, + UpgradeBeaconImplementationCheckDeployer, + '', + 'deploy', + [ + DharmaUpgradeBeacon.options.address, + DharmaSmartWalletImplementationV7.options.address + ] ) await runTest( - 'V6 UserSmartWallet escape hatch account can call escape', - UserSmartWalletV6, - 'escape', - 'send', + 'V7 user smart wallet can be called and still has the same dharma key set', + UserSmartWalletV7, + 'getUserSigningKey', + 'call', [], true, - receipt => { - // TODO: verify logs - }, - address + value => { + assert.strictEqual(value, addressTwo) + } ) await runTest( - 'V6 UserSmartWallet escape hatch account can call escape again', - UserSmartWalletV6, - 'escape', - 'send', + 'V7 UserSmartWallet can get the new version (7)', + UserSmartWalletV7, + 'getVersion', + 'call', [], true, - receipt => { - // TODO: verify logs - }, - address + value => { + assert.strictEqual(value, '7') + } ) await runTest( - 'V6 UserSmartWallet can get an escape hatch action ID', - UserSmartWalletV6, - 'getNextCustomActionID', + 'V7 UserSmartWallet nonce is still set to value from before upgrade', + UserSmartWalletV7, + 'getNonce', 'call', - [ - 8, // RemoveEscapeHatch, - 0, - constants.NULL_ADDRESS, - 0 - ], + [], true, value => { - customActionId = value + assert.strictEqual(value, originalNonce) } ) - escapeHatchSignature = signHashedPrefixedHexString( - customActionId, - address - ) - - escapeHatchUserSignature = signHashedPrefixedHexString( - customActionId, - addressTwo + await runTest( + 'V7 UserSmartWallet can get balances', + UserSmartWalletV7, + 'getBalances', + 'call', + [], + true, + value => { + //console.log(value) + } ) await runTest( - 'V6 UserSmartWallet relay can remove an escape hatch', - UserSmartWalletV6, - 'removeEscapeHatch', + 'V7 UserSmartWallet secondary can call to cancel', + UserSmartWalletV7, + 'cancel', 'send', [ 0, - escapeHatchUserSignature, - escapeHatchSignature - ], - true, - receipt => { - // TODO: verify logs - }, - originalAddress + '0x' + ] ) await runTest( - 'V6 UserSmartWallet cannot call escape once escape hatch is removed', - UserSmartWalletV6, - 'escape', - 'send', + 'V7 UserSmartWallet nonce is now set to original + 1', + UserSmartWalletV7, + 'getNonce', + 'call', [], - false, - receipt => { - // TODO: verify logs + true, + value => { + assert.strictEqual(value, (parseInt(originalNonce) + 1).toString()) } ) await runTest( - 'V6 UserSmartWallet can get an escape hatch action ID', - UserSmartWalletV6, + 'V7 UserSmartWallet can get next custom action ID to set a user signing key', + UserSmartWalletV7, 'getNextCustomActionID', 'call', [ - 9, // DisableEscapeHatch, - 0, - constants.NULL_ADDRESS, + 1, // SetUserSigningKey, + constants.FULL_APPROVAL, // This value shouldn't matter + addressTwo, 0 ], true, @@ -8330,27 +8337,54 @@ module.exports = {test: async function (provider, testingContext) { } ) - escapeHatchSignature = signHashedPrefixedHexString( + setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( customActionId, address ) - escapeHatchUserSignature = signHashedPrefixedHexString( - customActionId, - addressTwo - ) - await runTest( - 'V6 UserSmartWallet relay can disable the escape hatch', - UserSmartWalletV6, - 'permanentlyDisableEscapeHatch', + 'V7 UserSmartWallet can set a new user signing key with signatures', + UserSmartWalletV7, + 'setUserSigningKey', 'send', [ + addressTwo, 0, - escapeHatchUserSignature, - escapeHatchSignature + '0x', + setUserSigningKeyDharmaSignature ], true, + receipt => {}, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet has the new user signing key set', + UserSmartWalletV7, + 'getUserSigningKey', + 'call', + [], + true, + value => { + assert.strictEqual(value, addressTwo) + } + ) + + await runTest( + 'cSai can be sent to V7 UserSmartWallet', + CSAI, + 'transfer', + 'send', + [UserSmartWalletV7.options.address, web3.utils.toWei('0.5', 'mwei')] + ) + + await runTest( + 'V7 UserSmartWallet relay can trigger cSai to dDai migration before dDai approval', + UserSmartWalletV7, + 'migrateCSaiToDDai', + 'send', + [], + true, receipt => { // TODO: verify logs }, @@ -8358,13 +8392,13 @@ module.exports = {test: async function (provider, testingContext) { ) await runTest( - 'V6 UserSmartWallet can get an escape hatch action ID', - UserSmartWalletV6, + 'V7 UserSmartWallet can get next custom action ID', + UserSmartWalletV7, 'getNextCustomActionID', 'call', [ - 7, // SetEscapeHatch, - 0, + 0, // DAIWithdrawal + constants.FULL_APPROVAL, address, 0 ], @@ -8374,8 +8408,2489 @@ module.exports = {test: async function (provider, testingContext) { } ) - escapeHatchSignature = signHashedPrefixedHexString( - customActionId, + await runTest( + 'V7 UserSmartWallet can get custom action ID and it matches next action ID', + UserSmartWalletV7, + 'getCustomActionID', + 'call', + [ + 0, // DAIWithdrawal + constants.FULL_APPROVAL, + address, + parseInt(originalNonce) + 2, + 0 + ], + true, + value => { + assert.strictEqual(value, customActionId) + } + ) + + await runTest( + 'V7 UserSmartWallet can get next generic action ID', + UserSmartWalletV7, + 'getNextGenericActionID', + 'call', + [ + address, + '0x', + 0 + ], + true, + value => { + genericActionID = value + } + ) + + await runTest( + 'V7 UserSmartWallet can get generic action ID and it matches next action ID', + UserSmartWalletV7, + 'getGenericActionID', + 'call', + [ + address, + '0x', + parseInt(originalNonce) + 2, + 0 + ], + true, + value => { + assert.strictEqual(value, genericActionID) + } + ) + + await runTest( + 'UserSmartWallet calls to atomic methods revert', + UserSmartWalletV7, + '_withdrawDaiAtomic', + 'send', + [ + '1', + address + ], + false + ) + + // Give the Dai Whale some ETH so it can make transactions + await web3.eth.sendTransaction({ + from: address, + to: constants.DAI_WHALE_ADDRESS, + value: web3.utils.toWei('1', 'ether'), + gas: (testingContext !== 'coverage') ? '0xffff' : gasLimit - 1, + gasPrice: 1 + }) + + await runTest( + 'Dai Whale can deposit Dai into the V7 smart wallet', + DAI, + 'transfer', + 'send', + [targetWalletAddress, web3.utils.toWei('100', 'ether')], + true, + receipt => { + if (testingContext !== 'coverage') { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.DAI_WHALE_ADDRESS + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei('100', 'ether') + ) + } + }, + constants.DAI_WHALE_ADDRESS + ) + + await runTest( + 'USDC Whale can deposit usdc into the V7 smart wallet', + USDC, + 'transfer', + 'send', + [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals + true, + receipt => { + if (testingContext !== 'coverage') { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.USDC_WHALE_ADDRESS + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei('100', 'lovelace') + ) + } + }, + constants.USDC_WHALE_ADDRESS + ) + + await runTest( + 'V7 UserSmartWallet can get a generic action ID', + UserSmartWalletV7, + 'getNextGenericActionID', + 'call', + [ + DAI.options.address, + DAI.methods.approve(CDAI.options.address, 0).encodeABI(), + 0 + ], + true, + value => { + customActionId = value + } + ) + + executeActionSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + executeActionUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet can call executeAction', + UserSmartWalletV7, + 'executeAction', + 'send', + [ + DAI.options.address, + DAI.methods.approve(CDAI.options.address, 0).encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ) + + await runTest( + 'V7 user smart wallet can trigger repayAndDeposit to deposit all new funds', + UserSmartWalletV7, + 'repayAndDeposit', + 'send', + [], + true, + receipt => { + // TODO: validate + } + ) + + await runTest( + 'Dai Whale can deposit dai into the V7 smart wallet', + DAI, + 'transfer', + 'send', + [targetWalletAddress, web3.utils.toWei('100', 'ether')], + true, + receipt => { + if (testingContext !== 'coverage') { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.DAI_WHALE_ADDRESS + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei('100', 'ether') + ) + } + }, + constants.DAI_WHALE_ADDRESS + ) + + await runTest( + 'V7 UserSmartWallet can get a generic action ID', + UserSmartWalletV7, + 'getNextGenericActionID', + 'call', + [ + constants.ESCAPE_HATCH_REGISTRY_ADDRESS, + '0x', + 0 + ], + true, + value => { + customActionId = value + } + ) + + executeActionSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + executeActionUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet cannot call executeAction and target Escape Hatch Registry', + UserSmartWalletV7, + 'executeAction', + 'send', + [ + constants.ESCAPE_HATCH_REGISTRY_ADDRESS, + '0x', + 0, + executeActionUserSignature, + executeActionSignature + ], + false + ) + + await runTest( + 'V7 UserSmartWallet can get a generic action ID', + UserSmartWalletV7, + 'getNextGenericActionID', + 'call', + [ + DAI.options.address, + DAI.methods.approve(CDAI.options.address, 0).encodeABI(), + 0 + ], + true, + value => { + customActionId = value + } + ) + + executeActionSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + executeActionUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet can call executeAction', + UserSmartWalletV7, + 'executeAction', + 'send', + [ + DAI.options.address, + DAI.methods.approve(CDAI.options.address, 0).encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ) + + await runTest( + 'V7 user smart wallet repayAndDeposit can still deposit without approval', + UserSmartWalletV7, + 'repayAndDeposit', + 'send', + [], + true, + receipt => { + // TODO: validate + } + ) + + await runTest( + 'V7 UserSmartWallet can get a generic action ID', + UserSmartWalletV7, + 'getNextGenericActionID', + 'call', + [ + DAI.options.address, + DAI.methods.approve(CDAI.options.address, constants.FULL_APPROVAL).encodeABI(), + 0 + ], + true, + value => { + customActionId = value + } + ) + + executeActionSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + executeActionUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet can call executeAction', + UserSmartWalletV7, + 'executeAction', + 'send', + [ + DAI.options.address, + DAI.methods.approve(CDAI.options.address, constants.FULL_APPROVAL).encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ) + + await runTest( + 'V7 user smart wallet repayAndDeposit can deposit with approval added back', + UserSmartWalletV7, + 'repayAndDeposit', + 'send', + [], + true, + receipt => { + // TODO: validate + } + ) + + await runTest( + 'V7 user smart wallet can trigger repayAndDeposit even with no funds', + UserSmartWalletV7, + 'repayAndDeposit', + 'send', + [], + true, + receipt => { + // TODO: validate + } + ) + + await runTest( + 'V7 UserSmartWallet can get custom action ID and it matches next action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 1, // SetUserSigningKey, + 0, + constants.NULL_ADDRESS, + 0 + ], + true, + value => { + customActionId = value + } + ) + + setUserSigningKeyUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + await runTest( + 'V7 UserSmartWallet cannot set the null address as a new user signing key', + UserSmartWalletV7, + 'setUserSigningKey', + 'send', + [ + constants.NULL_ADDRESS, + 0, + setUserSigningKeyUserSignature, + setUserSigningKeyDharmaSignature + ], + false, + receipt => {}, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get next custom action ID to set a user signing key', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 1, // SetUserSigningKey, + constants.FULL_APPROVAL, // This value shouldn't matter + addressTwo, + 0 + ], + true, + value => { + customActionId = value + } + ) + + await runTest( + 'UserSmartWallet can get the nonce', + UserSmartWalletV7, + 'getNonce', + 'call', + [], + true, + value => { + currentNonce = value + } + ) + + await runTest( + 'V7 UserSmartWallet can get custom action ID and it matches next action ID', + UserSmartWalletV7, + 'getCustomActionID', + 'call', + [ + 1, // SetUserSigningKey, + 0, // Note that this value differs from above + addressTwo, + currentNonce, + 0 + ], + true, + value => { + assert.strictEqual(value, customActionId) + } + ) + + setUserSigningKeyUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + await runTest( + 'V7 UserSmartWallet can set a new user signing key with signatures', + UserSmartWalletV7, + 'setUserSigningKey', + 'send', + [ + addressTwo, + 0, + setUserSigningKeyUserSignature, + setUserSigningKeyDharmaSignature + ], + true, + receipt => {}, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get next custom action ID to cancel', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 0, // Cancel + constants.FULL_APPROVAL, // This value shouldn't matter + originalAddress, // This value shouldn't matter either + 0 + ], + true, + value => { + customActionId = value + } + ) + + await runTest( + 'UserSmartWallet can get the nonce', + UserSmartWalletV7, + 'getNonce', + 'call', + [], + true, + value => { + currentNonce = value + } + ) + + await runTest( + 'V7 UserSmartWallet can get custom action ID and it matches next action ID', + UserSmartWalletV7, + 'getCustomActionID', + 'call', + [ + 0, // Cancel + 0, // Note that this value differs from above + addressTwo, // This one too + currentNonce, + 0 + ], + true, + value => { + assert.strictEqual(value, customActionId) + } + ) + + cancelUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet secondary can cancel using a signature', + UserSmartWalletV7, + 'cancel', + 'send', + [ + 0, + cancelUserSignature + ], + true, + receipt => {}, + originalAddress + ) + + await runTest( + 'UserSmartWallet nonce is incremented after cancelling', + UserSmartWalletV7, + 'getNonce', + 'call', + [], + true, + value => { + assert.strictEqual(parseInt(value), parseInt(currentNonce) + 1) + } + ) + + await runTest( + 'V7 UserSmartWallet secondary cannot call to withdraw dai without primary', + UserSmartWalletV7, + 'withdrawDai', + 'send', + [ + '1000000000000000000', + address, + 0, + '0x', + '0x' + ], + false + ) + + await runTest( + 'V7 UserSmartWallet secondary cannot call to withdraw usdc without primary', + UserSmartWalletV7, + 'withdrawUSDC', + 'send', + [ + 1, + address, + 0, + '0x', + '0x' + ], + false + ) + + await runTest( + 'V7 UserSmartWallet secondary can no longer call to set userSigningKey without primary', + UserSmartWalletV7, + 'setUserSigningKey', + 'send', + [ + address, + 0, + '0x', + '0x' + ], + false + ) + + await runTest( + 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 5, // USDCWithdrawal, + '1', // dust + address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + usdcWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + usdcUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay cannot withdraw "dust" USDC', + UserSmartWalletV7, + 'withdrawUSDC', + 'send', + [ + '1', + address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 5, // USDCWithdrawal, + '100000', + constants.NULL_ADDRESS, // bad recipient + 0 + ], + true, + value => { + customActionId = value + } + ) + + usdcWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + usdcUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay cannot withdraw USDC to null address', + UserSmartWalletV7, + 'withdrawUSDC', + 'send', + [ + '100000', + constants.NULL_ADDRESS, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 5, // USDCWithdrawal, + '100000', + address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + usdcWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + usdcUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay can call with two signatures to withdraw USDC', + UserSmartWalletV7, + 'withdrawUSDC', + 'send', + [ + '100000', + address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 5, // USDCWithdrawal, + constants.FULL_APPROVAL, + address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + usdcWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + usdcUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay cannot call with bad signature to withdraw USDC', + UserSmartWalletV7, + 'withdrawUSDC', + 'send', + [ + constants.FULL_APPROVAL, + address, + 0, + usdcUserWithdrawalSignature, + '0xffffffff' + usdcWithdrawalSignature.slice(10) + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet cannot call with bad user signature to withdraw USDC', + UserSmartWalletV7, + 'withdrawUSDC', + 'send', + [ + constants.FULL_APPROVAL, + address, + 0, + '0xffffffff' + usdcUserWithdrawalSignature.slice(10), + usdcWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet relay can call with two signatures to withdraw max USDC', + UserSmartWalletV7, + 'withdrawUSDC', + 'send', + [ + constants.FULL_APPROVAL, + address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + originalAddress + ) + + /* TODO: get this working manually + const withdrawalMessage = ( + UserSmartWallet.options.address + // smart wallet address + constants.NULL_BYTES_32.slice(2) + // smart wallet version + address.slice(2) + // user dharma key + address.slice(2) + // dharma key registry key + '5'.padStart(64, '0') + // nonce + constants.NULL_BYTES_32.slice(2) + // minimum gas + '04' + // action type + 'f'.padStart(64, 'f') + // amount + address.slice(2) // recipient + ) + + const saiWithdrawalSignature = signHashedPrefixedHashedHexString( + withdrawalMessage, + address + ) + */ + + await runTest( + 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 10, // DaiWithdrawal + '1', + address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + daiWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + daiUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay cannot withdraw "dust" dai', + UserSmartWalletV7, + 'withdrawDai', + 'send', + [ + '1', + address, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + false, + receipt => {}, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 10, // DaiWithdrawal + '1000000000000000', + constants.NULL_ADDRESS, + 0 + ], + true, + value => { + customActionId = value + } + ) + + daiWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + daiUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay cannot withdraw dai to null address', + UserSmartWalletV7, + 'withdrawDai', + 'send', + [ + '1000000000000000', + constants.NULL_ADDRESS, + 0, + saiUserWithdrawalSignature, + saiWithdrawalSignature + ], + false, + receipt => {}, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 10, // DaiWithdrawal + '1000000000000000', + address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + daiWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + daiUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay can call with signature to withdraw dai', + UserSmartWalletV7, + 'withdrawDai', + 'send', + [ + '1000000000000000', + address, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt.events) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet cannot get a non-custom "custom" next action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 2, // Generic, + constants.FULL_APPROVAL, + address, + 0 + ], + false + ) + + await runTest( + 'V7 UserSmartWallet cannot get a non-custom "custom" action ID', + UserSmartWalletV7, + 'getCustomActionID', + 'call', + [ + 2, // Generic, + constants.FULL_APPROVAL, + address, + 0, + 0 + ], + false + ) + + await runTest( + 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 10, // DaiWithdrawal + constants.FULL_APPROVAL, + address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + daiWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + daiUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay cannot call with bad signature to withdraw dai', + UserSmartWalletV7, + 'withdrawDai', + 'send', + [ + constants.FULL_APPROVAL, + address, + 0, + daiUserWithdrawalSignature, + '0xffffffff' + daiWithdrawalSignature.slice(10) + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet relay cannot call with bad user signature to withdraw dai', + UserSmartWalletV7, + 'withdrawDai', + 'send', + [ + constants.FULL_APPROVAL, + address, + 0, + '0xffffffff' + daiUserWithdrawalSignature.slice(10), + daiWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet relay can call with signature to withdraw sai', + UserSmartWalletV7, + 'withdrawDai', + 'send', + [ + constants.FULL_APPROVAL, + address, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get a Ether withdrawal custom action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 6, // ETHWithdrawal, + '0', // no amount + address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + ethWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + ethUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay cannot to withdraw ether with no amount', + UserSmartWalletV7, + 'withdrawEther', + 'send', + [ + '0', + address, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get a Ether withdrawal custom action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 6, // ETHWithdrawal, + '1', + constants.NULL_ADDRESS, // no recipient + 0 + ], + true, + value => { + customActionId = value + } + ) + + ethWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + ethUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay cannot to withdraw ether with no recipient', + UserSmartWalletV7, + 'withdrawEther', + 'send', + [ + '1', + constants.NULL_ADDRESS, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get a Ether withdrawal custom action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 6, // ETHWithdrawal, + '1', + address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + ethWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + ethUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay cannot call with bad signature to withdraw eth', + UserSmartWalletV7, + 'withdrawEther', + 'send', + [ + '1', + address, + 0, + ethUserWithdrawalSignature, + '0xffffffff' + ethWithdrawalSignature.slice(10) + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet relay cannot call with bad user signature to withdraw eth', + UserSmartWalletV7, + 'withdrawEther', + 'send', + [ + '1', + address, + 0, + '0xffffffff' + ethUserWithdrawalSignature.slice(10), + ethWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet relay can call with signature to withdraw ether', + UserSmartWalletV7, + 'withdrawEther', + 'send', + [ + '1', + address, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get a Ether withdrawal custom action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 6, // ETHWithdrawal, + '1', + address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + ethWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + ethUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay cannot call with bad signature to withdraw eth', + UserSmartWalletV7, + 'withdrawEther', + 'send', + [ + '1', + address, + 0, + ethUserWithdrawalSignature, + '0xffffffff' + ethWithdrawalSignature.slice(10) + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet relay cannot call with bad user signature to withdraw eth', + UserSmartWalletV7, + 'withdrawEther', + 'send', + [ + '1', + address, + 0, + '0xffffffff' + ethUserWithdrawalSignature.slice(10), + ethWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet relay can call with signature to withdraw ether', + UserSmartWalletV7, + 'withdrawEther', + 'send', + [ + '1', + address, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet cancel reverts with bad signature', + UserSmartWalletV7, + 'cancel', + 'send', + [ + 0, + '0x' + ], + false, + receipt => {}, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet calls revert if insufficient action gas is supplied', + UserSmartWalletV7, + 'cancel', + 'send', + [ + constants.FULL_APPROVAL, + '0x' + ], + false + ) + + await runTest( + 'V7 UserSmartWallet calls succeed if sufficient non-zero action gas supplied', + UserSmartWalletV7, + 'cancel', + 'send', + [ + '1', + '0x' + ] + ) + + await runTest( + 'V7 UserSmartWallet can get a cancel custom action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 0, // Cancel, + '0', + address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + cancelSignature = signHashedPrefixedHexString(customActionId, addressTwo) + + await runTest( + 'V7 UserSmartWallet can cancel using a signature', + UserSmartWalletV7, + 'cancel', + 'send', + [ + '0', + cancelSignature + ], + true, + receipt => {}, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet calls to atomic methods revert', + UserSmartWalletV7, + '_withdrawDaiAtomic', + 'send', + [ + '1', + address + ], + false + ) + + await runTest( + 'V7 UserSmartWallet calls to recover from random address revert', + UserSmartWalletV7, + 'recover', + 'send', + [ + address + ], + false + ) + + await runTest( + 'DharmaSmartWalletFactoryV1 can deploy a V7 smart wallet using a Dharma Key', + DharmaSmartWalletFactoryV1, + 'newSmartWallet', + 'send', + [addressTwo], + true, + receipt => { + //console.log(receipt.status, receipt.gasUsed) + if (testingContext !== 'coverage') { + let events = [] + Object.values(receipt.events).forEach((value) => { + const log = constants.EVENT_DETAILS[value.raw.topics[0]] + const decoded = web3.eth.abi.decodeLog( + log.abi, value.raw.data, value.raw.topics + ) + events.push({ + address: contractNames[value.address], + eventName: log.name, + returnValues: decoded + }) + }) + + assert.strictEqual(events[0].eventName, 'NewUserSigningKey') + assert.strictEqual(events[0].returnValues.userSigningKey, addressTwo) + //console.log(events) + + // TODO: test more events + } + } + ) + + await runTest( + 'V7 UserSmartWallet can get a generic action ID', + UserSmartWalletV7, + 'getNextGenericActionID', + 'call', + [ + USDC.options.address, + USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), + 0 + ], + true, + value => { + customActionId = value + } + ) + + executeActionSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + executeActionUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet cannot call executeAction and target a non-contract', + UserSmartWalletV7, + 'executeAction', + 'send', + [ + address, + USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ], + false + ) + + await runTest( + 'V7 UserSmartWallet cannot call executeAction and target itself', + UserSmartWalletV7, + 'executeAction', + 'send', + [ + UserSmartWalletV7.options.address, + USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ], + false + ) + + await runTest( + 'V7 UserSmartWallet can call executeAction', + UserSmartWalletV7, + 'executeAction', + 'send', + [ + USDC.options.address, + USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ) + + await runTest( + 'V7 UserSmartWallet can get the next generic batch action ID', + UserSmartWalletV7, + 'getNextGenericAtomicBatchActionID', + 'call', + [ + [{to: SAI.options.address, data: SAI.methods.totalSupply().encodeABI()}], + 0 + ], + true, + value => { + customActionId = value + } + ) + + await runTest( + 'UserSmartWallet can get the nonce', + UserSmartWalletV7, + 'getNonce', + 'call', + [], + true, + value => { + currentNonce = value + } + ) + + await runTest( + 'V7 UserSmartWallet generic batch action ID with nonce matches next ID', + UserSmartWalletV7, + 'getGenericAtomicBatchActionID', + 'call', + [ + [{to: SAI.options.address, data: SAI.methods.totalSupply().encodeABI()}], + currentNonce, + 0 + ], + true, + value => { + assert.strictEqual(value, customActionId) + } + ) + + executeActionSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + executeActionUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet can call executeActionWithAtomicBatchCalls', + UserSmartWalletV7, + 'executeActionWithAtomicBatchCalls', + 'send', + [ + [{to: SAI.options.address, data: SAI.methods.totalSupply().encodeABI()}], + 0, + executeActionUserSignature, + executeActionSignature + ] + ) + + await runTest( + 'USDC Whale can deposit usdc into the deployed smart wallet', + USDC, + 'transfer', + 'send', + [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals + true, + receipt => { + if (testingContext !== 'coverage') { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.USDC_WHALE_ADDRESS + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei('100', 'lovelace') + ) + } + }, + constants.USDC_WHALE_ADDRESS + ) + + await runTest( + 'new user smart wallet can trigger repayAndDeposit to deposit all new funds', + UserSmartWalletV7, + 'repayAndDeposit', + 'send', + [], + true, + receipt => { + // TODO: validate + } + ) + + await runTest( + 'Check blacklister address', + FIAT_TOKEN, + 'blacklister', + 'call', + [], + true, + value => { + blacklister = value + } + ) + + await runTest( + 'Check pauser address', + FIAT_TOKEN, + 'pauser', + 'call', + [], + true, + value => { + pauser = value + } + ) + + await runTest( + 'blacklist mock address', + FIAT_TOKEN, + 'blacklist', + 'send', + [constants.MOCK_USDC_BLACKLISTED_ADDRESS], + true, + receipt => {}, + blacklister + ) + + await runTest( + 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', + DharmaSmartWalletFactoryV1, + 'getNextSmartWallet', + 'call', + [constants.MOCK_USDC_BLACKLISTED_ADDRESS], + true, + value => { + targetBlacklistAddress = value + } + ) + + const BlacklistedUserSmartWalletV7 = new web3.eth.Contract( + DharmaSmartWalletImplementationV7Artifact.abi, + targetBlacklistAddress + ) + + await runTest( + 'USDC Whale can deposit usdc into the yet-to-be-blacklisted smart wallet', + USDC, + 'transfer', + 'send', + [targetBlacklistAddress, web3.utils.toWei('100', 'lovelace')], // six decimals + true, + receipt => { + if (testingContext !== 'coverage') { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.USDC_WHALE_ADDRESS + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetBlacklistAddress + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei('100', 'lovelace') + ) + } + }, + constants.USDC_WHALE_ADDRESS + ) + + await runTest( + 'blacklist counterfactual deployment address', + FIAT_TOKEN, + 'blacklist', + 'send', + [targetBlacklistAddress], + true, + receipt => {}, + blacklister + ) + + await runTest( + 'DharmaSmartWalletFactoryV1 can deploy to a blacklisted address', + DharmaSmartWalletFactoryV1, + 'newSmartWallet', + 'send', + [constants.MOCK_USDC_BLACKLISTED_ADDRESS], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ) + + await runTest( + 'blacklisted smart wallet will not approve USDC during repayAndDeposit', + BlacklistedUserSmartWalletV7, + 'repayAndDeposit', + 'send', + [], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ) + + await runTest( + 'un-blacklist counterfactual deployment address', + FIAT_TOKEN, + 'unBlacklist', + 'send', + [targetBlacklistAddress], + true, + receipt => {}, + blacklister + ) + + await runTest( + 'pause USDC', + FIAT_TOKEN, + 'pause', + 'send', + [], + true, + receipt => {}, + pauser + ) + + await runTest( + 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 5, // USDCWithdrawal, + constants.FULL_APPROVAL, + address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + usdcWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + usdcUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet attempt to withdraw max USDC when paused causes ExternalError', + UserSmartWalletV7, + 'withdrawUSDC', + 'send', + [ + constants.FULL_APPROVAL, + address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + originalAddress + ) + + await runTest( + 'smart wallet will not approve USDC when paused during repayAndDeposit', + BlacklistedUserSmartWalletV7, + 'repayAndDeposit', + 'send', + [], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ) + + await runTest( + 'unpause USDC', + FIAT_TOKEN, + 'unpause', + 'send', + [], + true, + receipt => {}, + pauser + ) + + await runTest( + 'unblacklisted, unpaused smart wallet approves USDC during repayAndDeposit', + BlacklistedUserSmartWalletV7, + 'repayAndDeposit', + 'send', + [], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ) + + await runTest( + 'V7 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', + UserSmartWallet, + 'getNextCustomActionID', + 'call', + [ + 5, // USDCWithdrawal, + web3.utils.toWei('50', 'lovelace'), + constants.MOCK_USDC_BLACKLISTED_ADDRESS, + 0 + ], + true, + value => { + customActionId = value + } + ) + + usdcWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + usdcUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay call to withdraw USDC to blacklisted address', + UserSmartWallet, + 'withdrawUSDC', + 'send', + [ + web3.utils.toWei('50', 'lovelace'), + constants.MOCK_USDC_BLACKLISTED_ADDRESS, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt.events[0]) + //console.log(receipt.events.ExternalError) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', + UserSmartWallet, + 'getNextCustomActionID', + 'call', + [ + 5, // USDCWithdrawal, + constants.FULL_APPROVAL, + UserSmartWallet.options.address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + usdcWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + usdcUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay call to withdraw USDC to itself', + UserSmartWallet, + 'withdrawUSDC', + 'send', + [ + constants.FULL_APPROVAL, + UserSmartWallet.options.address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', + UserSmartWallet, + 'getNextCustomActionID', + 'call', + [ + 5, // USDCWithdrawal, + constants.FULL_APPROVAL, + constants.MOCK_USDC_BLACKLISTED_ADDRESS, + 0 + ], + true, + value => { + customActionId = value + } + ) + + usdcWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + usdcUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay call to withdraw USDC to blacklisted address', + UserSmartWallet, + 'withdrawUSDC', + 'send', + [ + constants.FULL_APPROVAL, + constants.MOCK_USDC_BLACKLISTED_ADDRESS, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt.events[0]) + //console.log(receipt.events.ExternalError) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get a Ether withdrawal custom action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 6, // ETHWithdrawal, + '1', + targetWalletAddress, + 0 + ], + true, + value => { + customActionId = value + } + ) + + ethWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + ethUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay cannot withdraw eth to a non-payable account', + UserSmartWalletV7, + 'withdrawEther', + 'send', + [ + '1', + targetWalletAddress, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + originalAddress + ) + + await runTest( + 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', + DharmaSmartWalletFactoryV1, + 'getNextSmartWallet', + 'call', + [targetWalletAddress], + true, + value => { + // TODO: verify against expected value + targetWalletAddressTwo = value + } + ) + + await runTest( + 'DharmaSmartWalletFactoryV1 can deploy a V7 smart wallet using a contract key', + DharmaSmartWalletFactoryV1, + 'newSmartWallet', + 'send', + [targetWalletAddress] + ) + + const UserSmartWalletV7Two = new web3.eth.Contract( + DharmaSmartWalletImplementationV7Artifact.abi, + targetWalletAddressTwo + ) + + await runTest( + 'V7 UserSmartWallet cancel reverts with bad contract signature', + UserSmartWalletV7Two, + 'cancel', + 'send', + [ + 0, + '0x' + ], + false, + receipt => {}, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get a generic action ID', + UserSmartWalletV7, + 'getNextGenericActionID', + 'call', + [ + SAI.options.address, + SAI.methods.transfer(address, constants.FULL_APPROVAL).encodeABI(), + 0 + ], + true, + value => { + customActionId = value + } + ) + + executeActionSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + executeActionUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet can call executeAction', + UserSmartWalletV7, + 'executeAction', + 'send', + [ + SAI.options.address, + SAI.methods.transfer(address, constants.FULL_APPROVAL).encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ) + + await runTest( + 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', + UserSmartWallet, + 'getNextCustomActionID', + 'call', + [ + 10, // DaiWithdrawal + '1000000000000000000', + constants.NULL_ADDRESS, + 0 + ], + true, + value => { + customActionId = value + } + ) + + daiWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + daiUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay cannot withdraw to the null address', + UserSmartWallet, + 'withdrawDai', + 'send', + [ + '1000000000000000000', + constants.NULL_ADDRESS, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt.events) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', + UserSmartWallet, + 'getNextCustomActionID', + 'call', + [ + 10, // DaiWithdrawal + '100000000000000000000000000000000000000', // too much + address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + daiWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + daiUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay cannot withdraw too much dai', + UserSmartWallet, + 'withdrawDai', + 'send', + [ + '100000000000000000000000000000000000000', // too much + address, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt.events) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', + UserSmartWallet, + 'getNextCustomActionID', + 'call', + [ + 5, // USDCWithdrawal, + '100000000000000000000000000000000000000', // too much + address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + usdcWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + usdcUserWithdrawalSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay can call with two signatures to withdraw USDC', + UserSmartWallet, + 'withdrawUSDC', + 'send', + [ + '100000000000000000000000000000000000000', // too much + address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get next generic batch action ID', + UserSmartWalletV7, + 'getNextGenericAtomicBatchActionID', + 'call', + [ + [{ + to: DAI.options.address, + data: DAI.methods.transfer( + address, '100000000000000000000000000000' + ).encodeABI() + }], + 0 + ], + true, + value => { + customActionId = value + } + ) + + executeActionSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + executeActionUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet bad executeActionWithAtomicBatchCalls emits CallFailure', + UserSmartWalletV7, + 'executeActionWithAtomicBatchCalls', + 'send', + [ + [{ + to: DAI.options.address, + data: DAI.methods.transfer( + address, '100000000000000000000000000000' + ).encodeABI() + }], + 0, + executeActionUserSignature, + executeActionSignature + ], + true, + receipt => { + //console.log(receipt) + } + ) + + await runTest( + 'V7 UserSmartWallet can get a generic action ID', + UserSmartWalletV7, + 'getNextGenericActionID', + 'call', + [ + Comptroller.options.address, + Comptroller.methods.enterMarkets( + [constants.CDAI_MAINNET_ADDRESS] + ).encodeABI(), + 0 + ], + true, + value => { + customActionId = value + } + ) + + executeActionSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + executeActionUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet can call executeAction to enter dai market', + UserSmartWalletV7, + 'executeAction', + 'send', + [ + Comptroller.options.address, + Comptroller.methods.enterMarkets( + [constants.CDAI_MAINNET_ADDRESS] + ).encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ) + + await runTest( + 'Dai Whale can deposit dai into the smart wallet', + DAI, + 'transfer', + 'send', + [targetWalletAddress, web3.utils.toWei('100', 'ether')], + true, + receipt => { + if (testingContext !== 'coverage') { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.DAI_WHALE_ADDRESS + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei('100', 'ether') + ) + } + }, + constants.DAI_WHALE_ADDRESS + ) + + await runTest( + 'V7 UserSmartWallet can trigger repayAndDeposit to deposit all new funds', + UserSmartWalletV7, + 'repayAndDeposit' + ) + + await runTest( + 'V7 UserSmartWallet can get a generic action ID', + UserSmartWalletV7, + 'getNextGenericActionID', + 'call', + [ + CSAI_BORROW.options.address, + CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), + 0 + ], + true, + value => { + customActionId = value + } + ) + + executeActionSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + executeActionUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet can call executeAction to perform a borrow', + UserSmartWalletV7, + 'executeAction', + 'send', + [ + CSAI_BORROW.options.address, + CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ], + true, + receipt => { + //console.log(receipt.events) + }, + originalAddress + ) + + + + + await runTest( + 'V7 UserSmartWallet can get an escape hatch action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 7, // SetEscapeHatch, + 0, + constants.NULL_ADDRESS, // no recipient + 0 + ], + true, + value => { + customActionId = value + } + ) + + escapeHatchSignature = signHashedPrefixedHexString( + customActionId, address ) @@ -8385,8 +10900,65 @@ module.exports = {test: async function (provider, testingContext) { ) await runTest( - 'V6 UserSmartWallet relay cannot set an escape hatch once disabled', - UserSmartWalletV6, + 'V7 UserSmartWallet relay cannot set an escape hatch with no account', + UserSmartWalletV7, + 'setEscapeHatch', + 'send', + [ + constants.NULL_ADDRESS, + 0, + escapeHatchUserSignature, + escapeHatchSignature + ], + false, + receipt => { + // TODO: verify logs + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get an escape hatch action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 7, // SetEscapeHatch, + 0, + address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + escapeHatchSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + escapeHatchUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet cannot call escape before escape hatch is set', + UserSmartWalletV7, + 'escape', + 'send', + [], + false, + receipt => { + // TODO: verify logs + } + ) + + await runTest( + 'V7 UserSmartWallet relay can set an escape hatch', + UserSmartWalletV7, 'setEscapeHatch', 'send', [ @@ -8395,6 +10967,19 @@ module.exports = {test: async function (provider, testingContext) { escapeHatchUserSignature, escapeHatchSignature ], + true, + receipt => { + // TODO: verify logs + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet non-escape hatch account cannot call escape', + UserSmartWalletV7, + 'escape', + 'send', + [], false, receipt => { // TODO: verify logs @@ -8403,8 +10988,179 @@ module.exports = {test: async function (provider, testingContext) { ) await runTest( - 'V6 UserSmartWallet relay can trigger sai to dai migration as a no-op', - UserSmartWalletV6, + 'V7 UserSmartWallet escape hatch account can call escape', + UserSmartWalletV7, + 'escape', + 'send', + [], + true, + receipt => { + // TODO: verify logs + }, + address + ) + + await runTest( + 'V7 UserSmartWallet escape hatch account can call escape again', + UserSmartWalletV7, + 'escape', + 'send', + [], + true, + receipt => { + // TODO: verify logs + }, + address + ) + + await runTest( + 'V7 UserSmartWallet can get an escape hatch action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 8, // RemoveEscapeHatch, + 0, + constants.NULL_ADDRESS, + 0 + ], + true, + value => { + customActionId = value + } + ) + + escapeHatchSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + escapeHatchUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay can remove an escape hatch', + UserSmartWalletV7, + 'removeEscapeHatch', + 'send', + [ + 0, + escapeHatchUserSignature, + escapeHatchSignature + ], + true, + receipt => { + // TODO: verify logs + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet cannot call escape once escape hatch is removed', + UserSmartWalletV7, + 'escape', + 'send', + [], + false, + receipt => { + // TODO: verify logs + } + ) + + await runTest( + 'V7 UserSmartWallet can get an escape hatch action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 9, // DisableEscapeHatch, + 0, + constants.NULL_ADDRESS, + 0 + ], + true, + value => { + customActionId = value + } + ) + + escapeHatchSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + escapeHatchUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay can disable the escape hatch', + UserSmartWalletV7, + 'permanentlyDisableEscapeHatch', + 'send', + [ + 0, + escapeHatchUserSignature, + escapeHatchSignature + ], + true, + receipt => { + // TODO: verify logs + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet can get an escape hatch action ID', + UserSmartWalletV7, + 'getNextCustomActionID', + 'call', + [ + 7, // SetEscapeHatch, + 0, + address, + 0 + ], + true, + value => { + customActionId = value + } + ) + + escapeHatchSignature = signHashedPrefixedHexString( + customActionId, + address + ) + + escapeHatchUserSignature = signHashedPrefixedHexString( + customActionId, + addressTwo + ) + + await runTest( + 'V7 UserSmartWallet relay cannot set an escape hatch once disabled', + UserSmartWalletV7, + 'setEscapeHatch', + 'send', + [ + address, + 0, + escapeHatchUserSignature, + escapeHatchSignature + ], + false, + receipt => { + // TODO: verify logs + }, + originalAddress + ) + + await runTest( + 'V7 UserSmartWallet relay can trigger sai to dai migration as a no-op', + UserSmartWalletV7, 'migrateSaiToDai', 'send', [], @@ -8416,9 +11172,9 @@ module.exports = {test: async function (provider, testingContext) { ) await runTest( - 'V6 UserSmartWallet relay can trigger cSai to cDai migration as a no-op', - UserSmartWalletV6, - 'migrateCSaiToCDai', + 'V7 UserSmartWallet relay can trigger cSai to dDai migration as a no-op', + UserSmartWalletV7, + 'migrateCSaiToDDai', 'send', [], true, @@ -8429,19 +11185,19 @@ module.exports = {test: async function (provider, testingContext) { ) await runTest( - 'cSai can be sent to V6 UserSmartWallet', + 'cSai can be sent to V7 UserSmartWallet', CSAI, 'transfer', 'send', - [UserSmartWalletV6.options.address, web3.utils.toWei('0.5', 'mwei')] + [UserSmartWalletV7.options.address, web3.utils.toWei('0.5', 'mwei')] ) await runTest( - 'Sai Whale can deposit sai into the V6 user smart wallet', + 'Sai Whale can deposit sai into the V7 user smart wallet', SAI, 'transfer', 'send', - [UserSmartWalletV6.options.address, web3.utils.toWei('1', 'ether')], + [UserSmartWalletV7.options.address, web3.utils.toWei('1', 'ether')], true, receipt => { if (testingContext !== 'coverage') { @@ -8451,7 +11207,7 @@ module.exports = {test: async function (provider, testingContext) { ) assert.strictEqual( receipt.events.Transfer.returnValues.to, - UserSmartWalletV6.options.address + UserSmartWalletV7.options.address ) assert.strictEqual( receipt.events.Transfer.returnValues.value, @@ -8463,8 +11219,8 @@ module.exports = {test: async function (provider, testingContext) { ) await runTest( - 'V6 UserSmartWallet relay can trigger sai to dai migration', - UserSmartWalletV6, + 'V7 UserSmartWallet relay can trigger sai to dai migration', + UserSmartWalletV7, 'migrateSaiToDai', 'send', [], @@ -8476,9 +11232,9 @@ module.exports = {test: async function (provider, testingContext) { ) await runTest( - 'V6 UserSmartWallet relay can trigger cSai to cDai migration', - UserSmartWalletV6, - 'migrateCSaiToCDai', + 'V7 UserSmartWallet relay can trigger cSai to dDai migration', + UserSmartWalletV7, + 'migrateCSaiToDDai', 'send', [], true, @@ -8495,7 +11251,7 @@ module.exports = {test: async function (provider, testingContext) { 'initiateAccountRecovery', 'send', [ - UserSmartWalletV6.options.address, + UserSmartWalletV7.options.address, originalAddress, 0 // extraTime in seconds ], @@ -8512,7 +11268,7 @@ module.exports = {test: async function (provider, testingContext) { 'recover', 'send', [ - UserSmartWalletV6.options.address, + UserSmartWalletV7.options.address, originalAddress ], false @@ -8528,7 +11284,7 @@ module.exports = {test: async function (provider, testingContext) { 'recover', 'send', [ - UserSmartWalletV6.options.address, + UserSmartWalletV7.options.address, originalAddress ], true, @@ -8538,6 +11294,8 @@ module.exports = {test: async function (provider, testingContext) { } ) + // ZZZZZ + // COVERAGE TESTING - deployments const DharmaUpgradeBeaconControllerManagerCoverage = await runTest( `DharmaUpgradeBeaconControllerManager contract deployment`, From a549025255b5478453ef5e56b90c231a5bba0528 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Thu, 6 Feb 2020 15:56:23 -0500 Subject: [PATCH 08/47] get Dharma Dai (mock) and Dharma USD Coin set up --- .../token/DharmaDaiImplementationV1.sol | 72 ++- scripts/test/deploy.js | 548 +++++++++++++++++- 2 files changed, 586 insertions(+), 34 deletions(-) diff --git a/contracts/implementations/token/DharmaDaiImplementationV1.sol b/contracts/implementations/token/DharmaDaiImplementationV1.sol index 1022d23..435af0e 100644 --- a/contracts/implementations/token/DharmaDaiImplementationV1.sol +++ b/contracts/implementations/token/DharmaDaiImplementationV1.sol @@ -4,19 +4,19 @@ import "@openzeppelin/contracts/math/SafeMath.sol"; import "./DharmaTokenV1.sol"; import "../../../interfaces/CTokenInterface.sol"; import "../../../interfaces/ERC20Interface.sol"; -import "../../../interfaces/CDaiInterestRateModelInterface.sol"; +import "../../../interfaces/CUSDCInterestRateModelInterface.sol"; import "../../../interfaces/PotInterface.sol"; /** - * @title DharmaDaiImplementationV1 + * @title MockDharmaDaiImplementationV1 * @author 0age (dToken mechanics derived from Compound cTokens, ERC20 methods * derived from Open Zeppelin's ERC20 contract) * @notice Dharma Dai is an interest-bearing token, with cDai as the backing * token and Dai as the underlying token. The dDai exchange rate will initially * increase at 90% the rate of the cDai exchange rate. */ -contract DharmaDaiImplementationV1 is DharmaTokenV1 { +contract MockDharmaDaiImplementationV1 is DharmaTokenV1 { string internal constant _NAME = "Dharma Dai"; string internal constant _SYMBOL = "dDai"; string internal constant _UNDERLYING_NAME = "Dai"; @@ -30,39 +30,36 @@ contract DharmaDaiImplementationV1 is DharmaTokenV1 { 0x6B175474E89094C44Da98b954EedeAC495271d0F // mainnet ); - PotInterface internal constant _POT = PotInterface( - 0x197E90f9FAD81970bA7976f33CbD77088E5D7cf7 // mainnet - ); - // Note: this is just an EOA for the initial prototype. address internal constant _VAULT = 0x7e4A8391C728fEd9069B2962699AB416628B19Fa; + uint256 internal constant _SCALING_FACTOR_SQUARED = 1e36; + /** - * @notice Internal view function to get the current cDai exchange rate and - * supply rate per block. - * @return The current cDai exchange rate, or amount of Dai that is redeemable - * for each cDai, and the cDai supply rate per block (with 18 decimal places - * added to each returned rate). + * @notice Internal view function to get the current cDAI exchange rate and + * supply rate per block. NOTE: THIS IS MOCKED USING SAI DEPLOYED TO THE DAI + * ADDRESS! + * @return The current cDAI exchange rate, or amount of Dai that is + * redeemable for each cDAI, and the cDAI supply rate per block (with 18 + * decimal places added to each returned rate). */ function _getCurrentCTokenRates() internal view returns ( uint256 exchangeRate, uint256 supplyRate ) { - // Determine the number of blocks that have elapsed since last cDai accrual. + // Determine number of blocks that have elapsed since last cDAI accrual. uint256 blockDelta = block.number.sub(_CDAI.accrualBlockNumber()); // Return stored values if accrual has already been performed this block. if (blockDelta == 0) return ( _CDAI.exchangeRateStored(), _CDAI.supplyRatePerBlock() ); - - // Determine total "cash" held by cDai contract by calculating DSR interest. - uint256 cash = ( // solhint-disable-next-line not-rely-on-time - _rpow(_POT.dsr(), now.sub(_POT.rho()), 1e27).mul(_POT.chi()) / 1e27 // chi - ).mul(_POT.pie(address(_CDAI))) / 1e27; - - // Get the latest interest rate model from the cDai contract. - CDaiInterestRateModelInterface interestRateModel = ( - CDaiInterestRateModelInterface(_CDAI.interestRateModel()) + + // Determine total "cash" held by cDAI contract. + uint256 cash = _DAI.balanceOf(address(_CDAI)); + + // Get the latest interest rate model from the cDAI contract. + CUSDCInterestRateModelInterface interestRateModel = ( + CUSDCInterestRateModelInterface(_CDAI.interestRateModel()) ); // Get the current stored total borrows, reserves, and reserve factor. @@ -71,23 +68,34 @@ contract DharmaDaiImplementationV1 is DharmaTokenV1 { uint256 reserveFactor = _CDAI.reserveFactorMantissa(); // Get accumulated borrow interest via interest rate model and block delta. - uint256 interest = interestRateModel.getBorrowRate( + (uint256 err, uint256 borrowRate) = interestRateModel.getBorrowRate( cash, borrows, reserves - ).mul(blockDelta).mul(borrows) / _SCALING_FACTOR; + ); + require( + err == _COMPOUND_SUCCESS, "Interest Rate Model borrow rate check failed." + ); + + uint256 interest = borrowRate.mul(blockDelta).mul(borrows) / _SCALING_FACTOR; // Update total borrows and reserves using calculated accumulated interest. borrows = borrows.add(interest); reserves = reserves.add(reserveFactor.mul(interest) / _SCALING_FACTOR); - // Determine cDai exchange rate: (cash + borrows - reserves) / total supply - exchangeRate = ( - ((cash.add(borrows)).sub(reserves)).mul(_SCALING_FACTOR) - ).div(_CDAI.totalSupply()); + // Get "underlying": (cash + borrows - reserves) + uint256 underlying = (cash.add(borrows)).sub(reserves); - // Get supply rate via interest rate model and calculated parameters. - supplyRate = interestRateModel.getSupplyRate( - cash, borrows, reserves, reserveFactor - ); + // Determine cDAI exchange rate: underlying / total supply + exchangeRate = (underlying.mul(_SCALING_FACTOR)).div(_CDAI.totalSupply()); + + // Get "borrows per" by dividing total borrows by underlying and scaling up. + uint256 borrowsPer = ( + borrows.mul(_SCALING_FACTOR_SQUARED) + ).div(underlying); + + // Supply rate is borrow interest * (1 - reserveFactor) * borrowsPer + supplyRate = ( + interest.mul(_SCALING_FACTOR.sub(reserveFactor)).mul(borrowsPer) + ) / _SCALING_FACTOR_SQUARED; } function _getUnderlyingName() internal pure returns (string memory underlyingName) { diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index a0438a3..935baa9 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -7,8 +7,6 @@ let DharmaUpgradeBeaconArtifact; let DharmaUpgradeBeaconControllerArtifact; let DharmaUpgradeBeaconEnvoyArtifact; let DharmaKeyRingUpgradeBeaconArtifact; -let DharmaDaiUpgradeBeaconArtifact; -let DharmaUSDCUpgradeBeaconArtifact; let DharmaKeyRegistryV1Artifact; let DharmaKeyRegistryV2Artifact; let DharmaAccountRecoveryManagerV2Artifact; @@ -19,10 +17,21 @@ let AdharmaKeyRingImplementationArtifact; let DharmaUpgradeBeaconControllerManagerArtifact; let DharmaKeyRingFactoryV2Artifact; let DharmaEscapeHatchRegistryArtifact; + +let DharmaDaiUpgradeBeaconArtifact; let DharmaDaiArtifact; + +let DharmaUSDCUpgradeBeaconArtifact; let DharmaUSDCArtifact; + let SmartWalletRevertReasonHelperV1Artifact; +const DharmaDaiInitializerArtifact = require('../../build/contracts/DharmaDaiInitializer.json') +const DharmaDaiImplementationV1Artifact = require('../../build/contracts/MockDharmaDaiImplementationV1.json') + +const DharmaUSDCInitializerArtifact = require('../../build/contracts/DharmaUSDCInitializer.json') +const DharmaUSDCImplementationV1Artifact = require('../../build/contracts/DharmaUSDCImplementationV1.json') + const DharmaUpgradeMultisigArtifact = require('../../build/contracts/DharmaUpgradeMultisig.json') const DharmaAccountRecoveryMultisigArtifact = require('../../build/contracts/DharmaAccountRecoveryMultisig.json') const DharmaAccountRecoveryOperatorMultisigArtifact = require('../../build/contracts/DharmaAccountRecoveryOperatorMultisig.json') @@ -103,7 +112,9 @@ module.exports = {test: async function (provider, testingContext) { AdharmaKeyRingImplementationArtifact = require('../../../build/contracts/AdharmaKeyRingImplementation.json') DharmaUpgradeBeaconControllerManagerArtifact = require('../../../build/contracts/DharmaUpgradeBeaconControllerManager.json') DharmaEscapeHatchRegistryArtifact = require('../../../build/contracts/DharmaEscapeHatchRegistry.json') + DharmaDaiUpgradeBeaconArtifact = require('../../../build/contracts/DharmaDaiUpgradeBeacon.json') DharmaDaiArtifact = require('../../../build/contracts/DharmaDai.json') + DharmaUSDCUpgradeBeaconArtifact = require('../../../build/contracts/DharmaUSDCUpgradeBeacon.json') DharmaUSDCArtifact = require('../../../build/contracts/DharmaUSDC.json') SmartWalletRevertReasonHelperV1Artifact = require('../../../build/contracts/SmartWalletRevertReasonHelperV1.json') } else { @@ -123,7 +134,9 @@ module.exports = {test: async function (provider, testingContext) { AdharmaKeyRingImplementationArtifact = require('../../build/contracts/AdharmaKeyRingImplementation.json') DharmaUpgradeBeaconControllerManagerArtifact = require('../../build/contracts/DharmaUpgradeBeaconControllerManager.json') DharmaEscapeHatchRegistryArtifact = require('../../build/contracts/DharmaEscapeHatchRegistry.json') + DharmaDaiUpgradeBeaconArtifact = require('../../build/contracts/DharmaDaiUpgradeBeacon.json') DharmaDaiArtifact = require('../../build/contracts/DharmaDai.json') + DharmaUSDCUpgradeBeaconArtifact = require('../../build/contracts/DharmaUSDCUpgradeBeacon.json') DharmaUSDCArtifact = require('../../build/contracts/DharmaUSDC.json') SmartWalletRevertReasonHelperV1Artifact = require('../../build/contracts/SmartWalletRevertReasonHelperV1.json') } @@ -203,6 +216,26 @@ module.exports = {test: async function (provider, testingContext) { constants.INDESTRUCTIBLE_REGISTRY_ADDRESS ) + const DharmaDaiUpgradeBeaconController = new web3.eth.Contract( + DharmaUpgradeBeaconControllerArtifact.abi, + constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_ADDRESS + ) + + const DharmaUSDCUpgradeBeaconController = new web3.eth.Contract( + DharmaUpgradeBeaconControllerArtifact.abi, + constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_ADDRESS + ) + + const DharmaDaiInitializer = new web3.eth.Contract( + DharmaDaiInitializerArtifact.abi, + constants.DHARMA_DAI_ADDRESS + ) + + const DharmaUSDCInitializer = new web3.eth.Contract( + DharmaUSDCInitializerArtifact.abi, + constants.DHARMA_USDC_ADDRESS + ) + const SmartWalletRevertReasonHelperV1 = new web3.eth.Contract( SmartWalletRevertReasonHelperV1Artifact.abi, constants.REVERT_REASON_HELPER_ADDRESS @@ -458,6 +491,34 @@ module.exports = {test: async function (provider, testingContext) { ) ) + const DharmaDaiInitializerDeployer = new web3.eth.Contract( + DharmaDaiInitializerArtifact.abi + ) + DharmaDaiInitializerDeployer.options.data = ( + DharmaDaiInitializerArtifact.bytecode + ) + + const DharmaDaiImplementationV1Deployer = new web3.eth.Contract( + DharmaDaiImplementationV1Artifact.abi + ) + DharmaDaiImplementationV1Deployer.options.data = ( + DharmaDaiImplementationV1Artifact.bytecode + ) + + const DharmaUSDCInitializerDeployer = new web3.eth.Contract( + DharmaUSDCInitializerArtifact.abi + ) + DharmaUSDCInitializerDeployer.options.data = ( + DharmaUSDCInitializerArtifact.bytecode + ) + + const DharmaUSDCImplementationV1Deployer = new web3.eth.Contract( + DharmaUSDCImplementationV1Artifact.abi + ) + DharmaUSDCImplementationV1Deployer.options.data = ( + DharmaUSDCImplementationV1Artifact.bytecode + ) + /* const DharmaKeyRingImplementationV0Deployer = new web3.eth.Contract( DharmaKeyRingImplementationV0Artifact.abi @@ -2147,6 +2208,489 @@ module.exports = {test: async function (provider, testingContext) { } ) + + + + + + + + + + let currentDharmaDaiUpgradeBeaconControllerCode; + await runTest( + 'Checking Dharma Dai Upgrade Beacon Controller runtime code', + MockCodeCheck, + 'code', + 'call', + [constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_ADDRESS], + true, + value => { + currentDharmaDaiUpgradeBeaconControllerCode = value; + } + ) + + if ( + currentDharmaDaiUpgradeBeaconControllerCode !== swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.deployedBytecode, + constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA + ) + ) { + await runTest( + `DharmaDaiUpgradeBeaconController contract address check through immutable create2 factory`, + ImmutableCreate2Factory, + 'findCreate2Address', + 'call', + [ + constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_SALT, + swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.bytecode, + constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA + ) + ], + true, + value => { + assert.strictEqual(value, constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_ADDRESS) + } + ) + + await runTest( + `DharmaDaiUpgradeBeaconController contract deployment through immutable create2 factory`, + ImmutableCreate2Factory, + 'safeCreate2', + 'send', + [ + constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_SALT, + swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.bytecode, + constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA + ) + ] + ) + } + + await runTest( + 'Deployed DharmaDaiUpgradeBeaconController code is correct', + MockCodeCheck, + 'code', + 'call', + [constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_ADDRESS], + true, + value => { + assert.strictEqual(value, swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.deployedBytecode, + constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA + )) + } + ) + + let currentDharmaUSDCUpgradeBeaconControllerCode; + await runTest( + 'Checking Dharma USDC Upgrade Beacon Controller runtime code', + MockCodeCheck, + 'code', + 'call', + [constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_ADDRESS], + true, + value => { + currentDharmaUSDCUpgradeBeaconControllerCode = value; + } + ) + + if ( + currentDharmaUSDCUpgradeBeaconControllerCode !== swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.deployedBytecode, + constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA + ) + ) { + await runTest( + `DharmaUSDCUpgradeBeaconController contract address check through immutable create2 factory`, + ImmutableCreate2Factory, + 'findCreate2Address', + 'call', + [ + constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_SALT, + swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.bytecode, + constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA + ) + ], + true, + value => { + assert.strictEqual(value, constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_ADDRESS) + } + ) + + await runTest( + `DharmaUSDCUpgradeBeaconController contract deployment through immutable create2 factory`, + ImmutableCreate2Factory, + 'safeCreate2', + 'send', + [ + constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_SALT, + swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.bytecode, + constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA + ) + ] + ) + } + + await runTest( + 'Deployed DharmaUSDCUpgradeBeaconController code is correct', + MockCodeCheck, + 'code', + 'call', + [constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_ADDRESS], + true, + value => { + assert.strictEqual(value, swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.deployedBytecode, + constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA + )) + } + ) + + let currentDharmaDaiUpgradeBeaconCode; + await runTest( + 'Checking Dharma Dai Upgrade Beacon Controller runtime code', + MockCodeCheck, + 'code', + 'call', + [constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS], + true, + value => { + currentDharmaDaiUpgradeBeaconCode = value; + } + ) + + if ( + currentDharmaDaiUpgradeBeaconCode !== swapMetadataHash( + DharmaDaiUpgradeBeaconArtifact.deployedBytecode, + constants.DHARMA_DAI_UPGRADE_BEACON_METADATA + ) + ) { + await runTest( + `DharmaDaiUpgradeBeacon contract address check through immutable create2 factory`, + ImmutableCreate2Factory, + 'findCreate2Address', + 'call', + [ + constants.DHARMA_DAI_UPGRADE_BEACON_SALT, + swapMetadataHash( + DharmaDaiUpgradeBeaconArtifact.bytecode, + constants.DHARMA_DAI_UPGRADE_BEACON_METADATA + ) + ], + true, + value => { + assert.strictEqual(value, constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS) + } + ) + + await runTest( + `DharmaDaiUpgradeBeacon contract deployment through immutable create2 factory`, + ImmutableCreate2Factory, + 'safeCreate2', + 'send', + [ + constants.DHARMA_DAI_UPGRADE_BEACON_SALT, + swapMetadataHash( + DharmaDaiUpgradeBeaconArtifact.bytecode, + constants.DHARMA_DAI_UPGRADE_BEACON_METADATA + ) + ] + ) + } + + await runTest( + 'Deployed DharmaDaiUpgradeBeacon code is correct', + MockCodeCheck, + 'code', + 'call', + [constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS], + true, + value => { + assert.strictEqual(value, swapMetadataHash( + DharmaDaiUpgradeBeaconArtifact.deployedBytecode, + constants.DHARMA_DAI_UPGRADE_BEACON_METADATA + )) + } + ) + + let currentDharmaUSDCUpgradeBeaconCode; + await runTest( + 'Checking Dharma USDC Upgrade Beacon Controller runtime code', + MockCodeCheck, + 'code', + 'call', + [constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS], + true, + value => { + currentDharmaUSDCUpgradeBeaconCode = value; + } + ) + + if ( + currentDharmaUSDCUpgradeBeaconCode !== swapMetadataHash( + DharmaUSDCUpgradeBeaconArtifact.deployedBytecode, + constants.DHARMA_USDC_UPGRADE_BEACON_METADATA + ) + ) { + await runTest( + `DharmaUSDCUpgradeBeacon contract address check through immutable create2 factory`, + ImmutableCreate2Factory, + 'findCreate2Address', + 'call', + [ + constants.DHARMA_USDC_UPGRADE_BEACON_SALT, + swapMetadataHash( + DharmaUSDCUpgradeBeaconArtifact.bytecode, + constants.DHARMA_USDC_UPGRADE_BEACON_METADATA + ) + ], + true, + value => { + assert.strictEqual(value, constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS) + } + ) + + await runTest( + `DharmaUSDCUpgradeBeacon contract deployment through immutable create2 factory`, + ImmutableCreate2Factory, + 'safeCreate2', + 'send', + [ + constants.DHARMA_USDC_UPGRADE_BEACON_SALT, + swapMetadataHash( + DharmaUSDCUpgradeBeaconArtifact.bytecode, + constants.DHARMA_USDC_UPGRADE_BEACON_METADATA + ) + ] + ) + } + + await runTest( + 'Deployed DharmaUSDCUpgradeBeacon code is correct', + MockCodeCheck, + 'code', + 'call', + [constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS], + true, + value => { + assert.strictEqual(value, swapMetadataHash( + DharmaUSDCUpgradeBeaconArtifact.deployedBytecode, + constants.DHARMA_USDC_UPGRADE_BEACON_METADATA + )) + } + ) + + let currentDharmaDaiCode; + await runTest( + 'Checking Dharma Dai Upgrade Beacon Controller runtime code', + MockCodeCheck, + 'code', + 'call', + [constants.DHARMA_DAI_ADDRESS], + true, + value => { + currentDharmaDaiCode = value; + } + ) + + if ( + currentDharmaDaiCode !== swapMetadataHash( + DharmaDaiArtifact.deployedBytecode, + constants.DHARMA_DAI_METADATA + ) + ) { + await runTest( + `DharmaDai contract address check through immutable create2 factory`, + ImmutableCreate2Factory, + 'findCreate2Address', + 'call', + [ + constants.DHARMA_DAI_SALT, + swapMetadataHash( + DharmaDaiArtifact.bytecode, + constants.DHARMA_DAI_METADATA + ) + ], + true, + value => { + assert.strictEqual(value, constants.DHARMA_DAI_ADDRESS) + } + ) + + await runTest( + `DharmaDai contract deployment through immutable create2 factory`, + ImmutableCreate2Factory, + 'safeCreate2', + 'send', + [ + constants.DHARMA_DAI_SALT, + swapMetadataHash( + DharmaDaiArtifact.bytecode, + constants.DHARMA_DAI_METADATA + ) + ] + ) + } + + await runTest( + 'Deployed DharmaDai code is correct', + MockCodeCheck, + 'code', + 'call', + [constants.DHARMA_DAI_ADDRESS], + true, + value => { + assert.strictEqual(value, swapMetadataHash( + DharmaDaiArtifact.deployedBytecode, + constants.DHARMA_DAI_METADATA + )) + } + ) + + let currentDharmaUSDCCode; + await runTest( + 'Checking Dharma USDC Upgrade Beacon Controller runtime code', + MockCodeCheck, + 'code', + 'call', + [constants.DHARMA_USDC_ADDRESS], + true, + value => { + currentDharmaUSDCCode = value; + } + ) + + if ( + currentDharmaUSDCCode !== swapMetadataHash( + DharmaUSDCArtifact.deployedBytecode, + constants.DHARMA_USDC_METADATA + ) + ) { + await runTest( + `DharmaUSDC contract address check through immutable create2 factory`, + ImmutableCreate2Factory, + 'findCreate2Address', + 'call', + [ + constants.DHARMA_USDC_SALT, + swapMetadataHash( + DharmaUSDCArtifact.bytecode, + constants.DHARMA_USDC_METADATA + ) + ], + true, + value => { + assert.strictEqual(value, constants.DHARMA_USDC_ADDRESS) + } + ) + + await runTest( + `DharmaUSDC contract deployment through immutable create2 factory`, + ImmutableCreate2Factory, + 'safeCreate2', + 'send', + [ + constants.DHARMA_USDC_SALT, + swapMetadataHash( + DharmaUSDCArtifact.bytecode, + constants.DHARMA_USDC_METADATA + ) + ] + ) + } + + await runTest( + 'Deployed DharmaUSDC code is correct', + MockCodeCheck, + 'code', + 'call', + [constants.DHARMA_USDC_ADDRESS], + true, + value => { + assert.strictEqual(value, swapMetadataHash( + DharmaUSDCArtifact.deployedBytecode, + constants.DHARMA_USDC_METADATA + )) + } + ) + + const DharmaDaiInitializerImplementation = await runTest( + `DharmaDaiInitializer contract deployment`, + DharmaDaiInitializerDeployer, + '', + 'deploy' + ) + + const DharmaUSDCInitializerImplementation = await runTest( + `DharmaUSDCInitializer contract deployment`, + DharmaUSDCInitializerDeployer, + '', + 'deploy' + ) + + const DharmaDaiImplementationV1 = await runTest( + `DharmaDaiImplementationV1 contract deployment`, + DharmaDaiImplementationV1Deployer, + '', + 'deploy' + ) + + const DharmaUSDCImplementationV1 = await runTest( + `DharmaUSDCImplementationV1 contract deployment`, + DharmaUSDCImplementationV1Deployer, + '', + 'deploy' + ) + + await runTest( + 'DharmaDaiUpgradeBeaconController can set initializer implementation', + DharmaDaiUpgradeBeaconController, + 'upgrade', + 'send', + [constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS, DharmaDaiInitializerImplementation.options.address] + ) + + await runTest( + 'DharmaDai can be initialized', + DharmaDaiInitializer, + 'initialize' + ) + + await runTest( + 'DharmaDaiUpgradeBeaconController can set implementation V1', + DharmaDaiUpgradeBeaconController, + 'upgrade', + 'send', + [constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS, DharmaDaiImplementationV1.options.address] + ) + + await runTest( + 'DharmaUSDCUpgradeBeaconController can set initializer implementation', + DharmaUSDCUpgradeBeaconController, + 'upgrade', + 'send', + [constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS, DharmaUSDCInitializerImplementation.options.address] + ) + + await runTest( + 'DharmaUSDC can be initialized', + DharmaUSDCInitializer, + 'initialize' + ) + + await runTest( + 'DharmaUSDCUpgradeBeaconController can set implementation V1', + DharmaUSDCUpgradeBeaconController, + 'upgrade', + 'send', + [constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS, DharmaUSDCImplementationV1.options.address] + ) + await runTest( `AdharmaSmartWalletImplementation contract deployment`, AdharmaSmartWalletImplementationDeployer, From 53f848e71ff57f8a75d641c84adf874a9220b49d Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Thu, 6 Feb 2020 13:58:01 -0800 Subject: [PATCH 09/47] refactor web3 --- scripts/test/ci.js | 22 +- scripts/test/deploy.js | 4 +- scripts/test/deployMockExternal.js | 5 +- scripts/test/test.js | 4 +- scripts/test/testHelpers.js | 844 +++++++++++++++++++++++++++++ scripts/test/web3.js | 9 + 6 files changed, 869 insertions(+), 19 deletions(-) create mode 100644 scripts/test/testHelpers.js create mode 100644 scripts/test/web3.js diff --git a/scripts/test/ci.js b/scripts/test/ci.js index 4e4b4eb..44b6119 100644 --- a/scripts/test/ci.js +++ b/scripts/test/ci.js @@ -1,20 +1,16 @@ -const connectionConfig = require('../../truffle-config.js') - -const connection = connectionConfig.networks['development'] - -let web3Provider = connection.provider - // import tests -var deployMockExternal = require('./deployMockExternal.js') -var deploy = require('./deploy.js') -var test = require('./test.js') +const deployMockExternal = require('./deployMockExternal.js'); +const deploy = require('./deploy.js'); +const test = require('./test.js'); // run tests async function runTests() { - await deployMockExternal.test(web3Provider, 'development') - await deploy.test(web3Provider, 'development') - await test.test(web3Provider, 'development') + const context = "development"; + + await deployMockExternal.test(context); + await deploy.test(context); + await test.test(context); process.exit(0) } -runTests() +runTests(); diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index 935baa9..d7c983a 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -2,6 +2,7 @@ var assert = require('assert') var fs = require('fs') var util = require('ethereumjs-util') const constants = require('./constants.js') +const { web3 } = require("./web3"); let DharmaUpgradeBeaconArtifact; let DharmaUpgradeBeaconControllerArtifact; @@ -94,7 +95,7 @@ function swapMetadataHash(bytecode, newMetadataHashes) { return bytecode } -module.exports = {test: async function (provider, testingContext) { +module.exports = {test: async function (testingContext) { if (testingContext === 'coverage') { DharmaUpgradeBeaconEnvoyArtifact = require('../../../build/contracts/DharmaUpgradeBeaconEnvoy.json') DharmaUpgradeBeaconControllerArtifact = require('../../../build/contracts/DharmaUpgradeBeaconController.json') @@ -141,7 +142,6 @@ module.exports = {test: async function (provider, testingContext) { SmartWalletRevertReasonHelperV1Artifact = require('../../build/contracts/SmartWalletRevertReasonHelperV1.json') } - var web3 = provider let passed = 0 let failed = 0 let gasUsage = {} diff --git a/scripts/test/deployMockExternal.js b/scripts/test/deployMockExternal.js index ed02cba..3f7590c 100644 --- a/scripts/test/deployMockExternal.js +++ b/scripts/test/deployMockExternal.js @@ -6,8 +6,9 @@ const constants = require('./constants.js') const IERC20Artifact = require('../../build/contracts/IERC20.json') const MockSaiToDaiMigratorArtifact = require('../../build/contracts/MockSaiToDaiMigrator.json') -module.exports = {test: async function (provider, testingContext) { - var web3 = provider +const { web3 } = require("./web3"); + +module.exports = {test: async function (testingContext) { let passed = 0 let failed = 0 let gasUsage = {} diff --git a/scripts/test/test.js b/scripts/test/test.js index a8a1cc3..0eb7a41 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -2,6 +2,7 @@ var assert = require('assert') var fs = require('fs') var util = require('ethereumjs-util') const constants = require('./constants.js') +const { web3 } = require("./web3"); const AdharmaSmartWalletImplementationArtifact = require('../../build/contracts/AdharmaSmartWalletImplementation.json') const AdharmaKeyRingImplementationArtifact = require('../../build/contracts/AdharmaKeyRingImplementation.json') @@ -57,8 +58,7 @@ function longer() { return new Promise(resolve => {setTimeout(() => {resolve()}, 500)}) } -module.exports = {test: async function (provider, testingContext) { - var web3 = provider +module.exports = {test: async function (testingContext) { let passed = 0 let failed = 0 let gasUsage = {} diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js new file mode 100644 index 0000000..c2b226e --- /dev/null +++ b/scripts/test/testHelpers.js @@ -0,0 +1,844 @@ +import web3 from "web3"; + +const SCALING_FACTOR = web3.utils.toBN("1000000000000000000"); +const ZERO = web3.utils.toBN("0"); +const ONE = web3.utils.toBN("1"); +const NINE = web3.utils.toBN("9"); +const TEN = web3.utils.toBN("10"); + +class Tester { + constructor(provider, testingContext) { + this.web3 = provider; + this.context = testingContext; + this.failed = 0; + this.passed = 0; + } + + async init() { + const DharmaDaiDeployer = new this.web3.eth.Contract( + DharmaDaiArtifact.abi + ); + DharmaDaiDeployer.options.data = DharmaDaiArtifact.bytecode; + this.DharmaDaiDeployer = DharmaDaiDeployer; + + const DharmaUSDCDeployer = new this.web3.eth.Contract( + DharmaUSDCArtifact.abi + ); + DharmaUSDCDeployer.options.data = DharmaUSDCArtifact.bytecode; + this.DharmaUSDCDeployer = DharmaUSDCDeployer; + + const DharmaDaiInitializerDeployer = new this.web3.eth.Contract( + DharmaDaiInitializerArtifact.abi + ); + DharmaDaiInitializerDeployer.options.data = + DharmaDaiInitializerArtifact.bytecode; + this.DharmaDaiInitializerDeployer = DharmaDaiInitializerDeployer; + + const DharmaUSDCInitializerDeployer = new this.web3.eth.Contract( + DharmaUSDCInitializerArtifact.abi + ); + DharmaUSDCInitializerDeployer.options.data = + DharmaUSDCInitializerArtifact.bytecode; + this.DharmaUSDCInitializerDeployer = DharmaUSDCInitializerDeployer; + + const UpgradeBeaconControllerDeployer = new this.web3.eth.Contract( + UpgradeBeaconControllerArtifact.abi + ); + UpgradeBeaconControllerDeployer.options.data = + UpgradeBeaconControllerArtifact.bytecode; + this.UpgradeBeaconControllerDeployer = UpgradeBeaconControllerDeployer; + + const UpgradeBeaconDeployer = new this.web3.eth.Contract( + UpgradeBeaconArtifact.abi + ); + UpgradeBeaconDeployer.options.data = UpgradeBeaconArtifact.bytecode; + this.UpgradeBeaconDeployer = UpgradeBeaconDeployer; + + const UpgradeBeaconProxyDeployer = new this.web3.eth.Contract( + UpgradeBeaconProxyArtifact.abi + ); + UpgradeBeaconProxyDeployer.options.data = + UpgradeBeaconProxyArtifact.bytecode; + this.UpgradeBeaconProxyDeployer = UpgradeBeaconProxyDeployer; + + const Scenario0HelperDeployer = new this.web3.eth.Contract( + Scenario0HelperArtifact.abi + ); + Scenario0HelperDeployer.options.data = Scenario0HelperArtifact.bytecode; + this.Scenario0HelperDeployer = Scenario0HelperDeployer; + + const Scenario2HelperDeployer = new this.web3.eth.Contract( + Scenario2HelperArtifact.abi + ); + Scenario2HelperDeployer.options.data = Scenario2HelperArtifact.bytecode; + this.Scenario2HelperDeployer = Scenario2HelperDeployer; + + const Scenario5HelperDeployer = new this.web3.eth.Contract( + Scenario5HelperArtifact.abi + ); + Scenario5HelperDeployer.options.data = Scenario5HelperArtifact.bytecode; + this.Scenario5HelperDeployer = Scenario5HelperDeployer; + + const Scenario6HelperDeployer = new this.web3.eth.Contract( + Scenario6HelperArtifact.abi + ); + Scenario6HelperDeployer.options.data = Scenario6HelperArtifact.bytecode; + this.Scenario6HelperDeployer = Scenario6HelperDeployer; + + const Scenario7HelperDeployer = new this.web3.eth.Contract( + Scenario7HelperArtifact.abi + ); + Scenario7HelperDeployer.options.data = Scenario7HelperArtifact.bytecode; + this.Scenario7HelperDeployer = Scenario7HelperDeployer; + + const Scenario9HelperDeployer = new this.web3.eth.Contract( + Scenario9HelperArtifact.abi + ); + Scenario9HelperDeployer.options.data = Scenario9HelperArtifact.bytecode; + this.Scenario9HelperDeployer = Scenario9HelperDeployer; + + const Scenario11HelperDeployer = new this.web3.eth.Contract( + Scenario11HelperArtifact.abi + ); + Scenario11HelperDeployer.options.data = + Scenario11HelperArtifact.bytecode; + this.Scenario11HelperDeployer = Scenario11HelperDeployer; + + const MockERC1271Deployer = new this.web3.eth.Contract( + MockERC1271Artifact.abi + ); + MockERC1271Deployer.options.data = MockERC1271Artifact.bytecode; + this.MockERC1271Deployer = MockERC1271Deployer; + + this.DAI = new this.web3.eth.Contract( + IERC20Artifact.abi, + constants.DAI_MAINNET_ADDRESS + ); + + this.USDC = new this.web3.eth.Contract( + IERC20Artifact.abi, + constants.USDC_MAINNET_ADDRESS + ); + + this.CDAI = new this.web3.eth.Contract( + ICTokenArtifact.abi, + constants.CDAI_MAINNET_ADDRESS + ); + + this.CUSDC = new this.web3.eth.Contract( + ICTokenArtifact.abi, + constants.CUSDC_MAINNET_ADDRESS + ); + + this.UNISWAP_DAI = new this.web3.eth.Contract( + UniswapArtifact.abi, + constants.UNISWAP_DAI_MAINNET_ADDRESS + ); + + this.UNISWAP_USDC = new this.web3.eth.Contract( + UniswapArtifact.abi, + constants.UNISWAP_USDC_MAINNET_ADDRESS + ); + + const addresses = await this.web3.eth.getAccounts(); + if (addresses.length < 1) { + console.log("cannot find enough addresses to run tests!"); + process.exit(1); + } + + this.originalAddress = addresses[0]; + + this.address = await this.setupNewDefaultAddress( + `0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed` + ); + + this.addressTwo = await this.setupNewDefaultAddress( + `0xf00df00df00df00df00df00df00df00df00df00df00df00df00df00df00df00d` + ); + + let latestBlock = await this.web3.eth.getBlock("latest"); + + this.gasLimit = latestBlock.gasLimit; + } + + async setupNewDefaultAddress(newPrivateKey) { + const pubKey = await this.web3.eth.accounts.privateKeyToAccount( + newPrivateKey + ); + await this.web3.eth.accounts.wallet.add(pubKey); + + await this.web3.eth.sendTransaction({ + from: this.originalAddress, + to: pubKey.address, + value: 2 * 10 ** 18, + gas: "0x5208", + gasPrice: "0x4A817C800" + }); + + return pubKey.address; + } + async raiseGasLimit(necessaryGas) { + let iterations = 9999; + + if (necessaryGas > 8000000) { + console.error("the gas needed is too high!"); + process.exit(1); + } else if (typeof necessaryGas === "undefined") { + iterations = 20; + necessaryGas = 8000000; + } + + // bring up gas limit if necessary by doing additional transactions + let block = await this.web3.eth.getBlock("latest"); + while (iterations > 0 && block.gasLimit < necessaryGas) { + await this.web3.eth.sendTransaction({ + from: originalAddress, + to: originalAddress, + value: "0x01", + gas: "0x5208", + gasPrice: "0x4A817C800" + }); + block = await this.web3.eth.getBlock("latest"); + iterations--; + } + + console.log("raising gasLimit, currently at " + block.gasLimit); + return block.gasLimit; + } + + async getDeployGas(dataPayload) { + await this.web3.eth + .estimateGas({ + from: address, + data: dataPayload + }) + .catch(async error => { + if ( + error.message === + "Returned error: gas required exceeds allowance or always failing " + + "transaction" + ) { + await this.raiseGasLimit(); + await this.getDeployGas(dataPayload); + } + }); + + return this.web3.eth.estimateGas({ + from: address, + data: dataPayload + }); + } + + async advanceTime(time) { + return new Promise((resolve, reject) => { + this.web3.currentProvider.send( + { + jsonrpc: "2.0", + method: "evm_increaseTime", + params: [time], + id: new Date().getTime() + }, + (err, result) => { + if (err) { + return reject(err); + } + return resolve(result); + } + ); + }); + } + + async takeSnapshot() { + return new Promise((resolve, reject) => { + this.web3.currentProvider.send( + { + jsonrpc: "2.0", + method: "evm_snapshot", + id: new Date().getTime() + }, + (err, snapshotId) => { + if (err) { + return reject(err); + } + return resolve(snapshotId); + } + ); + }); + } + + async revertToSnapShot(id) { + return new Promise((resolve, reject) => { + this.web3.currentProvider.send( + { + jsonrpc: "2.0", + method: "evm_revert", + params: [id], + id: new Date().getTime() + }, + (err, result) => { + if (err) { + return reject(err); + } + return resolve(result); + } + ); + }); + } + + async advanceBlock() { + return new Promise((resolve, reject) => { + this.web3.currentProvider.send( + { + jsonrpc: "2.0", + method: "evm_mine", + id: new Date().getTime() + }, + (err, result) => { + if (err) { + return reject(err); + } + return resolve(result); + } + ); + }); + } + + async rpc(request) { + return new Promise((okay, fail) => + this.web3.currentProvider.send(request, (err, res) => + err ? fail(err) : okay(res) + ) + ); + } + + async getLatestBlockNumber() { + let { result: num } = await this.rpc({ + method: "eth_blockNumber", + id: new Date().getTime() // for snapshotting + }); + return num; + } + + async advanceBlocks(blocksToAdvance, nonce) { + if (blocksToAdvance < 1) { + throw new Error("must advance at least one block."); + } + + let currentBlockNumberHex = await this.getLatestBlockNumber(); + + const accountNonce = + typeof nonce === "undefined" + ? await this.web3.eth.getTransactionCount(this.address) + : nonce; + + const extraBlocks = blocksToAdvance - 1; + const extraBlocksHex = + "0x" + (extraBlocks + parseInt(currentBlockNumberHex)).toString(16); + + const nextBlockNumber = blocksToAdvance + 1; + const nextBlockNumberHex = + "0x" + + (nextBlockNumber + parseInt(currentBlockNumberHex)).toString(16); + + await this.rpc({ + method: "evm_mineBlockNumber", + params: [extraBlocksHex], + id: new Date().getTime() + }); + + const newBlockNumberHex = + "0x" + + (blocksToAdvance + parseInt(currentBlockNumberHex)).toString(16); + currentBlockNumberHex = await this.getLatestBlockNumber(); + + if (currentBlockNumberHex !== newBlockNumberHex) { + console.error( + `current block is now ${parseInt( + currentBlockNumberHex + )} - evm_mineBlockNumber failed... (expected ${parseInt( + newBlockNumberHex + )})` + ); + process.exit(1); + } + + const dummyTxReceipt = await this.web3.eth.sendTransaction({ + from: this.address, + to: this.address, + data: "0x", + value: 0, + gas: 21000, + gasPrice: 1, + nonce: accountNonce + }); + + return await this.web3.eth.getBlock(dummyTxReceipt.blockHash); + } + + async advanceTimeAndBlock(time) { + await this.advanceTime(time); + await this.advanceBlock(); + return Promise.resolve(this.web3.eth.getBlock("latest")); + } + + async advanceTimeAndBlocks(blocks, nonce) { + if (blocks < 2) { + return reject("must advance by at least two blocks."); + } + //let block = await this.web3.eth.getBlock(await this.getLatestBlockNumber()) + await this.advanceTime(blocks * 15); + //block = await this.web3.eth.getBlock(await this.getLatestBlockNumber()) + + // next block must be extracted from this function ('getBlock' breaks) + return await this.advanceBlocks(blocks - 1, nonce); + } + + signHashedPrefixedHexString(hashedHexString, account) { + const sig = util.ecsign( + util.toBuffer( + this.web3.utils.keccak256( + // prefix => "\x19Ethereum Signed Message:\n32" + "0x19457468657265756d205369676e6564204d6573736167653a0a3332" + + hashedHexString.slice(2), + { encoding: "hex" } + ) + ), + util.toBuffer(this.web3.eth.accounts.wallet[account].privateKey) + ); + + return ( + util.bufferToHex(sig.r) + + util.bufferToHex(sig.s).slice(2) + + this.web3.utils.toHex(sig.v).slice(2) + ); + } + + signHashedPrefixedHashedHexString(hexString, account) { + const sig = util.ecsign( + util.toBuffer( + this.web3.utils.keccak256( + // prefix => "\x19Ethereum Signed Message:\n32" + "0x19457468657265756d205369676e6564204d6573736167653a0a3332" + + this.web3.utils + .keccak256(hexString, { encoding: "hex" }) + .slice(2), + { encoding: "hex" } + ) + ), + util.toBuffer(this.web3.eth.accounts.wallet[account].privateKey) + ); + + return ( + util.bufferToHex(sig.r) + + util.bufferToHex(sig.s).slice(2) + + web3.utils.toHex(sig.v).slice(2) + ); + } + + async sendTransaction( + instance, + method, + args, + from, + value, + gas, + gasPrice, + transactionShouldSucceed, + nonce + ) { + return instance.methods[method](...args) + .send({ + from: from, + value: value, + gas: gas, + gasPrice: gasPrice, + nonce: nonce + }) + .on("confirmation", (confirmationNumber, r) => { + confirmations[r.transactionHash] = confirmationNumber; + }) + .catch(error => { + if (transactionShouldSucceed) { + console.error(error); + } + return { status: false }; + }); + } + + async callMethod( + instance, + method, + args, + from, + value, + gas, + gasPrice, + callShouldSucceed + ) { + let callSucceeded = true; + + const returnValues = await instance.methods[method](...args) + .call({ + from: from, + value: value, + gas: gas, + gasPrice: gasPrice + }) + .catch(error => { + if (callShouldSucceed) { + console.error(error); + } + callSucceeded = false; + }); + + return { callSucceeded, returnValues }; + } + + async send( + title, + instance, + method, + args, + from, + value, + gas, + gasPrice, + transactionShouldSucceed, + assertionCallback, + nonce + ) { + const receipt = await this.sendTransaction( + instance, + method, + args, + from, + value, + gas, + gasPrice, + transactionShouldSucceed, + nonce + ); + + const transactionSucceeded = receipt.status; + + if (transactionSucceeded) { + try { + assertionCallback(receipt); + } catch (error) { + console.log(error); + return false; // return false if assertions fail and throw an error + } + } + + //return true if transaction success matches expectations, false if expectations are mismatched + return transactionSucceeded === transactionShouldSucceed; + } + + async call( + title, + instance, + method, + args, + from, + value, + gas, + gasPrice, + callShouldSucceed, + assertionCallback + ) { + const { callSucceeded, returnValues } = await this.callMethod( + instance, + method, + args, + from, + value, + gas, + gasPrice, + callShouldSucceed + ); + + // if call succeeds, try assertion callback + if (callSucceeded) { + try { + assertionCallback(returnValues); + } catch (error) { + console.log(error); + return false; + } + } + return callSucceeded === callShouldSucceed; + } + + async deploy( + title, + instance, + args, + from, + value, + gas, + gasPrice, + shouldSucceed, + assertionCallback + ) { + let deployData = instance.deploy({ arguments: args }).encodeABI(); + let deployGas = await this.web3.eth + .estimateGas({ + from: from, + data: deployData + }) + .catch(error => { + if (shouldSucceed) { + console.error(error); + } + return this.gasLimit; + }); + + if (deployGas > this.gasLimit) { + console.error( + ` ✘ ${title}: deployment costs exceed block gas limit!` + ); + process.exit(1); + } + + if (typeof gas === "undefined") { + gas = deployGas; + } + + if (deployGas > gas) { + console.error(` ✘ ${title}: deployment costs exceed supplied gas.`); + process.exit(1); + } + + let signed; + let deployHash; + let receipt; + const contract = await instance + .deploy({ arguments: args }) + .send({ + from: from, + gas: gas, + gasPrice: gasPrice + }) + .on("transactionHash", hash => { + deployHash = hash; + }) + .on("receipt", r => { + receipt = r; + }) + .on("confirmation", (confirmationNumber, r) => { + confirmations[r.transactionHash] = confirmationNumber; + }) + .catch(error => { + if (shouldSucceed) { + console.error(error); + } + + receipt = { status: false }; + }); + + if (receipt.status !== shouldSucceed) { + if (contract) { + return [false, contract, gas]; + } + return [false, instance, gas]; + } else if (!shouldSucceed) { + if (contract) { + return [true, contract, gas]; + } + return [true, instance, gas]; + } + + assert.ok(receipt.status); + + let assertionsPassed; + try { + assertionCallback(receipt); + assertionsPassed = true; + } catch (error) { + assertionsPassed = false; + } + + if (contract) { + return [assertionsPassed, contract, gas]; + } + return [assertionsPassed, instance, gas]; + } + + /* aggregates the first 3 functions + * run test without coverage, once they're passing then run with coverage + * coverage changes the gas -- orders of magnitued more expensive + * any test that are gas dependent get grilled under coverage test + * + * + * default: send + */ + async runTest( + title, + instance, + method, + callOrSendOrDeploy, + args, + shouldSucceed, + assertionCallback, + from, + value, + gas, + nonce + ) { + if (typeof callOrSendOrDeploy === "undefined") { + callOrSendOrDeploy = "send"; + } + if (typeof args === "undefined") { + args = []; + } + if (typeof shouldSucceed === "undefined") { + shouldSucceed = true; + } + if (typeof assertionCallback === "undefined") { + assertionCallback = value => {}; + } + if (typeof from === "undefined") { + from = this.address; + } + if (typeof value === "undefined") { + value = 0; + } + if (typeof gas === "undefined" && callOrSendOrDeploy !== "deploy") { + gas = 6009006; + if (this.context === "coverage") { + gas = this.gasLimit - 1; + } + } + let ok = false; + let contract; + let deployGas; + if (callOrSendOrDeploy === "send") { + ok = await this.send( + title, + instance, + method, + args, + from, + value, + gas, + 1, + shouldSucceed, + assertionCallback, + nonce + ); + } else if (callOrSendOrDeploy === "call") { + ok = await this.call( + title, + instance, + method, + args, + from, + value, + gas, + 1, + shouldSucceed, + assertionCallback + ); + } else if (callOrSendOrDeploy === "deploy") { + const fields = await this.deploy( + title, + instance, + args, + from, + value, + gas, + 1, + shouldSucceed, + assertionCallback + ); + ok = fields[0]; + contract = fields[1]; + deployGas = fields[2]; + } else { + console.error("must use call, send, or deploy!"); + process.exit(1); + } + + if (ok) { + console.log( + ` ✓ ${ + callOrSendOrDeploy === "deploy" ? "successful " : "" + }${title}${ + callOrSendOrDeploy === "deploy" ? ` (${deployGas} gas)` : "" + }` + ); + this.passed++; + } else { + console.log( + ` ✘ ${ + callOrSendOrDeploy === "deploy" ? "failed " : "" + }${title}${ + callOrSendOrDeploy === "deploy" ? ` (${deployGas} gas)` : "" + }` + ); + this.failed++; + } + + if (contract) { + return contract; + } + } + + getEvents(receipt, contractNames) { + const { events } = receipt; + + // web3 "helpfully" collects multiple events into arrays... flatten them :) + let flattenedEvents = {}; + for (const e of Object.values(events)) { + if (Array.isArray(e)) { + for (const n of e) { + flattenedEvents[n.logIndex] = n; + } + } else { + flattenedEvents[e.logIndex] = e; + } + } + + return Object.values(flattenedEvents) + .map(value => { + // Handle MKR events independently (Pot and Vat called by cDai) + if (value.raw.topics.length === 4) { + const callerAddress = this.web3.utils.toChecksumAddress( + "0x" + value.raw.topics[1].slice(26) + ); + return { + address: contractNames[value.address], + eventName: null, + returnValues: { + selector: value.raw.topics[0].slice(0, 10), + caller: + callerAddress in contractNames + ? contractNames[callerAddress] + : callerAddress, + arg1: value.raw.topics[2], + arg2: value.raw.topics[3] + } + }; + } + + const topic = value.raw.topics[0]; + const log = constants.EVENT_DETAILS[topic]; + + return { + address: contractNames[value.address], + eventName: log.name, + returnValues: this.web3.eth.abi.decodeLog( + log.abi, + value.raw.data, + value.raw.topics.slice(1) + ) + }; + }) + .filter(value => value !== null); + } +} + +module.exports = { + Tester, + longer +}; diff --git a/scripts/test/web3.js b/scripts/test/web3.js new file mode 100644 index 0000000..77443e1 --- /dev/null +++ b/scripts/test/web3.js @@ -0,0 +1,9 @@ +const connectionConfig = require('../../truffle-config.js'); + +const connection = connectionConfig.networks['development']; + +const web3 = connection.provider; + +module.exports = { + web3, +}; From ec4715452ffeb35210cdfcaa051556f904b801d3 Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Thu, 6 Feb 2020 14:25:50 -0800 Subject: [PATCH 10/47] remove owner variables and start using tester class --- scripts/test/deploy.js | 78 ++++--------- scripts/test/testHelpers.js | 218 +++++++++--------------------------- 2 files changed, 79 insertions(+), 217 deletions(-) diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index d7c983a..0ce4d7d 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -3,6 +3,7 @@ var fs = require('fs') var util = require('ethereumjs-util') const constants = require('./constants.js') const { web3 } = require("./web3"); +const { Tester } = require("./testHelpers"); let DharmaUpgradeBeaconArtifact; let DharmaUpgradeBeaconControllerArtifact; @@ -599,49 +600,18 @@ module.exports = {test: async function (testingContext) { targetCodeCheckAddress ) - // get available addresses and assign them to various roles - const addresses = await web3.eth.getAccounts() - if (addresses.length < 1) { - console.log('cannot find enough addresses to run tests!') - process.exit(1) - } - - let latestBlock = await web3.eth.getBlock('latest') - - const originalAddress = addresses[0] + + const tester = new Tester(testingContext); + await tester.init(); - let address = await setupNewDefaultAddress( - '0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed' - ) - - let addressTwo = await setupNewDefaultAddress( - '0xf00df00df00df00df00df00df00df00df00df00df00df00df00df00df00df00d' - ) - - const ownerOne = await setupNewDefaultAddress( - constants.MOCK_OWNER_PRIVATE_KEYS[0] - ) - const ownerTwo = await setupNewDefaultAddress( - constants.MOCK_OWNER_PRIVATE_KEYS[1] - ) - const ownerThree = await setupNewDefaultAddress( - constants.MOCK_OWNER_PRIVATE_KEYS[2] - ) - const ownerFour = await setupNewDefaultAddress( - constants.MOCK_OWNER_PRIVATE_KEYS[3] - ) - const ownerFive = await setupNewDefaultAddress( - constants.MOCK_OWNER_PRIVATE_KEYS[4] - ) - const gasLimit = latestBlock.gasLimit console.log('funding initial create2 contract deployer address...') await web3.eth.sendTransaction({ - from: originalAddress, + from: tester.originalAddress, to: constants.KEYLESS_CREATE2_DEPLOYER_ADDRESS, value: web3.utils.toWei('0.01', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : gasLimit - 1, + gas: (testingContext !== 'coverage') ? '0x5208' : tester.gasLimit - 1, gasPrice: 1 }) @@ -754,10 +724,10 @@ module.exports = {test: async function (testingContext) { if (shouldSucceed) { console.error(error) } - return gasLimit + return tester.gasLimit }) - if (deployGas > gasLimit) { + if (deployGas > tester.gasLimit) { console.error(` ✘ ${title}: deployment costs exceed block gas limit!`) process.exit(1) } @@ -845,7 +815,7 @@ module.exports = {test: async function (testingContext) { assertionCallback = (value) => {} } if (typeof(from) === 'undefined') { - from = address + from = tester.address } if (typeof(value) === 'undefined') { value = 0 @@ -853,7 +823,7 @@ module.exports = {test: async function (testingContext) { if (typeof(gas) === 'undefined' && callOrSend !== 'deploy') { gas = 6009006 if (testingContext === 'coverage') { - gas = gasLimit - 1 + gas = tester.gasLimit - 1 } } let ok = false @@ -935,7 +905,7 @@ module.exports = {test: async function (testingContext) { await web3.eth.accounts.wallet.add(pubKey) await web3.eth.sendTransaction({ - from: originalAddress, + from: tester.originalAddress, to: pubKey.address, value: 10 ** 18, gas: '0x5208', @@ -959,8 +929,8 @@ module.exports = {test: async function (testingContext) { var block = await web3.eth.getBlock("latest") while (iterations > 0 && block.gasLimit < necessaryGas) { await web3.eth.sendTransaction({ - from: originalAddress, - to: originalAddress, + from: tester.originalAddress, + to: tester.originalAddress, value: '0x01', gas: '0x5208', gasPrice: '0x4A817C800' @@ -975,7 +945,7 @@ module.exports = {test: async function (testingContext) { async function getDeployGas(dataPayload) { await web3.eth.estimateGas({ - from: address, + from: tester.address, data: dataPayload }).catch(async error => { if ( @@ -990,7 +960,7 @@ module.exports = {test: async function (testingContext) { }) deployGas = await web3.eth.estimateGas({ - from: address, + from: tester.address, data: dataPayload }) @@ -1102,10 +1072,10 @@ module.exports = {test: async function (testingContext) { // deploy a mock code check contract using the initial create2 deployer console.log(' ✓ deploying test contract via create2 contract...') const DeploymentTx = await web3.eth.sendTransaction({ - from: originalAddress, + from: tester.originalAddress, to: constants.KEYLESS_CREATE2_ADDRESS, value: 0, - gas: (testingContext !== 'coverage') ? 1500051 : gasLimit - 1, + gas: (testingContext !== 'coverage') ? 1500051 : tester.gasLimit - 1, gasPrice: 1, data: MockCodeCheckArtifact.bytecode }) @@ -1134,10 +1104,10 @@ module.exports = {test: async function (testingContext) { ' initial create2 contract...' ) await web3.eth.sendTransaction({ - from: originalAddress, + from: tester.originalAddress, to: constants.KEYLESS_CREATE2_ADDRESS, value: '0', - gas: (testingContext !== 'coverage') ? '608261' : gasLimit - 1, + gas: (testingContext !== 'coverage') ? '608261' : tester.gasLimit - 1, gasPrice: 1, data: constants.IMMUTABLE_CREATE2_FACTORY_CREATION_CODE }); @@ -1193,10 +1163,10 @@ module.exports = {test: async function (testingContext) { if (currentIndestructibleRegistryRuntimeHash !== constants.INDESTRUCTIBLE_REGISTRY_RUNTIME_HASH) { console.log(` ✓ submitting indestructible registry deployment through immutable create2 contract...`) await web3.eth.sendTransaction({ - from: originalAddress, + from: tester.originalAddress, to: constants.IMMUTABLE_CREATE2_FACTORY_ADDRESS, value: '0', - gas: (testingContext !== 'coverage') ? '3000000' : gasLimit - 1, + gas: (testingContext !== 'coverage') ? '3000000' : tester.gasLimit - 1, gasPrice: 1, data: constants.INDESTRUCTIBLE_REGISTRY_CREATION_TX }); @@ -2871,7 +2841,7 @@ module.exports = {test: async function (testingContext) { DharmaAccountRecoveryMultisigDeployer, '', 'deploy', - [[ownerOne, ownerTwo, ownerThree, ownerFour]] + [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour]] ) await runTest( @@ -2926,7 +2896,7 @@ module.exports = {test: async function (testingContext) { DharmaKeyRegistryMultisigDeployer, '', 'deploy', - [[ownerOne, ownerTwo, ownerThree, ownerFour, ownerFive]] + [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] ) await runTest( @@ -3344,7 +3314,7 @@ module.exports = {test: async function (testingContext) { DharmaUpgradeMultisigDeployer, '', 'deploy', - [[ownerOne, ownerTwo, ownerThree, ownerFour, ownerFive]] + [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] ) await runTest( diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index c2b226e..e213245 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -1,4 +1,5 @@ -import web3 from "web3"; +const { web3 } = require("./web3"); +const constants = require("./constants"); const SCALING_FACTOR = web3.utils.toBN("1000000000000000000"); const ZERO = web3.utils.toBN("0"); @@ -7,167 +8,58 @@ const NINE = web3.utils.toBN("9"); const TEN = web3.utils.toBN("10"); class Tester { - constructor(provider, testingContext) { - this.web3 = provider; + constructor(testingContext) { this.context = testingContext; this.failed = 0; this.passed = 0; } async init() { - const DharmaDaiDeployer = new this.web3.eth.Contract( - DharmaDaiArtifact.abi - ); - DharmaDaiDeployer.options.data = DharmaDaiArtifact.bytecode; - this.DharmaDaiDeployer = DharmaDaiDeployer; - - const DharmaUSDCDeployer = new this.web3.eth.Contract( - DharmaUSDCArtifact.abi - ); - DharmaUSDCDeployer.options.data = DharmaUSDCArtifact.bytecode; - this.DharmaUSDCDeployer = DharmaUSDCDeployer; - - const DharmaDaiInitializerDeployer = new this.web3.eth.Contract( - DharmaDaiInitializerArtifact.abi - ); - DharmaDaiInitializerDeployer.options.data = - DharmaDaiInitializerArtifact.bytecode; - this.DharmaDaiInitializerDeployer = DharmaDaiInitializerDeployer; - - const DharmaUSDCInitializerDeployer = new this.web3.eth.Contract( - DharmaUSDCInitializerArtifact.abi - ); - DharmaUSDCInitializerDeployer.options.data = - DharmaUSDCInitializerArtifact.bytecode; - this.DharmaUSDCInitializerDeployer = DharmaUSDCInitializerDeployer; - - const UpgradeBeaconControllerDeployer = new this.web3.eth.Contract( - UpgradeBeaconControllerArtifact.abi - ); - UpgradeBeaconControllerDeployer.options.data = - UpgradeBeaconControllerArtifact.bytecode; - this.UpgradeBeaconControllerDeployer = UpgradeBeaconControllerDeployer; - - const UpgradeBeaconDeployer = new this.web3.eth.Contract( - UpgradeBeaconArtifact.abi - ); - UpgradeBeaconDeployer.options.data = UpgradeBeaconArtifact.bytecode; - this.UpgradeBeaconDeployer = UpgradeBeaconDeployer; - - const UpgradeBeaconProxyDeployer = new this.web3.eth.Contract( - UpgradeBeaconProxyArtifact.abi - ); - UpgradeBeaconProxyDeployer.options.data = - UpgradeBeaconProxyArtifact.bytecode; - this.UpgradeBeaconProxyDeployer = UpgradeBeaconProxyDeployer; - - const Scenario0HelperDeployer = new this.web3.eth.Contract( - Scenario0HelperArtifact.abi - ); - Scenario0HelperDeployer.options.data = Scenario0HelperArtifact.bytecode; - this.Scenario0HelperDeployer = Scenario0HelperDeployer; - - const Scenario2HelperDeployer = new this.web3.eth.Contract( - Scenario2HelperArtifact.abi - ); - Scenario2HelperDeployer.options.data = Scenario2HelperArtifact.bytecode; - this.Scenario2HelperDeployer = Scenario2HelperDeployer; - - const Scenario5HelperDeployer = new this.web3.eth.Contract( - Scenario5HelperArtifact.abi - ); - Scenario5HelperDeployer.options.data = Scenario5HelperArtifact.bytecode; - this.Scenario5HelperDeployer = Scenario5HelperDeployer; - - const Scenario6HelperDeployer = new this.web3.eth.Contract( - Scenario6HelperArtifact.abi - ); - Scenario6HelperDeployer.options.data = Scenario6HelperArtifact.bytecode; - this.Scenario6HelperDeployer = Scenario6HelperDeployer; - - const Scenario7HelperDeployer = new this.web3.eth.Contract( - Scenario7HelperArtifact.abi - ); - Scenario7HelperDeployer.options.data = Scenario7HelperArtifact.bytecode; - this.Scenario7HelperDeployer = Scenario7HelperDeployer; - - const Scenario9HelperDeployer = new this.web3.eth.Contract( - Scenario9HelperArtifact.abi - ); - Scenario9HelperDeployer.options.data = Scenario9HelperArtifact.bytecode; - this.Scenario9HelperDeployer = Scenario9HelperDeployer; + // get available addresses and assign them to various roles + const addresses = await web3.eth.getAccounts(); + if (addresses.length < 1) { + console.log('cannot find enough addresses to run tests!'); + process.exit(1) + } - const Scenario11HelperDeployer = new this.web3.eth.Contract( - Scenario11HelperArtifact.abi - ); - Scenario11HelperDeployer.options.data = - Scenario11HelperArtifact.bytecode; - this.Scenario11HelperDeployer = Scenario11HelperDeployer; + let latestBlock = await web3.eth.getBlock('latest'); - const MockERC1271Deployer = new this.web3.eth.Contract( - MockERC1271Artifact.abi - ); - MockERC1271Deployer.options.data = MockERC1271Artifact.bytecode; - this.MockERC1271Deployer = MockERC1271Deployer; + this.originalAddress = addresses[0]; - this.DAI = new this.web3.eth.Contract( - IERC20Artifact.abi, - constants.DAI_MAINNET_ADDRESS + this.address = await this.setupNewDefaultAddress( + '0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed' ); - this.USDC = new this.web3.eth.Contract( - IERC20Artifact.abi, - constants.USDC_MAINNET_ADDRESS + let addressTwo = await this.setupNewDefaultAddress( + '0xf00df00df00df00df00df00df00df00df00df00df00df00df00df00df00df00d' ); - this.CDAI = new this.web3.eth.Contract( - ICTokenArtifact.abi, - constants.CDAI_MAINNET_ADDRESS + this.ownerOne = await this.setupNewDefaultAddress( + constants.MOCK_OWNER_PRIVATE_KEYS[0] ); - - this.CUSDC = new this.web3.eth.Contract( - ICTokenArtifact.abi, - constants.CUSDC_MAINNET_ADDRESS + this.ownerTwo = await this.setupNewDefaultAddress( + constants.MOCK_OWNER_PRIVATE_KEYS[1] ); - - this.UNISWAP_DAI = new this.web3.eth.Contract( - UniswapArtifact.abi, - constants.UNISWAP_DAI_MAINNET_ADDRESS + this.ownerThree = await this.setupNewDefaultAddress( + constants.MOCK_OWNER_PRIVATE_KEYS[2] ); - - this.UNISWAP_USDC = new this.web3.eth.Contract( - UniswapArtifact.abi, - constants.UNISWAP_USDC_MAINNET_ADDRESS + this.ownerFour = await this.setupNewDefaultAddress( + constants.MOCK_OWNER_PRIVATE_KEYS[3] ); - - const addresses = await this.web3.eth.getAccounts(); - if (addresses.length < 1) { - console.log("cannot find enough addresses to run tests!"); - process.exit(1); - } - - this.originalAddress = addresses[0]; - - this.address = await this.setupNewDefaultAddress( - `0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed` + this.ownerFive = await this.setupNewDefaultAddress( + constants.MOCK_OWNER_PRIVATE_KEYS[4] ); - this.addressTwo = await this.setupNewDefaultAddress( - `0xf00df00df00df00df00df00df00df00df00df00df00df00df00df00df00df00d` - ); - - let latestBlock = await this.web3.eth.getBlock("latest"); - - this.gasLimit = latestBlock.gasLimit; + this.gasLimit = latestBlock.gasLimit } async setupNewDefaultAddress(newPrivateKey) { - const pubKey = await this.web3.eth.accounts.privateKeyToAccount( + const pubKey = await web3.eth.accounts.privateKeyToAccount( newPrivateKey ); - await this.web3.eth.accounts.wallet.add(pubKey); + await web3.eth.accounts.wallet.add(pubKey); - await this.web3.eth.sendTransaction({ + await web3.eth.sendTransaction({ from: this.originalAddress, to: pubKey.address, value: 2 * 10 ** 18, @@ -177,6 +69,7 @@ class Tester { return pubKey.address; } + async raiseGasLimit(necessaryGas) { let iterations = 9999; @@ -189,16 +82,16 @@ class Tester { } // bring up gas limit if necessary by doing additional transactions - let block = await this.web3.eth.getBlock("latest"); + let block = await web3.eth.getBlock("latest"); while (iterations > 0 && block.gasLimit < necessaryGas) { - await this.web3.eth.sendTransaction({ + await web3.eth.sendTransaction({ from: originalAddress, to: originalAddress, value: "0x01", gas: "0x5208", gasPrice: "0x4A817C800" }); - block = await this.web3.eth.getBlock("latest"); + block = await web3.eth.getBlock("latest"); iterations--; } @@ -207,7 +100,7 @@ class Tester { } async getDeployGas(dataPayload) { - await this.web3.eth + await web3.eth .estimateGas({ from: address, data: dataPayload @@ -223,7 +116,7 @@ class Tester { } }); - return this.web3.eth.estimateGas({ + return web3.eth.estimateGas({ from: address, data: dataPayload }); @@ -231,7 +124,7 @@ class Tester { async advanceTime(time) { return new Promise((resolve, reject) => { - this.web3.currentProvider.send( + web3.currentProvider.send( { jsonrpc: "2.0", method: "evm_increaseTime", @@ -250,7 +143,7 @@ class Tester { async takeSnapshot() { return new Promise((resolve, reject) => { - this.web3.currentProvider.send( + web3.currentProvider.send( { jsonrpc: "2.0", method: "evm_snapshot", @@ -268,7 +161,7 @@ class Tester { async revertToSnapShot(id) { return new Promise((resolve, reject) => { - this.web3.currentProvider.send( + web3.currentProvider.send( { jsonrpc: "2.0", method: "evm_revert", @@ -287,7 +180,7 @@ class Tester { async advanceBlock() { return new Promise((resolve, reject) => { - this.web3.currentProvider.send( + web3.currentProvider.send( { jsonrpc: "2.0", method: "evm_mine", @@ -305,7 +198,7 @@ class Tester { async rpc(request) { return new Promise((okay, fail) => - this.web3.currentProvider.send(request, (err, res) => + web3.currentProvider.send(request, (err, res) => err ? fail(err) : okay(res) ) ); @@ -328,7 +221,7 @@ class Tester { const accountNonce = typeof nonce === "undefined" - ? await this.web3.eth.getTransactionCount(this.address) + ? await web3.eth.getTransactionCount(this.address) : nonce; const extraBlocks = blocksToAdvance - 1; @@ -362,7 +255,7 @@ class Tester { process.exit(1); } - const dummyTxReceipt = await this.web3.eth.sendTransaction({ + const dummyTxReceipt = await web3.eth.sendTransaction({ from: this.address, to: this.address, data: "0x", @@ -372,22 +265,22 @@ class Tester { nonce: accountNonce }); - return await this.web3.eth.getBlock(dummyTxReceipt.blockHash); + return await web3.eth.getBlock(dummyTxReceipt.blockHash); } async advanceTimeAndBlock(time) { await this.advanceTime(time); await this.advanceBlock(); - return Promise.resolve(this.web3.eth.getBlock("latest")); + return Promise.resolve(web3.eth.getBlock("latest")); } async advanceTimeAndBlocks(blocks, nonce) { if (blocks < 2) { return reject("must advance by at least two blocks."); } - //let block = await this.web3.eth.getBlock(await this.getLatestBlockNumber()) + //let block = await web3.eth.getBlock(await this.getLatestBlockNumber()) await this.advanceTime(blocks * 15); - //block = await this.web3.eth.getBlock(await this.getLatestBlockNumber()) + //block = await web3.eth.getBlock(await this.getLatestBlockNumber()) // next block must be extracted from this function ('getBlock' breaks) return await this.advanceBlocks(blocks - 1, nonce); @@ -396,36 +289,36 @@ class Tester { signHashedPrefixedHexString(hashedHexString, account) { const sig = util.ecsign( util.toBuffer( - this.web3.utils.keccak256( + web3.utils.keccak256( // prefix => "\x19Ethereum Signed Message:\n32" "0x19457468657265756d205369676e6564204d6573736167653a0a3332" + hashedHexString.slice(2), { encoding: "hex" } ) ), - util.toBuffer(this.web3.eth.accounts.wallet[account].privateKey) + util.toBuffer(web3.eth.accounts.wallet[account].privateKey) ); return ( util.bufferToHex(sig.r) + util.bufferToHex(sig.s).slice(2) + - this.web3.utils.toHex(sig.v).slice(2) + web3.utils.toHex(sig.v).slice(2) ); } signHashedPrefixedHashedHexString(hexString, account) { const sig = util.ecsign( util.toBuffer( - this.web3.utils.keccak256( + web3.utils.keccak256( // prefix => "\x19Ethereum Signed Message:\n32" "0x19457468657265756d205369676e6564204d6573736167653a0a3332" + - this.web3.utils + web3.utils .keccak256(hexString, { encoding: "hex" }) .slice(2), { encoding: "hex" } ) ), - util.toBuffer(this.web3.eth.accounts.wallet[account].privateKey) + util.toBuffer(web3.eth.accounts.wallet[account].privateKey) ); return ( @@ -581,7 +474,7 @@ class Tester { assertionCallback ) { let deployData = instance.deploy({ arguments: args }).encodeABI(); - let deployGas = await this.web3.eth + let deployGas = await web3.eth .estimateGas({ from: from, data: deployData @@ -803,7 +696,7 @@ class Tester { .map(value => { // Handle MKR events independently (Pot and Vat called by cDai) if (value.raw.topics.length === 4) { - const callerAddress = this.web3.utils.toChecksumAddress( + const callerAddress = web3.utils.toChecksumAddress( "0x" + value.raw.topics[1].slice(26) ); return { @@ -827,7 +720,7 @@ class Tester { return { address: contractNames[value.address], eventName: log.name, - returnValues: this.web3.eth.abi.decodeLog( + returnValues: web3.eth.abi.decodeLog( log.abi, value.raw.data, value.raw.topics.slice(1) @@ -840,5 +733,4 @@ class Tester { module.exports = { Tester, - longer }; From 2bb57147c36e5c94bff318e5ee4d30add80ee81f Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Thu, 6 Feb 2020 14:52:24 -0800 Subject: [PATCH 11/47] remove all helpers from deploy file --- scripts/test/deploy.js | 765 +++++++++--------------------------- scripts/test/testHelpers.js | 1 + 2 files changed, 182 insertions(+), 584 deletions(-) diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index 0ce4d7d..349a52c 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -600,12 +600,11 @@ module.exports = {test: async function (testingContext) { targetCodeCheckAddress ) - + const tester = new Tester(testingContext); await tester.init(); - console.log('funding initial create2 contract deployer address...') await web3.eth.sendTransaction({ from: tester.originalAddress, @@ -617,408 +616,14 @@ module.exports = {test: async function (testingContext) { console.log('running tests...') - // ************************** helper functions **************************** // - async function send( - title, - instance, - method, - args, - from, - value, - gas, - gasPrice, - shouldSucceed, - assertionCallback - ) { - const receipt = await instance.methods[method](...args).send({ - from: from, - value: value, - gas: gas, - gasPrice: gasPrice - }).on('confirmation', (confirmationNumber, r) => { - confirmations[r.transactionHash] = confirmationNumber - }).catch(error => { - if (shouldSucceed) { - console.error(error) - } - return {status: false} - }) - - if (receipt.status !== shouldSucceed) { - return false - } else if (!shouldSucceed) { - return true - } - - let assertionsPassed - try { - assertionCallback(receipt) - assertionsPassed = true - } catch(error) { - assertionsPassed = false - console.log(error); - } - - return assertionsPassed - } - - async function call( - title, - instance, - method, - args, - from, - value, - gas, - gasPrice, - shouldSucceed, - assertionCallback - ) { - let succeeded = true - returnValues = await instance.methods[method](...args).call({ - from: from, - value: value, - gas: gas, - gasPrice: gasPrice - }).catch(error => { - if (shouldSucceed) { - console.error(error) - } - succeeded = false - }) - - if (succeeded !== shouldSucceed) { - return false - } else if (!shouldSucceed) { - return true - } - - let assertionsPassed - try { - assertionCallback(returnValues) - assertionsPassed = true - } catch(error) { - assertionsPassed = false - console.log(error); - } - - return assertionsPassed - } - - async function deploy( - title, - instance, - args, - from, - value, - gas, - gasPrice, - shouldSucceed, - assertionCallback - ) { - let deployData = instance.deploy({arguments: args}).encodeABI() - let deployGas = await web3.eth.estimateGas({ - from: from, - data: deployData - }).catch(error => { - if (shouldSucceed) { - console.error(error) - } - return tester.gasLimit - }) - - if (deployGas > tester.gasLimit) { - console.error(` ✘ ${title}: deployment costs exceed block gas limit!`) - process.exit(1) - } - - if (typeof(gas) === 'undefined') { - gas = deployGas - } - - if (deployGas > gas) { - console.error(` ✘ ${title}: deployment costs exceed supplied gas.`) - process.exit(1) - } - - let signed - let deployHash - let receipt - const contract = await instance.deploy({arguments: args}).send({ - from: from, - gas: gas, - gasPrice: gasPrice - }).on('transactionHash', hash => { - deployHash = hash - }).on('receipt', r => { - receipt = r - }).on('confirmation', (confirmationNumber, r) => { - confirmations[r.transactionHash] = confirmationNumber - }).catch(error => { - if (shouldSucceed) { - console.error(error) - } - - receipt = {status: false} - }) - - if (receipt.status !== shouldSucceed) { - if (contract) { - return [false, contract, gas] - } - return [false, instance, gas] - } else if (!shouldSucceed) { - if (contract) { - return [true, contract, gas] - } - return [true, instance, gas] - } - - assert.ok(receipt.status) - - let assertionsPassed - try { - assertionCallback(receipt) - assertionsPassed = true - } catch(error) { - assertionsPassed = false - } - - if (contract) { - return [assertionsPassed, contract, gas] - } - return [assertionsPassed, instance, gas] - } - - async function runTest( - title, - instance, - method, - callOrSend, - args, - shouldSucceed, - assertionCallback, - from, - value, - gas - ) { - if (typeof(callOrSend) === 'undefined') { - callOrSend = 'send' - } - if (typeof(args) === 'undefined') { - args = [] - } - if (typeof(shouldSucceed) === 'undefined') { - shouldSucceed = true - } - if (typeof(assertionCallback) === 'undefined') { - assertionCallback = (value) => {} - } - if (typeof(from) === 'undefined') { - from = tester.address - } - if (typeof(value) === 'undefined') { - value = 0 - } - if (typeof(gas) === 'undefined' && callOrSend !== 'deploy') { - gas = 6009006 - if (testingContext === 'coverage') { - gas = tester.gasLimit - 1 - } - } - let ok = false - let contract - let deployGas - if (callOrSend === 'send') { - ok = await send( - title, - instance, - method, - args, - from, - value, - gas, - 1, - shouldSucceed, - assertionCallback - ) - } else if (callOrSend === 'call') { - ok = await call( - title, - instance, - method, - args, - from, - value, - gas, - 1, - shouldSucceed, - assertionCallback - ) - } else if (callOrSend === 'deploy') { - const fields = await deploy( - title, - instance, - args, - from, - value, - gas, - 1, - shouldSucceed, - assertionCallback - ) - ok = fields[0] - contract = fields[1] - deployGas = fields[2] - } else { - console.error('must use call, send, or deploy!') - process.exit(1) - } - - if (ok) { - console.log( - ` ✓ ${ - callOrSend === 'deploy' ? 'successful ' : '' - }${title}${ - callOrSend === 'deploy' ? ` (${deployGas} gas)` : '' - }` - ) - passed++ - } else { - console.log( - ` ✘ ${ - callOrSend === 'deploy' ? 'failed ' : '' - }${title}${ - callOrSend === 'deploy' ? ` (${deployGas} gas)` : '' - }` - ) - failed++ - } - - if (contract) { - return contract - } - } - - async function setupNewDefaultAddress(newPrivateKey) { - const pubKey = await web3.eth.accounts.privateKeyToAccount(newPrivateKey) - await web3.eth.accounts.wallet.add(pubKey) - - await web3.eth.sendTransaction({ - from: tester.originalAddress, - to: pubKey.address, - value: 10 ** 18, - gas: '0x5208', - gasPrice: '0x4A817C800' - }) - - return pubKey.address - } - - async function raiseGasLimit(necessaryGas) { - iterations = 9999 - if (necessaryGas > 8000000) { - console.error('the gas needed is too high!') - process.exit(1) - } else if (typeof necessaryGas === 'undefined') { - iterations = 20 - necessaryGas = 8000000 - } - - // bring up gas limit if necessary by doing additional transactions - var block = await web3.eth.getBlock("latest") - while (iterations > 0 && block.gasLimit < necessaryGas) { - await web3.eth.sendTransaction({ - from: tester.originalAddress, - to: tester.originalAddress, - value: '0x01', - gas: '0x5208', - gasPrice: '0x4A817C800' - }) - var block = await web3.eth.getBlock("latest") - iterations-- - } - - console.log("raising gasLimit, currently at " + block.gasLimit) - return block.gasLimit - } - - async function getDeployGas(dataPayload) { - await web3.eth.estimateGas({ - from: tester.address, - data: dataPayload - }).catch(async error => { - if ( - error.message === ( - 'Returned error: gas required exceeds allowance or always failing ' + - 'transaction' - ) - ) { - await raiseGasLimit() - await getDeployGas(dataPayload) - } - }) - - deployGas = await web3.eth.estimateGas({ - from: tester.address, - data: dataPayload - }) - - return deployGas - } - - function signHashedPrefixedHexString(hashedHexString, account) { - const hashedPrefixedMessage = web3.utils.keccak256( - // prefix => "\x19Ethereum Signed Message:\n32" - "0x19457468657265756d205369676e6564204d6573736167653a0a3332" + - hashedHexString.slice(2), - {encoding: "hex"} - ) - - const sig = util.ecsign( - util.toBuffer(hashedPrefixedMessage), - util.toBuffer(web3.eth.accounts.wallet[account].privateKey) - ) - - return ( - util.bufferToHex(sig.r) + - util.bufferToHex(sig.s).slice(2) + - web3.utils.toHex(sig.v).slice(2) - ) - } - - function signHashedPrefixedHashedHexString(hexString, account) { - const hashedPrefixedHashedMessage = web3.utils.keccak256( - // prefix => "\x19Ethereum Signed Message:\n32" - "0x19457468657265756d205369676e6564204d6573736167653a0a3332" + - web3.utils.keccak256(hexString, {encoding: "hex"}).slice(2), - {encoding: "hex"} - ) - - const sig = util.ecsign( - util.toBuffer(hashedPrefixedHashedMessage), - util.toBuffer(web3.eth.accounts.wallet[account].privateKey) - ) - - return ( - util.bufferToHex(sig.r) + - util.bufferToHex(sig.s).slice(2) + - web3.utils.toHex(sig.v).slice(2) - ) - } - - // *************************** deploy contracts *************************** // - let deployGas - let selfAddress - - const MockCodeCheck = await runTest( + const MockCodeCheck = await tester.runTest( `MockCodeCheck contract deployment`, MockCodeCheckDeployer, '', 'deploy' ) - await runTest( + await tester.runTest( 'Deployed MockCodeCheck code is correct', MockCodeCheck, 'code', @@ -1030,7 +635,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'Deployed MockCodeCheck has correct extcodehash', MockCodeCheck, 'hash', @@ -1049,7 +654,7 @@ module.exports = {test: async function (testingContext) { ) let currentKeylessCreate2Runtime; - await runTest( + await tester.runTest( 'Current runtime code at address of initial create2 factory can be retrieved', MockCodeCheck, 'code', @@ -1067,7 +672,7 @@ module.exports = {test: async function (testingContext) { await web3.eth.sendSignedTransaction( constants.KEYLESS_CREATE2_DEPLOYMENT_TRANSACTION ); - passed++ + tester.passed++ // deploy a mock code check contract using the initial create2 deployer console.log(' ✓ deploying test contract via create2 contract...') @@ -1079,13 +684,13 @@ module.exports = {test: async function (testingContext) { gasPrice: 1, data: MockCodeCheckArtifact.bytecode }) - passed++ + tester.passed++ } else { console.log(' ✓ initial create2 contract already deployed, skipping...') } let currentInefficientImmutableCreate2FactoryRuntimeHash; - await runTest( + await tester.runTest( 'Current runtime hash at address of inefficient immutable create2 factory can be retrieved', MockCodeCheck, 'hash', @@ -1111,13 +716,13 @@ module.exports = {test: async function (testingContext) { gasPrice: 1, data: constants.IMMUTABLE_CREATE2_FACTORY_CREATION_CODE }); - passed++ + tester.passed++ } else { console.log(' ✓ inefficient immutable create2 factory contract already deployed, skipping...') } let currentImmutableCreate2FactoryRuntimeHash; - await runTest( + await tester.runTest( 'Current runtime hash at address of immutable create2 factory can be retrieved', MockCodeCheck, 'hash', @@ -1131,7 +736,7 @@ module.exports = {test: async function (testingContext) { // submit the immutable create2 deployment transaction if needed if (currentImmutableCreate2FactoryRuntimeHash !== constants.IMMUTABLE_CREATE2_FACTORY_RUNTIME_HASH) { - await runTest( + await tester.runTest( `submitting immutable create2 factory deployment through initial create2 contract...`, InefficientImmutableCreate2Factory, 'safeCreate2', @@ -1147,7 +752,7 @@ module.exports = {test: async function (testingContext) { } let currentIndestructibleRegistryRuntimeHash; - await runTest( + await tester.runTest( 'Current runtime hash at address of indestructible registry can be retrieved', MockCodeCheck, 'hash', @@ -1170,14 +775,14 @@ module.exports = {test: async function (testingContext) { gasPrice: 1, data: constants.INDESTRUCTIBLE_REGISTRY_CREATION_TX }); - passed++ + tester.passed++ } else { console.log(' ✓ indestructible registry contract already deployed, skipping...') } // BEGIN ACTUAL DEPLOYMENT TESTS - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController contract deployment fails before other deployments`, DharmaUpgradeBeaconControllerCoverageDeployer, '', @@ -1186,7 +791,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager contract deployment fails before other deployments`, DharmaUpgradeBeaconControllerManagerCoverageDeployer, '', @@ -1196,7 +801,7 @@ module.exports = {test: async function (testingContext) { ) let currentUpgradeBeaconEnvoyCode; - await runTest( + await tester.runTest( 'Checking Upgrade Beacon Envoy runtime code', MockCodeCheck, 'code', @@ -1211,7 +816,7 @@ module.exports = {test: async function (testingContext) { if ( currentUpgradeBeaconEnvoyCode !== constants.UPGRADE_BEACON_ENVOY_RUNTIME_CODE ) { - await runTest( + await tester.runTest( `UpgradeBeaconEnvoy contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -1226,7 +831,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `Upgrade Beacon Envoy contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -1238,7 +843,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed Upgrade Beacon Envoy code is correct', MockCodeCheck, 'code', @@ -1251,7 +856,7 @@ module.exports = {test: async function (testingContext) { ) let currentUpgradeBeaconControllerCode; - await runTest( + await tester.runTest( 'Checking Upgrade Beacon Controller runtime code', MockCodeCheck, 'code', @@ -1269,7 +874,7 @@ module.exports = {test: async function (testingContext) { constants.UPGRADE_BEACON_CONTROLLER_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -1287,7 +892,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -1302,7 +907,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed Upgrade Beacon Controller code is correct', MockCodeCheck, 'code', @@ -1318,7 +923,7 @@ module.exports = {test: async function (testingContext) { ) let currentKeyRingUpgradeBeaconControllerCode; - await runTest( + await tester.runTest( 'Checking Key Ring Upgrade Beacon Controller runtime code', MockCodeCheck, 'code', @@ -1336,7 +941,7 @@ module.exports = {test: async function (testingContext) { constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaKeyRingUpgradeBeaconController contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -1354,7 +959,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaKeyRingUpgradeBeaconController contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -1369,7 +974,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed Key Ring Upgrade Beacon Controller code is correct', MockCodeCheck, 'code', @@ -1384,14 +989,14 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController contract deployment`, DharmaUpgradeBeaconControllerDeployer, '', 'deploy' ) - const FailedUpgradeBeaconProxy = await runTest( + const FailedUpgradeBeaconProxy = await tester.runTest( `failure when deploying UpgradeBeaconProxyV1 contract using an undeployed beacon`, UpgradeBeaconProxyV1Deployer, '', @@ -1401,7 +1006,7 @@ module.exports = {test: async function (testingContext) { ) let currentUpgradeBeaconCode; - await runTest( + await tester.runTest( 'Checking Upgrade Beacon runtime code', MockCodeCheck, 'code', @@ -1419,7 +1024,7 @@ module.exports = {test: async function (testingContext) { constants.UPGRADE_BEACON_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaUpgradeBeacon contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -1437,7 +1042,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeacon contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -1452,7 +1057,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed Upgrade Beacon code is correct', MockCodeCheck, 'code', @@ -1467,7 +1072,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeacon contract deployment`, DharmaUpgradeBeaconDeployer, '', @@ -1475,7 +1080,7 @@ module.exports = {test: async function (testingContext) { ) let currentKeyRingUpgradeBeaconCode; - await runTest( + await tester.runTest( 'Checking Upgrade Beacon runtime code', MockCodeCheck, 'code', @@ -1493,7 +1098,7 @@ module.exports = {test: async function (testingContext) { constants.KEY_RING_UPGRADE_BEACON_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaKeyRingUpgradeBeacon contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -1511,7 +1116,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeacon contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -1526,7 +1131,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed Key Ring Upgrade Beacon code is correct', MockCodeCheck, 'code', @@ -1541,7 +1146,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaKeyRingUpgradeBeacon contract deployment`, DharmaKeyRingUpgradeBeaconDeployer, '', @@ -1549,7 +1154,7 @@ module.exports = {test: async function (testingContext) { ) let currentKeyRegistryCode; - await runTest( + await tester.runTest( 'Checking Key Registry runtime code', MockCodeCheck, 'code', @@ -1567,7 +1172,7 @@ module.exports = {test: async function (testingContext) { constants.KEY_REGISTRY_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaKeyRegistryV1 Code contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -1585,7 +1190,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaKeyRegistryV1 contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -1600,7 +1205,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed Key Registry code is correct', MockCodeCheck, 'code', @@ -1616,7 +1221,7 @@ module.exports = {test: async function (testingContext) { ) let currentKeyRegistryV2Code; - await runTest( + await tester.runTest( 'Checking Key Registry V2 runtime code', MockCodeCheck, 'code', @@ -1634,7 +1239,7 @@ module.exports = {test: async function (testingContext) { constants.KEY_REGISTRY_V2_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaKeyRegistryV2 Code contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -1652,7 +1257,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaKeyRegistryV2 contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -1667,7 +1272,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed Key Registry code is correct', MockCodeCheck, 'code', @@ -1683,7 +1288,7 @@ module.exports = {test: async function (testingContext) { ) let currentRevertReasonHelperCode; - await runTest( + await tester.runTest( 'Checking Revert Reason Helper runtime code', MockCodeCheck, 'code', @@ -1698,7 +1303,7 @@ module.exports = {test: async function (testingContext) { if ( currentRevertReasonHelperCode !== SmartWalletRevertReasonHelperV1Artifact.deployedBytecode ) { - await runTest( + await tester.runTest( `SmartWalletRevertReasonHelperV1 Code contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -1713,7 +1318,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `SmartWalletRevertReasonHelperV1 contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -1725,7 +1330,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed Revert Reason Helper code is correct', MockCodeCheck, 'code', @@ -1738,7 +1343,7 @@ module.exports = {test: async function (testingContext) { ) let currentEscapeHatchRegistryCode; - await runTest( + await tester.runTest( 'Checking Escape Hatch Registry runtime code', MockCodeCheck, 'code', @@ -1756,7 +1361,7 @@ module.exports = {test: async function (testingContext) { constants.ESCAPE_HATCH_REGISTRY_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry Code contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -1774,7 +1379,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -1789,7 +1394,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed Escape Hatch Registry code is correct', MockCodeCheck, 'code', @@ -1804,21 +1409,21 @@ module.exports = {test: async function (testingContext) { } ) - const DharmaSmartWalletImplementationV0 = await runTest( + const DharmaSmartWalletImplementationV0 = await tester.runTest( `DharmaSmartWalletImplementationV0 contract deployment`, DharmaSmartWalletImplementationV0Deployer, '', 'deploy' ) - const DharmaSmartWalletImplementationV1 = await runTest( + const DharmaSmartWalletImplementationV1 = await tester.runTest( `DharmaSmartWalletImplementationV1 contract deployment`, DharmaSmartWalletImplementationV1Deployer, '', 'deploy' ) - const DharmaSmartWalletImplementationV2 = await runTest( + const DharmaSmartWalletImplementationV2 = await tester.runTest( `DharmaSmartWalletImplementationV2 contract deployment`, DharmaSmartWalletImplementationV2Deployer, '', @@ -1841,21 +1446,21 @@ module.exports = {test: async function (testingContext) { ) */ - const DharmaSmartWalletImplementationV5 = await runTest( + const DharmaSmartWalletImplementationV5 = await tester.runTest( `DharmaSmartWalletImplementationV5 contract deployment`, DharmaSmartWalletImplementationV5Deployer, '', 'deploy' ) - const DharmaSmartWalletImplementationV6 = await runTest( + const DharmaSmartWalletImplementationV6 = await tester.runTest( `DharmaSmartWalletImplementationV6 contract deployment`, DharmaSmartWalletImplementationV6Deployer, '', 'deploy' ) - const DharmaSmartWalletImplementationV7 = await runTest( + const DharmaSmartWalletImplementationV7 = await tester.runTest( `DharmaSmartWalletImplementationV7 contract deployment`, DharmaSmartWalletImplementationV7Deployer, '', @@ -1871,7 +1476,7 @@ module.exports = {test: async function (testingContext) { ) */ - const DharmaKeyRingImplementationV1 = await runTest( + const DharmaKeyRingImplementationV1 = await tester.runTest( `DharmaKeyRingImplementationV1 contract deployment`, DharmaKeyRingImplementationV1Deployer, '', @@ -1888,7 +1493,7 @@ module.exports = {test: async function (testingContext) { */ let currentAccountRecoveryManagerCode; - await runTest( + await tester.runTest( 'Checking Account Recovery Manager runtime code', MockCodeCheck, 'code', @@ -1906,7 +1511,7 @@ module.exports = {test: async function (testingContext) { constants.ACCOUNT_RECOVERY_MANAGER_V2_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -1924,7 +1529,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -1939,7 +1544,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed Account Recovery Manager code is correct', MockCodeCheck, 'code', @@ -1954,7 +1559,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 contract deployment`, DharmaAccountRecoveryManagerV2Deployer, '', @@ -1962,7 +1567,7 @@ module.exports = {test: async function (testingContext) { ) let currentFactoryCode; - await runTest( + await tester.runTest( 'Checking Factory runtime code', MockCodeCheck, 'code', @@ -1980,7 +1585,7 @@ module.exports = {test: async function (testingContext) { constants.FACTORY_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaSmartWalletFactoryV1 Code contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -1998,7 +1603,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaSmartWalletFactoryV1 contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -2013,7 +1618,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed FactoryV1 code is correct', MockCodeCheck, 'code', @@ -2028,7 +1633,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaSmartWalletFactoryV1 contract deployment`, DharmaSmartWalletFactoryV1Deployer, '', @@ -2037,7 +1642,7 @@ module.exports = {test: async function (testingContext) { ) let currentKeyRingFactoryCode; - await runTest( + await tester.runTest( 'Checking Key Ring Factory runtime code', MockCodeCheck, 'code', @@ -2055,7 +1660,7 @@ module.exports = {test: async function (testingContext) { constants.KEY_RING_FACTORY_V2_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV2 Code contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -2073,7 +1678,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV2 contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -2088,7 +1693,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed KeyRingFactoryV2 code is correct', MockCodeCheck, 'code', @@ -2103,7 +1708,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV2 contract deployment`, DharmaKeyRingFactoryV2Deployer, '', @@ -2112,7 +1717,7 @@ module.exports = {test: async function (testingContext) { ) let currentAdharmaSmartWalletImplementationCode; - await runTest( + await tester.runTest( 'Checking Adharma smart wallet implementation runtime code', MockCodeCheck, 'code', @@ -2130,7 +1735,7 @@ module.exports = {test: async function (testingContext) { constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_METADATA ) ) { - await runTest( + await tester.runTest( `AdharmaSmartWalletImplementation contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -2148,7 +1753,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `AdharmaSmartWalletImplementation contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -2163,7 +1768,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed AdharmaSmartWalletImplementation code is correct', MockCodeCheck, 'code', @@ -2179,16 +1784,8 @@ module.exports = {test: async function (testingContext) { ) - - - - - - - - let currentDharmaDaiUpgradeBeaconControllerCode; - await runTest( + await tester.runTest( 'Checking Dharma Dai Upgrade Beacon Controller runtime code', MockCodeCheck, 'code', @@ -2206,7 +1803,7 @@ module.exports = {test: async function (testingContext) { constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaDaiUpgradeBeaconController contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -2224,7 +1821,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaDaiUpgradeBeaconController contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -2239,7 +1836,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed DharmaDaiUpgradeBeaconController code is correct', MockCodeCheck, 'code', @@ -2255,7 +1852,7 @@ module.exports = {test: async function (testingContext) { ) let currentDharmaUSDCUpgradeBeaconControllerCode; - await runTest( + await tester.runTest( 'Checking Dharma USDC Upgrade Beacon Controller runtime code', MockCodeCheck, 'code', @@ -2273,7 +1870,7 @@ module.exports = {test: async function (testingContext) { constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaUSDCUpgradeBeaconController contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -2291,7 +1888,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUSDCUpgradeBeaconController contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -2306,7 +1903,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed DharmaUSDCUpgradeBeaconController code is correct', MockCodeCheck, 'code', @@ -2322,7 +1919,7 @@ module.exports = {test: async function (testingContext) { ) let currentDharmaDaiUpgradeBeaconCode; - await runTest( + await tester.runTest( 'Checking Dharma Dai Upgrade Beacon Controller runtime code', MockCodeCheck, 'code', @@ -2340,7 +1937,7 @@ module.exports = {test: async function (testingContext) { constants.DHARMA_DAI_UPGRADE_BEACON_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaDaiUpgradeBeacon contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -2358,7 +1955,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaDaiUpgradeBeacon contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -2373,7 +1970,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed DharmaDaiUpgradeBeacon code is correct', MockCodeCheck, 'code', @@ -2389,7 +1986,7 @@ module.exports = {test: async function (testingContext) { ) let currentDharmaUSDCUpgradeBeaconCode; - await runTest( + await tester.runTest( 'Checking Dharma USDC Upgrade Beacon Controller runtime code', MockCodeCheck, 'code', @@ -2407,7 +2004,7 @@ module.exports = {test: async function (testingContext) { constants.DHARMA_USDC_UPGRADE_BEACON_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaUSDCUpgradeBeacon contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -2425,7 +2022,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUSDCUpgradeBeacon contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -2440,7 +2037,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed DharmaUSDCUpgradeBeacon code is correct', MockCodeCheck, 'code', @@ -2456,7 +2053,7 @@ module.exports = {test: async function (testingContext) { ) let currentDharmaDaiCode; - await runTest( + await tester.runTest( 'Checking Dharma Dai Upgrade Beacon Controller runtime code', MockCodeCheck, 'code', @@ -2474,7 +2071,7 @@ module.exports = {test: async function (testingContext) { constants.DHARMA_DAI_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaDai contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -2492,7 +2089,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaDai contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -2507,7 +2104,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed DharmaDai code is correct', MockCodeCheck, 'code', @@ -2523,7 +2120,7 @@ module.exports = {test: async function (testingContext) { ) let currentDharmaUSDCCode; - await runTest( + await tester.runTest( 'Checking Dharma USDC Upgrade Beacon Controller runtime code', MockCodeCheck, 'code', @@ -2541,7 +2138,7 @@ module.exports = {test: async function (testingContext) { constants.DHARMA_USDC_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaUSDC contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -2559,7 +2156,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUSDC contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -2574,7 +2171,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed DharmaUSDC code is correct', MockCodeCheck, 'code', @@ -2589,35 +2186,35 @@ module.exports = {test: async function (testingContext) { } ) - const DharmaDaiInitializerImplementation = await runTest( + const DharmaDaiInitializerImplementation = await tester.runTest( `DharmaDaiInitializer contract deployment`, DharmaDaiInitializerDeployer, '', 'deploy' ) - const DharmaUSDCInitializerImplementation = await runTest( + const DharmaUSDCInitializerImplementation = await tester.runTest( `DharmaUSDCInitializer contract deployment`, DharmaUSDCInitializerDeployer, '', 'deploy' ) - const DharmaDaiImplementationV1 = await runTest( + const DharmaDaiImplementationV1 = await tester.runTest( `DharmaDaiImplementationV1 contract deployment`, DharmaDaiImplementationV1Deployer, '', 'deploy' ) - const DharmaUSDCImplementationV1 = await runTest( + const DharmaUSDCImplementationV1 = await tester.runTest( `DharmaUSDCImplementationV1 contract deployment`, DharmaUSDCImplementationV1Deployer, '', 'deploy' ) - await runTest( + await tester.runTest( 'DharmaDaiUpgradeBeaconController can set initializer implementation', DharmaDaiUpgradeBeaconController, 'upgrade', @@ -2625,13 +2222,13 @@ module.exports = {test: async function (testingContext) { [constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS, DharmaDaiInitializerImplementation.options.address] ) - await runTest( + await tester.runTest( 'DharmaDai can be initialized', DharmaDaiInitializer, 'initialize' ) - await runTest( + await tester.runTest( 'DharmaDaiUpgradeBeaconController can set implementation V1', DharmaDaiUpgradeBeaconController, 'upgrade', @@ -2639,7 +2236,7 @@ module.exports = {test: async function (testingContext) { [constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS, DharmaDaiImplementationV1.options.address] ) - await runTest( + await tester.runTest( 'DharmaUSDCUpgradeBeaconController can set initializer implementation', DharmaUSDCUpgradeBeaconController, 'upgrade', @@ -2647,13 +2244,13 @@ module.exports = {test: async function (testingContext) { [constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS, DharmaUSDCInitializerImplementation.options.address] ) - await runTest( + await tester.runTest( 'DharmaUSDC can be initialized', DharmaUSDCInitializer, 'initialize' ) - await runTest( + await tester.runTest( 'DharmaUSDCUpgradeBeaconController can set implementation V1', DharmaUSDCUpgradeBeaconController, 'upgrade', @@ -2661,7 +2258,7 @@ module.exports = {test: async function (testingContext) { [constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS, DharmaUSDCImplementationV1.options.address] ) - await runTest( + await tester.runTest( `AdharmaSmartWalletImplementation contract deployment`, AdharmaSmartWalletImplementationDeployer, '', @@ -2669,7 +2266,7 @@ module.exports = {test: async function (testingContext) { ) let currentAdharmaKeyRingImplementationCode; - await runTest( + await tester.runTest( 'Checking Adharma key ring implementation runtime code', MockCodeCheck, 'code', @@ -2687,7 +2284,7 @@ module.exports = {test: async function (testingContext) { constants.ADHARMA_KEY_RING_IMPLEMENTATION_METADATA ) ) { - await runTest( + await tester.runTest( `AdharmaKeyRingImplementation contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -2705,7 +2302,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `AdharmaKeyRingImplementation contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -2720,7 +2317,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed AdharmaSmartWalletImplementation code is correct', MockCodeCheck, 'code', @@ -2735,14 +2332,14 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `AdharmaKeyRingImplementation contract deployment`, AdharmaKeyRingImplementationDeployer, '', 'deploy' ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig contract deployment fails if threshold is not met`, DharmaAccountRecoveryMultisigDeployer, '', @@ -2753,7 +2350,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig contract deployment fails if sigs are out of order`, DharmaAccountRecoveryMultisigDeployer, '', @@ -2768,7 +2365,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig contract deployment fails with too many owners`, DharmaAccountRecoveryMultisigDeployer, '', @@ -2789,7 +2386,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig contract deployment fails if threshold is not met`, DharmaAccountRecoveryOperatorMultisigDeployer, '', @@ -2800,7 +2397,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig contract deployment fails if sigs are out of order`, DharmaAccountRecoveryOperatorMultisigDeployer, '', @@ -2815,7 +2412,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig contract deployment fails with too many owners`, DharmaAccountRecoveryOperatorMultisigDeployer, '', @@ -2836,7 +2433,7 @@ module.exports = {test: async function (testingContext) { false ) - const DharmaAccountRecoveryMultisig = await runTest( + const DharmaAccountRecoveryMultisig = await tester.runTest( `DharmaAccountRecoveryMultisig contract deployment`, DharmaAccountRecoveryMultisigDeployer, '', @@ -2844,7 +2441,7 @@ module.exports = {test: async function (testingContext) { [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour]] ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig contract deployment fails if threshold is not met`, DharmaKeyRegistryMultisigDeployer, '', @@ -2855,7 +2452,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig contract deployment fails if sigs are out of order`, DharmaKeyRegistryMultisigDeployer, '', @@ -2870,7 +2467,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig contract deployment fails with too many owners`, DharmaKeyRegistryMultisigDeployer, '', @@ -2891,7 +2488,7 @@ module.exports = {test: async function (testingContext) { false ) - const DharmaKeyRegistryMultisig = await runTest( + const DharmaKeyRegistryMultisig = await tester.runTest( `DharmaKeyRegistryMultisig contract deployment`, DharmaKeyRegistryMultisigDeployer, '', @@ -2899,7 +2496,7 @@ module.exports = {test: async function (testingContext) { [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager contract deployment fails before indestructible registration`, DharmaUpgradeBeaconControllerManagerCoverageDeployer, '', @@ -2908,14 +2505,14 @@ module.exports = {test: async function (testingContext) { false ) - const IndestructibleRegistry = await runTest( + const IndestructibleRegistry = await tester.runTest( `IndestructibleRegistry contract deployment`, IndestructibleRegistryDeployer, '', 'deploy' ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register itself as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -2923,7 +2520,7 @@ module.exports = {test: async function (testingContext) { [IndestructibleRegistry.options.address] ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register the upgrade beacon as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -2931,7 +2528,7 @@ module.exports = {test: async function (testingContext) { [constants.UPGRADE_BEACON_ADDRESS] ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register the upgrade beacon controller as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -2939,7 +2536,7 @@ module.exports = {test: async function (testingContext) { [constants.UPGRADE_BEACON_CONTROLLER_ADDRESS] ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register the key ring upgrade beacon as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -2947,7 +2544,7 @@ module.exports = {test: async function (testingContext) { [constants.KEY_RING_UPGRADE_BEACON_ADDRESS] ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register the key ring upgrade beacon controller as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -2955,7 +2552,7 @@ module.exports = {test: async function (testingContext) { [constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS] ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register the upgrade beacon envoy as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -2963,7 +2560,7 @@ module.exports = {test: async function (testingContext) { [constants.UPGRADE_BEACON_ENVOY_ADDRESS] ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register the account recovery manager as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -2971,7 +2568,7 @@ module.exports = {test: async function (testingContext) { [constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS] ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register DharmaKeyRegistryV1 as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -2979,7 +2576,7 @@ module.exports = {test: async function (testingContext) { [constants.KEY_REGISTRY_ADDRESS] ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register DharmaKeyRegistryV2 as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -2987,7 +2584,7 @@ module.exports = {test: async function (testingContext) { [constants.KEY_REGISTRY_V2_ADDRESS] ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register DharmaEscapeHatchRegistry as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -2995,7 +2592,7 @@ module.exports = {test: async function (testingContext) { [constants.ESCAPE_HATCH_REGISTRY_ADDRESS] ) - await runTest( + await tester.runTest( 'WARNING: IndestructibleRegistry CANNOT register the smart wallet factory as indestructible (even though it is in fact NOT destructible)', IndestructibleRegistry, 'registerAsIndestructible', @@ -3004,7 +2601,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register the Adharma smart wallet implementation as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -3012,7 +2609,7 @@ module.exports = {test: async function (testingContext) { [constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS] ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register the Adharma key ring implementation as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -3020,7 +2617,7 @@ module.exports = {test: async function (testingContext) { [constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS] ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register V0 implementation as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -3038,7 +2635,7 @@ module.exports = {test: async function (testingContext) { ) */ - await runTest( + await tester.runTest( 'IndestructibleRegistry can register V1 implementation as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -3047,7 +2644,7 @@ module.exports = {test: async function (testingContext) { ) if (testingContext !== 'coverage') { - await runTest( + await tester.runTest( 'IndestructibleRegistry can register V2 implementation as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -3073,7 +2670,7 @@ module.exports = {test: async function (testingContext) { ) */ - await runTest( + await tester.runTest( 'IndestructibleRegistry can register V5 implementation as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -3081,7 +2678,7 @@ module.exports = {test: async function (testingContext) { [DharmaSmartWalletImplementationV5.options.address] ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register V6 implementation as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -3089,7 +2686,7 @@ module.exports = {test: async function (testingContext) { [DharmaSmartWalletImplementationV6.options.address] ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register V7 implementation as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -3097,7 +2694,7 @@ module.exports = {test: async function (testingContext) { [DharmaSmartWalletImplementationV7.options.address] ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register V1 key ring implementation as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -3116,7 +2713,7 @@ module.exports = {test: async function (testingContext) { ) */ - await runTest( + await tester.runTest( '"actual" IndestructibleRegistry can register the upgrade beacon as indestructible', ActualIndestructibleRegistry, 'registerAsIndestructible', @@ -3124,7 +2721,7 @@ module.exports = {test: async function (testingContext) { [constants.UPGRADE_BEACON_ADDRESS] ) - await runTest( + await tester.runTest( '"actual" IndestructibleRegistry can register the upgrade beacon controller as indestructible', ActualIndestructibleRegistry, 'registerAsIndestructible', @@ -3132,7 +2729,7 @@ module.exports = {test: async function (testingContext) { [constants.UPGRADE_BEACON_CONTROLLER_ADDRESS] ) - await runTest( + await tester.runTest( '"actual" IndestructibleRegistry can register the key ring upgrade beacon as indestructible', ActualIndestructibleRegistry, 'registerAsIndestructible', @@ -3140,7 +2737,7 @@ module.exports = {test: async function (testingContext) { [constants.KEY_RING_UPGRADE_BEACON_ADDRESS] ) - await runTest( + await tester.runTest( '"actual" IndestructibleRegistry can register the key ring upgrade beacon controller as indestructible', ActualIndestructibleRegistry, 'registerAsIndestructible', @@ -3148,7 +2745,7 @@ module.exports = {test: async function (testingContext) { [constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS] ) - await runTest( + await tester.runTest( '"actual" IndestructibleRegistry can register the Adharma smart wallet implementation as indestructible', ActualIndestructibleRegistry, 'registerAsIndestructible', @@ -3156,7 +2753,7 @@ module.exports = {test: async function (testingContext) { [constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS] ) - await runTest( + await tester.runTest( '"actual" IndestructibleRegistry can register the Adharma key ring implementation as indestructible', ActualIndestructibleRegistry, 'registerAsIndestructible', @@ -3164,14 +2761,14 @@ module.exports = {test: async function (testingContext) { [constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS] ) - const CodeHashCache = await runTest( + const CodeHashCache = await tester.runTest( `CodeHashCache contract deployment`, CodeHashCacheDeployer, '', 'deploy' ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register codehashcache as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -3179,7 +2776,7 @@ module.exports = {test: async function (testingContext) { [CodeHashCache.options.address] ) - await runTest( + await tester.runTest( 'CodeHashCache can register the runtime code hash of the smart wallet factory', CodeHashCache, 'registerCodeHash', @@ -3188,7 +2785,7 @@ module.exports = {test: async function (testingContext) { ) let currentUpgradeBeaconControllerManagerCode; - await runTest( + await tester.runTest( 'Checking Upgrade Beacon Controller Manager runtime code', MockCodeCheck, 'code', @@ -3206,7 +2803,7 @@ module.exports = {test: async function (testingContext) { constants.UPGRADE_BEACON_CONTROLLER_MANAGER_METADATA ) ) { - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager contract address check through immutable create2 factory`, ImmutableCreate2Factory, 'findCreate2Address', @@ -3224,7 +2821,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager contract deployment through immutable create2 factory`, ImmutableCreate2Factory, 'safeCreate2', @@ -3239,7 +2836,7 @@ module.exports = {test: async function (testingContext) { ) } - await runTest( + await tester.runTest( 'Deployed DharmaUpgradeBeaconControllerManager code is correct', MockCodeCheck, 'code', @@ -3254,7 +2851,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'IndestructibleRegistry can register the upgrade beacon controller manager as indestructible', IndestructibleRegistry, 'registerAsIndestructible', @@ -3262,7 +2859,7 @@ module.exports = {test: async function (testingContext) { [constants.UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS] ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig contract deployment fails if threshold is not met`, DharmaUpgradeMultisigDeployer, '', @@ -3273,7 +2870,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig contract deployment fails if sigs are out of order`, DharmaUpgradeMultisigDeployer, '', @@ -3288,7 +2885,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig contract deployment fails with too many owners`, DharmaUpgradeMultisigDeployer, '', @@ -3309,7 +2906,7 @@ module.exports = {test: async function (testingContext) { false ) - const DharmaUpgradeMultisig = await runTest( + const DharmaUpgradeMultisig = await tester.runTest( `DharmaUpgradeMultisig contract deployment`, DharmaUpgradeMultisigDeployer, '', @@ -3317,14 +2914,14 @@ module.exports = {test: async function (testingContext) { [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager contract deployment`, DharmaUpgradeBeaconControllerManagerDeployer, '', 'deploy' ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager contract coverage deployment`, DharmaUpgradeBeaconControllerManagerCoverageDeployer, '', @@ -3332,7 +2929,7 @@ module.exports = {test: async function (testingContext) { ) let currentSaiCode; - await runTest( + await tester.runTest( 'Checking for required external contracts...', MockCodeCheck, 'code', @@ -3346,8 +2943,8 @@ module.exports = {test: async function (testingContext) { if (!currentSaiCode) { console.log( - `completed ${passed + failed} test${passed + failed === 1 ? '' : 's'} ` + - `with ${failed} failure${failed === 1 ? '' : 's'}.` + `completed ${tester.passed + tester.failed} test${tester.passed + tester.failed === 1 ? '' : 's'} ` + + `with ${tester.failed} failure${tester.failed === 1 ? '' : 's'}.` ) console.log( @@ -3355,7 +2952,7 @@ module.exports = {test: async function (testingContext) { 'run against a fork of mainnet using `yarn forkStart` and `yarn test`.' ) - if (failed > 0) { + if (tester.failed > 0) { process.exit(1) } @@ -3365,11 +2962,11 @@ module.exports = {test: async function (testingContext) { console.log( - `completed ${passed + failed} test${passed + failed === 1 ? '' : 's'} ` + - `with ${failed} failure${failed === 1 ? '' : 's'}.` + `completed ${tester.passed + tester.failed} test${tester.passed + tester.failed === 1 ? '' : 's'} ` + + `with ${tester.failed} failure${tester.failed === 1 ? '' : 's'}.` ) - if (failed > 0) { + if (tester.failed > 0) { process.exit(1) } diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index e213245..b56832a 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -1,5 +1,6 @@ const { web3 } = require("./web3"); const constants = require("./constants"); +const assert = require("assert"); const SCALING_FACTOR = web3.utils.toBN("1000000000000000000"); const ZERO = web3.utils.toBN("0"); From 407bfe3870ea88dd195cf82511e13a8c0b6bb8e3 Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Thu, 6 Feb 2020 15:41:35 -0800 Subject: [PATCH 12/47] use checkAndDeploy function --- scripts/test/deploy.js | 328 ++++++++---------------------------- scripts/test/testHelpers.js | 104 ++++++++++++ 2 files changed, 172 insertions(+), 260 deletions(-) diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index 349a52c..cc11d11 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -3,7 +3,7 @@ var fs = require('fs') var util = require('ethereumjs-util') const constants = require('./constants.js') const { web3 } = require("./web3"); -const { Tester } = require("./testHelpers"); +const { Tester, swapMetadataHash, newContractAndSwapMetadataHash } = require("./testHelpers"); let DharmaUpgradeBeaconArtifact; let DharmaUpgradeBeaconControllerArtifact; @@ -66,36 +66,6 @@ const ImmutableCreate2FactoryArtifact = require('../../build/contracts/Immutable const IndestructibleRegistryArtifact = require('../../build/contracts/IndestructibleRegistry.json') const CodeHashCacheArtifact = require('../../build/contracts/CodeHashCache.json') -// used to wait for more confirmations -function longer() { - return new Promise(resolve => {setTimeout(() => {resolve()}, 500)}) -} - -function swapMetadataHash(bytecode, newMetadataHashes) { - const totalBzzrs = bytecode.split(constants.METADATA_IDENTIFIER).length - 1 - - if (totalBzzrs !== newMetadataHashes.length) { - throw("number of metadata hashes to replace must match provided number.") - } - - let startingPoint = bytecode.length - 1; - - for (i = 0; i < totalBzzrs; i++) { - let replacement = constants.METADATA_IDENTIFIER + newMetadataHashes.slice(i)[0] - let lastIndex = bytecode.lastIndexOf( - constants.METADATA_IDENTIFIER, startingPoint - ) - bytecode = ( - bytecode.slice(0, lastIndex) + replacement + bytecode.slice( - lastIndex + replacement.length, bytecode.length - ) - ) - startingPoint = lastIndex - 1; - } - - return bytecode -} - module.exports = {test: async function (testingContext) { if (testingContext === 'coverage') { DharmaUpgradeBeaconEnvoyArtifact = require('../../../build/contracts/DharmaUpgradeBeaconEnvoy.json') @@ -143,11 +113,6 @@ module.exports = {test: async function (testingContext) { SmartWalletRevertReasonHelperV1Artifact = require('../../build/contracts/SmartWalletRevertReasonHelperV1.json') } - let passed = 0 - let failed = 0 - let gasUsage = {} - let counts = {} - /* console.log( swapMetadataHash( @@ -242,25 +207,13 @@ module.exports = {test: async function (testingContext) { constants.REVERT_REASON_HELPER_ADDRESS ) - const IndestructibleRegistryDeployer = new web3.eth.Contract( - IndestructibleRegistryArtifact.abi - ) - IndestructibleRegistryDeployer.options.data = ( - swapMetadataHash( - IndestructibleRegistryArtifact.bytecode, - ['0000000000000000000000000000000000000000000000000000000000000000'] - ) - ) + const IndestructibleRegistryDeployer = newContractAndSwapMetadataHash( + IndestructibleRegistryArtifact + ); - const CodeHashCacheDeployer = new web3.eth.Contract( - CodeHashCacheArtifact.abi - ) - CodeHashCacheDeployer.options.data = ( - swapMetadataHash( - CodeHashCacheArtifact.bytecode, - ['0000000000000000000000000000000000000000000000000000000000000000'] - ) - ) + const CodeHashCacheDeployer = newContractAndSwapMetadataHash( + CodeHashCacheArtifact + ); const DharmaUpgradeMultisigDeployer = new web3.eth.Contract( DharmaUpgradeMultisigArtifact.abi @@ -380,65 +333,31 @@ module.exports = {test: async function (testingContext) { DharmaKeyRingFactoryV2Artifact.bytecode ) - const AdharmaSmartWalletImplementationDeployer = new web3.eth.Contract( - AdharmaSmartWalletImplementationArtifact.abi - ) - AdharmaSmartWalletImplementationDeployer.options.data = ( - swapMetadataHash( - AdharmaSmartWalletImplementationArtifact.bytecode, - ['0000000000000000000000000000000000000000000000000000000000000000'] - ) - ) - - const AdharmaKeyRingImplementationDeployer = new web3.eth.Contract( - AdharmaKeyRingImplementationArtifact.abi - ) - AdharmaKeyRingImplementationDeployer.options.data = ( - swapMetadataHash( - AdharmaKeyRingImplementationArtifact.bytecode, - ['0000000000000000000000000000000000000000000000000000000000000000'] - ) - ) - const DharmaAccountRecoveryManagerV2Deployer = new web3.eth.Contract( - DharmaAccountRecoveryManagerV2Artifact.abi - ) - DharmaAccountRecoveryManagerV2Deployer.options.data = ( - swapMetadataHash( - DharmaAccountRecoveryManagerV2Artifact.bytecode, - ['0000000000000000000000000000000000000000000000000000000000000000'] - ) - ) + const AdharmaSmartWalletImplementationDeployer = newContractAndSwapMetadataHash( + AdharmaSmartWalletImplementationArtifact + ); - const DharmaSmartWalletImplementationV0Deployer = new web3.eth.Contract( - DharmaSmartWalletImplementationV0Artifact.abi - ) - DharmaSmartWalletImplementationV0Deployer.options.data = ( - swapMetadataHash( - DharmaSmartWalletImplementationV0Artifact.bytecode, - ['0000000000000000000000000000000000000000000000000000000000000000'] - ) - ) + const AdharmaKeyRingImplementationDeployer = newContractAndSwapMetadataHash( + AdharmaKeyRingImplementationArtifact + ); - const DharmaSmartWalletImplementationV1Deployer = new web3.eth.Contract( - DharmaSmartWalletImplementationV1Artifact.abi - ) - DharmaSmartWalletImplementationV1Deployer.options.data = ( - swapMetadataHash( - DharmaSmartWalletImplementationV1Artifact.bytecode, - ['0000000000000000000000000000000000000000000000000000000000000000'] - ) - ) - const DharmaSmartWalletImplementationV2Deployer = new web3.eth.Contract( - DharmaSmartWalletImplementationV2Artifact.abi - ) - DharmaSmartWalletImplementationV2Deployer.options.data = ( - swapMetadataHash( - DharmaSmartWalletImplementationV2Artifact.bytecode, - ['0000000000000000000000000000000000000000000000000000000000000000'] - ) - ) + const DharmaAccountRecoveryManagerV2Deployer = newContractAndSwapMetadataHash( + DharmaAccountRecoveryManagerV2Artifact + ); + + const DharmaSmartWalletImplementationV0Deployer = newContractAndSwapMetadataHash( + DharmaSmartWalletImplementationV0Artifact + ); + + const DharmaSmartWalletImplementationV1Deployer = newContractAndSwapMetadataHash( + DharmaSmartWalletImplementationV1Artifact + ); + + const DharmaSmartWalletImplementationV2Deployer = newContractAndSwapMetadataHash( + DharmaSmartWalletImplementationV2Artifact + ); /* const DharmaSmartWalletImplementationV3Deployer = new web3.eth.Contract( @@ -462,35 +381,17 @@ module.exports = {test: async function (testingContext) { ) */ - const DharmaSmartWalletImplementationV5Deployer = new web3.eth.Contract( - DharmaSmartWalletImplementationV5Artifact.abi - ) - DharmaSmartWalletImplementationV5Deployer.options.data = ( - swapMetadataHash( - DharmaSmartWalletImplementationV5Artifact.bytecode, - ['0000000000000000000000000000000000000000000000000000000000000000'] - ) - ) + const DharmaSmartWalletImplementationV5Deployer = newContractAndSwapMetadataHash( + DharmaSmartWalletImplementationV5Artifact + ); - const DharmaSmartWalletImplementationV6Deployer = new web3.eth.Contract( - DharmaSmartWalletImplementationV6Artifact.abi - ) - DharmaSmartWalletImplementationV6Deployer.options.data = ( - swapMetadataHash( - DharmaSmartWalletImplementationV6Artifact.bytecode, - ['0000000000000000000000000000000000000000000000000000000000000000'] - ) - ) + const DharmaSmartWalletImplementationV6Deployer = newContractAndSwapMetadataHash( + DharmaSmartWalletImplementationV6Artifact + ); - const DharmaSmartWalletImplementationV7Deployer = new web3.eth.Contract( - DharmaSmartWalletImplementationV7Artifact.abi - ) - DharmaSmartWalletImplementationV7Deployer.options.data = ( - swapMetadataHash( - DharmaSmartWalletImplementationV7Artifact.bytecode, - ['0000000000000000000000000000000000000000000000000000000000000000'] - ) - ) + const DharmaSmartWalletImplementationV7Deployer = newContractAndSwapMetadataHash( + DharmaSmartWalletImplementationV7Artifact + ); const DharmaDaiInitializerDeployer = new web3.eth.Contract( DharmaDaiInitializerArtifact.abi @@ -532,15 +433,10 @@ module.exports = {test: async function (testingContext) { ) */ - const DharmaKeyRingImplementationV1Deployer = new web3.eth.Contract( - DharmaKeyRingImplementationV1Artifact.abi - ) - DharmaKeyRingImplementationV1Deployer.options.data = ( - swapMetadataHash( - DharmaKeyRingImplementationV1Artifact.bytecode, - ['0000000000000000000000000000000000000000000000000000000000000000'] - ) - ) + + const DharmaKeyRingImplementationV1Deployer = newContractAndSwapMetadataHash( + DharmaKeyRingImplementationV1Artifact + ); /* const DharmaKeyRingImplementationV2Deployer = new web3.eth.Contract( @@ -800,127 +696,39 @@ module.exports = {test: async function (testingContext) { false ) - let currentUpgradeBeaconEnvoyCode; - await tester.runTest( - 'Checking Upgrade Beacon Envoy runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.UPGRADE_BEACON_ENVOY_ADDRESS], - true, - value => { - currentUpgradeBeaconEnvoyCode = value; - } - ) - - if ( - currentUpgradeBeaconEnvoyCode !== constants.UPGRADE_BEACON_ENVOY_RUNTIME_CODE - ) { - await tester.runTest( - `UpgradeBeaconEnvoy contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.UPGRADE_BEACON_ENVOY_SALT, - constants.UPGRADE_BEACON_ENVOY_CREATION_CODE - ], - true, - value => { - assert.strictEqual(value, constants.UPGRADE_BEACON_ENVOY_ADDRESS) - } - ) - - await tester.runTest( - `Upgrade Beacon Envoy contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.UPGRADE_BEACON_ENVOY_SALT, - constants.UPGRADE_BEACON_ENVOY_CREATION_CODE - ] - ) - } - - await tester.runTest( - 'Deployed Upgrade Beacon Envoy code is correct', - MockCodeCheck, - 'code', - 'call', - [constants.UPGRADE_BEACON_ENVOY_ADDRESS], - true, - value => { - assert.strictEqual(value, constants.UPGRADE_BEACON_ENVOY_RUNTIME_CODE) - } - ) - let currentUpgradeBeaconControllerCode; - await tester.runTest( - 'Checking Upgrade Beacon Controller runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.UPGRADE_BEACON_CONTROLLER_ADDRESS], - true, - value => { - currentUpgradeBeaconControllerCode = value; - } - ) + // UpgradeBeaconEnvoy + await tester.checkAndDeploy( + "UpgradeBeaconEnvoy", + constants.UPGRADE_BEACON_ENVOY_ADDRESS, + constants.UPGRADE_BEACON_ENVOY_SALT, + constants.UPGRADE_BEACON_ENVOY_RUNTIME_CODE, + constants.UPGRADE_BEACON_ENVOY_CREATION_CODE, + MockCodeCheck, + ImmutableCreate2Factory + ); - if ( - currentUpgradeBeaconControllerCode !== swapMetadataHash( + // UpgradeBeaconController + const upgradeBeaconControllerRuntimeCode = swapMetadataHash( DharmaUpgradeBeaconControllerArtifact.deployedBytecode, constants.UPGRADE_BEACON_CONTROLLER_METADATA - ) - ) { - await tester.runTest( - `DharmaUpgradeBeaconController contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.UPGRADE_BEACON_CONTROLLER_SALT, - swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.bytecode, - constants.UPGRADE_BEACON_CONTROLLER_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.UPGRADE_BEACON_CONTROLLER_ADDRESS) - } - ) + ); - await tester.runTest( - `DharmaUpgradeBeaconController contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.UPGRADE_BEACON_CONTROLLER_SALT, - swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.bytecode, - constants.UPGRADE_BEACON_CONTROLLER_METADATA - ) - ] - ) - } + const upgradeBeaconControllerCreationCode = swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.bytecode, + constants.UPGRADE_BEACON_CONTROLLER_METADATA + ); + + await tester.checkAndDeploy( + "UpgradeBeaconController", + constants.UPGRADE_BEACON_CONTROLLER_ADDRESS, + constants.UPGRADE_BEACON_CONTROLLER_SALT, + upgradeBeaconControllerRuntimeCode, + upgradeBeaconControllerCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); - await tester.runTest( - 'Deployed Upgrade Beacon Controller code is correct', - MockCodeCheck, - 'code', - 'call', - [DharmaUpgradeBeaconController.options.address], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.deployedBytecode, - constants.UPGRADE_BEACON_CONTROLLER_METADATA - )) - } - ) let currentKeyRingUpgradeBeaconControllerCode; await tester.runTest( diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index b56832a..f2b9d84 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -730,8 +730,112 @@ class Tester { }) .filter(value => value !== null); } + + + async checkAndDeploy( + name, + address, + salt, + runtimeCode, + creationCode, + mockCodeCheck, + create2Factory + ) { + let currentCode; + await this.runTest( + `Checking ${name} runtime code`, + mockCodeCheck, + 'code', + 'call', + [address], + true, + value => { + currentCode = value; + } + ); + + if ( + currentCode !== runtimeCode + ) { + await this.runTest( + `${name} contract address check through immutable create2 factory`, + create2Factory, + 'findCreate2Address', + 'call', + [ + salt, + creationCode + ], + true, + value => { + assert.strictEqual(value, address) + } + ); + + await this.runTest( + `${name} contract deployment through immutable create2 factory`, + create2Factory, + 'safeCreate2', + 'send', + [salt, creationCode] + ); + } + + await this.runTest( + `Deployed ${name} code is correct`, + mockCodeCheck, + 'code', + 'call', + [address], + true, + value => { + assert.strictEqual(value, runtimeCode) + } + ); + } +} + +function swapMetadataHash(bytecode, newMetadataHashes) { + const totalBzzrs = bytecode.split(constants.METADATA_IDENTIFIER).length - 1; + + if (totalBzzrs !== newMetadataHashes.length) { + throw("number of metadata hashes to replace must match provided number."); + } + + let startingPoint = bytecode.length - 1; + + for (let i = 0; i < totalBzzrs; i++) { + let replacement = constants.METADATA_IDENTIFIER + newMetadataHashes.slice(i)[0]; + let lastIndex = bytecode.lastIndexOf( + constants.METADATA_IDENTIFIER, startingPoint + ); + bytecode = ( + bytecode.slice(0, lastIndex) + replacement + bytecode.slice( + lastIndex + replacement.length, bytecode.length + ) + ); + startingPoint = lastIndex - 1; + } + return bytecode; +} + +function newContractAndSwapMetadataHash(artifact) { + const contract = new web3.eth.Contract( + artifact.abi + ); + + contract.options.data = ( + swapMetadataHash( + artifact.bytecode, + ['0000000000000000000000000000000000000000000000000000000000000000'] + ) + ); + + return contract; } module.exports = { Tester, + swapMetadataHash, + newContractAndSwapMetadataHash, }; From 25097ee964f09b5ebe28885c8f5b672770622f8a Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Thu, 6 Feb 2020 17:12:24 -0800 Subject: [PATCH 13/47] use tester on deploy --- scripts/test/deploy.js | 1494 +++++++++------------------------------- 1 file changed, 323 insertions(+), 1171 deletions(-) diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index cc11d11..39dd40f 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -66,7 +66,7 @@ const ImmutableCreate2FactoryArtifact = require('../../build/contracts/Immutable const IndestructibleRegistryArtifact = require('../../build/contracts/IndestructibleRegistry.json') const CodeHashCacheArtifact = require('../../build/contracts/CodeHashCache.json') -module.exports = {test: async function (testingContext) { +async function test(testingContext) { if (testingContext === 'coverage') { DharmaUpgradeBeaconEnvoyArtifact = require('../../../build/contracts/DharmaUpgradeBeaconEnvoy.json') DharmaUpgradeBeaconControllerArtifact = require('../../../build/contracts/DharmaUpgradeBeaconController.json') @@ -708,6 +708,7 @@ module.exports = {test: async function (testingContext) { ImmutableCreate2Factory ); + // UpgradeBeaconController const upgradeBeaconControllerRuntimeCode = swapMetadataHash( DharmaUpgradeBeaconControllerArtifact.deployedBytecode, @@ -730,493 +731,182 @@ module.exports = {test: async function (testingContext) { ); - let currentKeyRingUpgradeBeaconControllerCode; - await tester.runTest( - 'Checking Key Ring Upgrade Beacon Controller runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS], - true, - value => { - currentKeyRingUpgradeBeaconControllerCode = value; - } - ) - - if ( - currentKeyRingUpgradeBeaconControllerCode !== swapMetadataHash( + // KeyRingUpgradeBeaconController + const keyRingUpgradeBeaconControllerRuntimeCode = swapMetadataHash( DharmaUpgradeBeaconControllerArtifact.deployedBytecode, constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_METADATA - ) - ) { - await tester.runTest( - `DharmaKeyRingUpgradeBeaconController contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_SALT, - swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.bytecode, - constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS) - } - ) + ); - await tester.runTest( - `DharmaKeyRingUpgradeBeaconController contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_SALT, - swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.bytecode, - constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_METADATA - ) - ] - ) - } + const keyRingUpgradeBeaconControllerCreationCode = swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.bytecode, + constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_METADATA + ); - await tester.runTest( - 'Deployed Key Ring Upgrade Beacon Controller code is correct', - MockCodeCheck, - 'code', - 'call', - [DharmaKeyRingUpgradeBeaconController.options.address], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.deployedBytecode, - constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_METADATA - )) - } - ) + await tester.checkAndDeploy( + "KeyRingUpgradeBeaconController", + constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS, + constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_SALT, + keyRingUpgradeBeaconControllerRuntimeCode, + keyRingUpgradeBeaconControllerCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); await tester.runTest( `DharmaUpgradeBeaconController contract deployment`, DharmaUpgradeBeaconControllerDeployer, '', 'deploy' - ) + ); - const FailedUpgradeBeaconProxy = await tester.runTest( + await tester.runTest( `failure when deploying UpgradeBeaconProxyV1 contract using an undeployed beacon`, UpgradeBeaconProxyV1Deployer, '', 'deploy', ["0x"], false - ) + ); - let currentUpgradeBeaconCode; - await tester.runTest( - 'Checking Upgrade Beacon runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.UPGRADE_BEACON_ADDRESS], - true, - value => { - currentUpgradeBeaconCode = value; - } - ) - if ( - currentUpgradeBeaconCode !== swapMetadataHash( + // UpgradeBeacon + const upgradeBeaconRuntimeCode = swapMetadataHash( DharmaUpgradeBeaconArtifact.deployedBytecode, constants.UPGRADE_BEACON_METADATA - ) - ) { - await tester.runTest( - `DharmaUpgradeBeacon contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.UPGRADE_BEACON_SALT, - swapMetadataHash( - DharmaUpgradeBeaconArtifact.bytecode, - constants.UPGRADE_BEACON_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.UPGRADE_BEACON_ADDRESS) - } - ) + ); - await tester.runTest( - `DharmaUpgradeBeacon contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.UPGRADE_BEACON_SALT, - swapMetadataHash( - DharmaUpgradeBeaconArtifact.bytecode, - constants.UPGRADE_BEACON_METADATA - ) - ] - ) - } + const upgradeBeaconCreationCode = swapMetadataHash( + DharmaUpgradeBeaconArtifact.bytecode, + constants.UPGRADE_BEACON_METADATA + ); + + await tester.checkAndDeploy( + "UpgradeBeacon", + constants.UPGRADE_BEACON_ADDRESS, + constants.UPGRADE_BEACON_SALT, + upgradeBeaconRuntimeCode, + upgradeBeaconCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); - await tester.runTest( - 'Deployed Upgrade Beacon code is correct', - MockCodeCheck, - 'code', - 'call', - [DharmaUpgradeBeacon.options.address], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaUpgradeBeaconArtifact.deployedBytecode, - constants.UPGRADE_BEACON_METADATA - )) - } - ) await tester.runTest( `DharmaUpgradeBeacon contract deployment`, DharmaUpgradeBeaconDeployer, '', 'deploy' - ) + ); - let currentKeyRingUpgradeBeaconCode; - await tester.runTest( - 'Checking Upgrade Beacon runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.KEY_RING_UPGRADE_BEACON_ADDRESS], - true, - value => { - currentKeyRingUpgradeBeaconCode = value; - } - ) - if ( - currentKeyRingUpgradeBeaconCode !== swapMetadataHash( + // KeyRingUpgradeBeacon + const keyRingUpgradeBeaconRuntimeCode = swapMetadataHash( DharmaKeyRingUpgradeBeaconArtifact.deployedBytecode, constants.KEY_RING_UPGRADE_BEACON_METADATA - ) - ) { - await tester.runTest( - `DharmaKeyRingUpgradeBeacon contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.KEY_RING_UPGRADE_BEACON_SALT, - swapMetadataHash( - DharmaKeyRingUpgradeBeaconArtifact.bytecode, - constants.KEY_RING_UPGRADE_BEACON_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.KEY_RING_UPGRADE_BEACON_ADDRESS) - } - ) + ); - await tester.runTest( - `DharmaUpgradeBeacon contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.KEY_RING_UPGRADE_BEACON_SALT, - swapMetadataHash( - DharmaKeyRingUpgradeBeaconArtifact.bytecode, - constants.KEY_RING_UPGRADE_BEACON_METADATA - ) - ] - ) - } + const keyRingUpgradeBeaconCreationCode = swapMetadataHash( + DharmaKeyRingUpgradeBeaconArtifact.bytecode, + constants.KEY_RING_UPGRADE_BEACON_METADATA + ); - await tester.runTest( - 'Deployed Key Ring Upgrade Beacon code is correct', - MockCodeCheck, - 'code', - 'call', - [DharmaKeyRingUpgradeBeacon.options.address], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaKeyRingUpgradeBeaconArtifact.deployedBytecode, - constants.KEY_RING_UPGRADE_BEACON_METADATA - )) - } - ) + await tester.checkAndDeploy( + "KeyRingUpgradeBeacon", + constants.KEY_RING_UPGRADE_BEACON_ADDRESS, + constants.KEY_RING_UPGRADE_BEACON_SALT, + keyRingUpgradeBeaconRuntimeCode, + keyRingUpgradeBeaconCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); await tester.runTest( `DharmaKeyRingUpgradeBeacon contract deployment`, DharmaKeyRingUpgradeBeaconDeployer, '', 'deploy' - ) + ); - let currentKeyRegistryCode; - await tester.runTest( - 'Checking Key Registry runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.KEY_REGISTRY_ADDRESS], - true, - value => { - currentKeyRegistryCode = value; - } - ) - if ( - currentKeyRegistryCode !== swapMetadataHash( + // KeyRegistry + const keyRegistryRuntimeCode = swapMetadataHash( DharmaKeyRegistryV1Artifact.deployedBytecode, constants.KEY_REGISTRY_METADATA - ) - ) { - await tester.runTest( - `DharmaKeyRegistryV1 Code contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.KEY_REGISTRY_SALT, - swapMetadataHash( - DharmaKeyRegistryV1Artifact.bytecode, - constants.KEY_REGISTRY_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.KEY_REGISTRY_ADDRESS) - } - ) + ); - await tester.runTest( - `DharmaKeyRegistryV1 contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.KEY_REGISTRY_SALT, - swapMetadataHash( - DharmaKeyRegistryV1Artifact.bytecode, - constants.KEY_REGISTRY_METADATA - ) - ] - ) - } + const keyRegistryCreationCode = swapMetadataHash( + DharmaKeyRegistryV1Artifact.bytecode, + constants.KEY_REGISTRY_METADATA + ); - await tester.runTest( - 'Deployed Key Registry code is correct', - MockCodeCheck, - 'code', - 'call', - [DharmaKeyRegistryV1.options.address], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaKeyRegistryV1Artifact.deployedBytecode, - constants.KEY_REGISTRY_METADATA - )) - } - ) + await tester.checkAndDeploy( + "KeyRegistry", + constants.KEY_REGISTRY_ADDRESS, + constants.KEY_REGISTRY_SALT, + keyRegistryRuntimeCode, + keyRegistryCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); - let currentKeyRegistryV2Code; - await tester.runTest( - 'Checking Key Registry V2 runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.KEY_REGISTRY_V2_ADDRESS], - true, - value => { - currentKeyRegistryV2Code = value; - } - ) - if ( - currentKeyRegistryV2Code !== swapMetadataHash( + // KeyRegistryV2 + const keyRegistryV2RuntimeCode = swapMetadataHash( DharmaKeyRegistryV2Artifact.deployedBytecode, constants.KEY_REGISTRY_V2_METADATA - ) - ) { - await tester.runTest( - `DharmaKeyRegistryV2 Code contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.KEY_REGISTRY_V2_SALT, - swapMetadataHash( - DharmaKeyRegistryV2Artifact.bytecode, - constants.KEY_REGISTRY_V2_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.KEY_REGISTRY_V2_ADDRESS) - } - ) - - await tester.runTest( - `DharmaKeyRegistryV2 contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.KEY_REGISTRY_V2_SALT, - swapMetadataHash( - DharmaKeyRegistryV2Artifact.bytecode, - constants.KEY_REGISTRY_V2_METADATA - ) - ] - ) - } - - await tester.runTest( - 'Deployed Key Registry code is correct', - MockCodeCheck, - 'code', - 'call', - [DharmaKeyRegistryV2.options.address], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaKeyRegistryV2Artifact.deployedBytecode, - constants.KEY_REGISTRY_V2_METADATA - )) - } - ) + ); - let currentRevertReasonHelperCode; - await tester.runTest( - 'Checking Revert Reason Helper runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.REVERT_REASON_HELPER_ADDRESS], - true, - value => { - currentRevertReasonHelperCode = value; - } - ) + const keyRegistryV2CreationCode = swapMetadataHash( + DharmaKeyRegistryV2Artifact.bytecode, + constants.KEY_REGISTRY_V2_METADATA + ); - if ( - currentRevertReasonHelperCode !== SmartWalletRevertReasonHelperV1Artifact.deployedBytecode - ) { - await tester.runTest( - `SmartWalletRevertReasonHelperV1 Code contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.NULL_BYTES_32, - SmartWalletRevertReasonHelperV1Artifact.bytecode - ], - true, - value => { - assert.strictEqual(value, constants.REVERT_REASON_HELPER_ADDRESS) - } - ) + await tester.checkAndDeploy( + "KeyRegistryV2", + constants.KEY_REGISTRY_V2_ADDRESS, + constants.KEY_REGISTRY_V2_SALT, + keyRegistryV2RuntimeCode, + keyRegistryV2CreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); - await tester.runTest( - `SmartWalletRevertReasonHelperV1 contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.NULL_BYTES_32, - SmartWalletRevertReasonHelperV1Artifact.bytecode - ] - ) - } - await tester.runTest( - 'Deployed Revert Reason Helper code is correct', - MockCodeCheck, - 'code', - 'call', - [SmartWalletRevertReasonHelperV1.options.address], - true, - value => { - assert.strictEqual(value, SmartWalletRevertReasonHelperV1Artifact.deployedBytecode) - } - ) + // RevertReasonHelper + await tester.checkAndDeploy( + "RevertReasonHelper", + constants.REVERT_REASON_HELPER_ADDRESS, + constants.NULL_BYTES_32, + SmartWalletRevertReasonHelperV1Artifact.deployedBytecode, + SmartWalletRevertReasonHelperV1Artifact.bytecode, + MockCodeCheck, + ImmutableCreate2Factory + ); - let currentEscapeHatchRegistryCode; - await tester.runTest( - 'Checking Escape Hatch Registry runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.ESCAPE_HATCH_REGISTRY_ADDRESS], - true, - value => { - currentEscapeHatchRegistryCode = value; - } - ) - if ( - currentEscapeHatchRegistryCode !== swapMetadataHash( + // EscapeHatchRegistry + const escapeHatchRegistryRuntimeCode = swapMetadataHash( DharmaEscapeHatchRegistryArtifact.deployedBytecode, constants.ESCAPE_HATCH_REGISTRY_METADATA - ) - ) { - await tester.runTest( - `DharmaEscapeHatchRegistry Code contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.ESCAPE_HATCH_REGISTRY_SALT, - swapMetadataHash( - DharmaEscapeHatchRegistryArtifact.bytecode, - constants.ESCAPE_HATCH_REGISTRY_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.ESCAPE_HATCH_REGISTRY_ADDRESS) - } - ) + ); - await tester.runTest( - `DharmaEscapeHatchRegistry contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.ESCAPE_HATCH_REGISTRY_SALT, - swapMetadataHash( - DharmaEscapeHatchRegistryArtifact.bytecode, - constants.ESCAPE_HATCH_REGISTRY_METADATA - ) - ] - ) - } + const escapeHatchRegistryCreationCode = swapMetadataHash( + DharmaEscapeHatchRegistryArtifact.bytecode, + constants.ESCAPE_HATCH_REGISTRY_METADATA + ); - await tester.runTest( - 'Deployed Escape Hatch Registry code is correct', - MockCodeCheck, - 'code', - 'call', - [DharmaEscapeHatchRegistry.options.address], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaEscapeHatchRegistryArtifact.deployedBytecode, - constants.ESCAPE_HATCH_REGISTRY_METADATA - )) - } - ) + await tester.checkAndDeploy( + "EscapeHatchRegistry", + constants.ESCAPE_HATCH_REGISTRY_ADDRESS, + constants.ESCAPE_HATCH_REGISTRY_SALT, + escapeHatchRegistryRuntimeCode, + escapeHatchRegistryCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); + + // Dharma Smart Wallet Implementations const DharmaSmartWalletImplementationV0 = await tester.runTest( `DharmaSmartWalletImplementationV0 contract deployment`, DharmaSmartWalletImplementationV0Deployer, @@ -1284,6 +974,7 @@ module.exports = {test: async function (testingContext) { ) */ + // Dharma Key Ring Implementations const DharmaKeyRingImplementationV1 = await tester.runTest( `DharmaKeyRingImplementationV1 contract deployment`, DharmaKeyRingImplementationV1Deployer, @@ -1300,146 +991,56 @@ module.exports = {test: async function (testingContext) { ) */ - let currentAccountRecoveryManagerCode; - await tester.runTest( - 'Checking Account Recovery Manager runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS], - true, - value => { - currentAccountRecoveryManagerCode = value; - } - ) - if ( - currentAccountRecoveryManagerCode !== swapMetadataHash( + // AccountRecoveryManager + const accountRecoveryManagerRuntimeCode = swapMetadataHash( DharmaAccountRecoveryManagerV2Artifact.deployedBytecode, constants.ACCOUNT_RECOVERY_MANAGER_V2_METADATA - ) - ) { - await tester.runTest( - `DharmaAccountRecoveryManagerV2 contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.ACCOUNT_RECOVERY_MANAGER_V2_SALT, - swapMetadataHash( - DharmaAccountRecoveryManagerV2Artifact.bytecode, - constants.ACCOUNT_RECOVERY_MANAGER_V2_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS) - } - ) + ); - await tester.runTest( - `DharmaAccountRecoveryManagerV2 contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.ACCOUNT_RECOVERY_MANAGER_V2_SALT, - swapMetadataHash( - DharmaAccountRecoveryManagerV2Artifact.bytecode, - constants.ACCOUNT_RECOVERY_MANAGER_V2_METADATA - ) - ] - ) - } + const accountRecoveryManagerCreationCode = swapMetadataHash( + DharmaAccountRecoveryManagerV2Artifact.bytecode, + constants.ACCOUNT_RECOVERY_MANAGER_V2_METADATA + ); - await tester.runTest( - 'Deployed Account Recovery Manager code is correct', - MockCodeCheck, - 'code', - 'call', - [DharmaAccountRecoveryManagerV2.options.address], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaAccountRecoveryManagerV2Artifact.deployedBytecode, - constants.ACCOUNT_RECOVERY_MANAGER_V2_METADATA - )) - } - ) + await tester.checkAndDeploy( + "AccountRecoveryManager", + constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS, + constants.ACCOUNT_RECOVERY_MANAGER_V2_SALT, + accountRecoveryManagerRuntimeCode, + accountRecoveryManagerCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); await tester.runTest( `DharmaAccountRecoveryManagerV2 contract deployment`, DharmaAccountRecoveryManagerV2Deployer, '', 'deploy' - ) + ); - let currentFactoryCode; - await tester.runTest( - 'Checking Factory runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.FACTORY_ADDRESS], - true, - value => { - currentFactoryCode = value; - } - ) - if ( - currentFactoryCode !== swapMetadataHash( + // DharmaSmartWalletFactory + const dharmaSmartWalletFactoryRuntimeCode = swapMetadataHash( DharmaSmartWalletFactoryV1Artifact.deployedBytecode, constants.FACTORY_METADATA - ) - ) { - await tester.runTest( - `DharmaSmartWalletFactoryV1 Code contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.FACTORY_SALT, - swapMetadataHash( - DharmaSmartWalletFactoryV1Artifact.bytecode, - constants.FACTORY_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.FACTORY_ADDRESS) - } - ) + ); - await tester.runTest( - `DharmaSmartWalletFactoryV1 contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.FACTORY_SALT, - swapMetadataHash( - DharmaSmartWalletFactoryV1Artifact.bytecode, - constants.FACTORY_METADATA - ) - ] - ) - } + const dharmaSmartWalletFactoryCreationCode = swapMetadataHash( + DharmaSmartWalletFactoryV1Artifact.bytecode, + constants.FACTORY_METADATA + ); - await tester.runTest( - 'Deployed FactoryV1 code is correct', - MockCodeCheck, - 'code', - 'call', - [DharmaSmartWalletFactoryV1.options.address], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaSmartWalletFactoryV1Artifact.deployedBytecode, - constants.FACTORY_METADATA - )) - } - ) + await tester.checkAndDeploy( + "DharmaSmartWalletFactory", + constants.FACTORY_ADDRESS, + constants.FACTORY_SALT, + dharmaSmartWalletFactoryRuntimeCode, + dharmaSmartWalletFactoryCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); await tester.runTest( `DharmaSmartWalletFactoryV1 contract deployment`, @@ -1447,74 +1048,29 @@ module.exports = {test: async function (testingContext) { '', 'deploy', [] - ) + ); - let currentKeyRingFactoryCode; - await tester.runTest( - 'Checking Key Ring Factory runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.KEY_RING_FACTORY_V2_ADDRESS], - true, - value => { - currentKeyRingFactoryCode = value; - } - ) - if ( - currentKeyRingFactoryCode !== swapMetadataHash( + // KeyRingFactory + const keyRingFactoryRuntimeCode = swapMetadataHash( DharmaKeyRingFactoryV2Artifact.deployedBytecode, constants.KEY_RING_FACTORY_V2_METADATA - ) - ) { - await tester.runTest( - `DharmaKeyRingFactoryV2 Code contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.KEY_RING_FACTORY_V2_SALT, - swapMetadataHash( - DharmaKeyRingFactoryV2Artifact.bytecode, - constants.KEY_RING_FACTORY_V2_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.KEY_RING_FACTORY_V2_ADDRESS) - } - ) + ); - await tester.runTest( - `DharmaKeyRingFactoryV2 contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.KEY_RING_FACTORY_V2_SALT, - swapMetadataHash( - DharmaKeyRingFactoryV2Artifact.bytecode, - constants.KEY_RING_FACTORY_V2_METADATA - ) - ] - ) - } + const keyRingFactoryCreationCode = swapMetadataHash( + DharmaKeyRingFactoryV2Artifact.bytecode, + constants.KEY_RING_FACTORY_V2_METADATA + ); - await tester.runTest( - 'Deployed KeyRingFactoryV2 code is correct', - MockCodeCheck, - 'code', - 'call', - [DharmaKeyRingFactoryV2.options.address], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaKeyRingFactoryV2Artifact.deployedBytecode, - constants.KEY_RING_FACTORY_V2_METADATA - )) - } - ) + await tester.checkAndDeploy( + "KeyRingFactory", + constants.KEY_RING_FACTORY_V2_ADDRESS, + constants.KEY_RING_FACTORY_V2_SALT, + keyRingFactoryRuntimeCode, + keyRingFactoryCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); await tester.runTest( `DharmaKeyRingFactoryV2 contract deployment`, @@ -1522,477 +1078,158 @@ module.exports = {test: async function (testingContext) { '', 'deploy', [] - ) - - let currentAdharmaSmartWalletImplementationCode; - await tester.runTest( - 'Checking Adharma smart wallet implementation runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS], - true, - value => { - currentAdharmaSmartWalletImplementationCode = value; - } - ) + ); - if ( - currentAdharmaSmartWalletImplementationCode !== swapMetadataHash( + // AdharmaSmartWalletImplementation + const adharmaSmartWalletImplementationRuntimeCode = swapMetadataHash( AdharmaSmartWalletImplementationArtifact.deployedBytecode, constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_METADATA - ) - ) { - await tester.runTest( - `AdharmaSmartWalletImplementation contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_SALT, - swapMetadataHash( - AdharmaSmartWalletImplementationArtifact.bytecode, - constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS) - } - ) - - await tester.runTest( - `AdharmaSmartWalletImplementation contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_SALT, - swapMetadataHash( - AdharmaSmartWalletImplementationArtifact.bytecode, - constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_METADATA - ) - ] - ) - } + ); - await tester.runTest( - 'Deployed AdharmaSmartWalletImplementation code is correct', - MockCodeCheck, - 'code', - 'call', - [constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - AdharmaSmartWalletImplementationArtifact.deployedBytecode, - constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_METADATA - )) - } - ) + const adharmaSmartWalletImplementationCreationCode = swapMetadataHash( + AdharmaSmartWalletImplementationArtifact.bytecode, + constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_METADATA + ); + await tester.checkAndDeploy( + "AdharmaSmartWalletImplementation", + constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS, + constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_SALT, + adharmaSmartWalletImplementationRuntimeCode, + adharmaSmartWalletImplementationCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); - let currentDharmaDaiUpgradeBeaconControllerCode; - await tester.runTest( - 'Checking Dharma Dai Upgrade Beacon Controller runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_ADDRESS], - true, - value => { - currentDharmaDaiUpgradeBeaconControllerCode = value; - } - ) - if ( - currentDharmaDaiUpgradeBeaconControllerCode !== swapMetadataHash( + // DharmaDaiUpgrageBeaconController + const dharmaDaiUpgradeBeaconControllerRuntimeCode = swapMetadataHash( DharmaUpgradeBeaconControllerArtifact.deployedBytecode, constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA - ) - ) { - await tester.runTest( - `DharmaDaiUpgradeBeaconController contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_SALT, - swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.bytecode, - constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_ADDRESS) - } - ) + ); - await tester.runTest( - `DharmaDaiUpgradeBeaconController contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_SALT, - swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.bytecode, - constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA - ) - ] - ) - } + const dharmaDaiUpgradeBeaconControllerCreationCode = swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.bytecode, + constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA + ); - await tester.runTest( - 'Deployed DharmaDaiUpgradeBeaconController code is correct', - MockCodeCheck, - 'code', - 'call', - [constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_ADDRESS], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.deployedBytecode, - constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA - )) - } - ) + await tester.checkAndDeploy( + "DharmaDaiUpgrageBeaconController", + constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_ADDRESS, + constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_SALT, + dharmaDaiUpgradeBeaconControllerRuntimeCode, + dharmaDaiUpgradeBeaconControllerCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); - let currentDharmaUSDCUpgradeBeaconControllerCode; - await tester.runTest( - 'Checking Dharma USDC Upgrade Beacon Controller runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_ADDRESS], - true, - value => { - currentDharmaUSDCUpgradeBeaconControllerCode = value; - } - ) - if ( - currentDharmaUSDCUpgradeBeaconControllerCode !== swapMetadataHash( + // DharmaUSDCUpgrageBeaconController + const dharmaUSDCUpgradeBeaconControllerRuntimeCode = swapMetadataHash( DharmaUpgradeBeaconControllerArtifact.deployedBytecode, constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA - ) - ) { - await tester.runTest( - `DharmaUSDCUpgradeBeaconController contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_SALT, - swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.bytecode, - constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_ADDRESS) - } - ) - - await tester.runTest( - `DharmaUSDCUpgradeBeaconController contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_SALT, - swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.bytecode, - constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA - ) - ] - ) - } + ); - await tester.runTest( - 'Deployed DharmaUSDCUpgradeBeaconController code is correct', - MockCodeCheck, - 'code', - 'call', - [constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_ADDRESS], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.deployedBytecode, - constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA - )) - } - ) + const dharmaUSDCUpgradeBeaconControllerCreationCode = swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.bytecode, + constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA + ); - let currentDharmaDaiUpgradeBeaconCode; - await tester.runTest( - 'Checking Dharma Dai Upgrade Beacon Controller runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS], - true, - value => { - currentDharmaDaiUpgradeBeaconCode = value; - } - ) + await tester.checkAndDeploy( + "DharmaUSDCUpgrageBeaconController", + constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_ADDRESS, + constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_SALT, + dharmaUSDCUpgradeBeaconControllerRuntimeCode, + dharmaUSDCUpgradeBeaconControllerCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); - if ( - currentDharmaDaiUpgradeBeaconCode !== swapMetadataHash( + // DharmaUSDCUpgrageBeacon + const dharmaDaiUpgradeBeaconRuntimeCode = swapMetadataHash( DharmaDaiUpgradeBeaconArtifact.deployedBytecode, constants.DHARMA_DAI_UPGRADE_BEACON_METADATA - ) - ) { - await tester.runTest( - `DharmaDaiUpgradeBeacon contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.DHARMA_DAI_UPGRADE_BEACON_SALT, - swapMetadataHash( - DharmaDaiUpgradeBeaconArtifact.bytecode, - constants.DHARMA_DAI_UPGRADE_BEACON_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS) - } - ) - - await tester.runTest( - `DharmaDaiUpgradeBeacon contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.DHARMA_DAI_UPGRADE_BEACON_SALT, - swapMetadataHash( - DharmaDaiUpgradeBeaconArtifact.bytecode, - constants.DHARMA_DAI_UPGRADE_BEACON_METADATA - ) - ] - ) - } + ); - await tester.runTest( - 'Deployed DharmaDaiUpgradeBeacon code is correct', - MockCodeCheck, - 'code', - 'call', - [constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaDaiUpgradeBeaconArtifact.deployedBytecode, - constants.DHARMA_DAI_UPGRADE_BEACON_METADATA - )) - } - ) + const dharmaDaiUpgradeBeaconCreationCode = swapMetadataHash( + DharmaDaiUpgradeBeaconArtifact.bytecode, + constants.DHARMA_DAI_UPGRADE_BEACON_METADATA + ); - let currentDharmaUSDCUpgradeBeaconCode; - await tester.runTest( - 'Checking Dharma USDC Upgrade Beacon Controller runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS], - true, - value => { - currentDharmaUSDCUpgradeBeaconCode = value; - } - ) + await tester.checkAndDeploy( + "DharmaDaiUpgrageBeacon", + constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS, + constants.DHARMA_DAI_UPGRADE_BEACON_SALT, + dharmaDaiUpgradeBeaconRuntimeCode, + dharmaDaiUpgradeBeaconCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); - if ( - currentDharmaUSDCUpgradeBeaconCode !== swapMetadataHash( + // DharmaUSDCUpgrageBeacon + const dharmaUSDCUpgradeBeaconRuntimeCode = swapMetadataHash( DharmaUSDCUpgradeBeaconArtifact.deployedBytecode, constants.DHARMA_USDC_UPGRADE_BEACON_METADATA - ) - ) { - await tester.runTest( - `DharmaUSDCUpgradeBeacon contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.DHARMA_USDC_UPGRADE_BEACON_SALT, - swapMetadataHash( - DharmaUSDCUpgradeBeaconArtifact.bytecode, - constants.DHARMA_USDC_UPGRADE_BEACON_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS) - } - ) + ); - await tester.runTest( - `DharmaUSDCUpgradeBeacon contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.DHARMA_USDC_UPGRADE_BEACON_SALT, - swapMetadataHash( - DharmaUSDCUpgradeBeaconArtifact.bytecode, - constants.DHARMA_USDC_UPGRADE_BEACON_METADATA - ) - ] - ) - } + const dharmaUSDCUpgradeBeaconCreationCode = swapMetadataHash( + DharmaUSDCUpgradeBeaconArtifact.bytecode, + constants.DHARMA_USDC_UPGRADE_BEACON_METADATA + ); - await tester.runTest( - 'Deployed DharmaUSDCUpgradeBeacon code is correct', - MockCodeCheck, - 'code', - 'call', - [constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaUSDCUpgradeBeaconArtifact.deployedBytecode, - constants.DHARMA_USDC_UPGRADE_BEACON_METADATA - )) - } - ) + await tester.checkAndDeploy( + "DharmaUSDCUpgrageBeacon", + constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS, + constants.DHARMA_USDC_UPGRADE_BEACON_SALT, + dharmaUSDCUpgradeBeaconRuntimeCode, + dharmaUSDCUpgradeBeaconCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); - let currentDharmaDaiCode; - await tester.runTest( - 'Checking Dharma Dai Upgrade Beacon Controller runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.DHARMA_DAI_ADDRESS], - true, - value => { - currentDharmaDaiCode = value; - } - ) - if ( - currentDharmaDaiCode !== swapMetadataHash( + // DharmaDai + const dharmaDaiRuntimeCode = swapMetadataHash( DharmaDaiArtifact.deployedBytecode, constants.DHARMA_DAI_METADATA - ) - ) { - await tester.runTest( - `DharmaDai contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.DHARMA_DAI_SALT, - swapMetadataHash( - DharmaDaiArtifact.bytecode, - constants.DHARMA_DAI_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.DHARMA_DAI_ADDRESS) - } - ) - - await tester.runTest( - `DharmaDai contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.DHARMA_DAI_SALT, - swapMetadataHash( - DharmaDaiArtifact.bytecode, - constants.DHARMA_DAI_METADATA - ) - ] - ) - } + ); - await tester.runTest( - 'Deployed DharmaDai code is correct', - MockCodeCheck, - 'code', - 'call', - [constants.DHARMA_DAI_ADDRESS], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaDaiArtifact.deployedBytecode, - constants.DHARMA_DAI_METADATA - )) - } - ) + const dharmaDaiCreationCode = swapMetadataHash( + DharmaDaiArtifact.bytecode, + constants.DHARMA_DAI_METADATA + ); - let currentDharmaUSDCCode; - await tester.runTest( - 'Checking Dharma USDC Upgrade Beacon Controller runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.DHARMA_USDC_ADDRESS], - true, - value => { - currentDharmaUSDCCode = value; - } - ) + await tester.checkAndDeploy( + "DharmaDai", + constants.DHARMA_DAI_ADDRESS, + constants.DHARMA_DAI_SALT, + dharmaDaiRuntimeCode, + dharmaDaiCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); - if ( - currentDharmaUSDCCode !== swapMetadataHash( + // DharmaUSDC + const dharmaUSDCRuntimeCode = swapMetadataHash( DharmaUSDCArtifact.deployedBytecode, constants.DHARMA_USDC_METADATA - ) - ) { - await tester.runTest( - `DharmaUSDC contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.DHARMA_USDC_SALT, - swapMetadataHash( - DharmaUSDCArtifact.bytecode, - constants.DHARMA_USDC_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.DHARMA_USDC_ADDRESS) - } - ) + ); - await tester.runTest( - `DharmaUSDC contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.DHARMA_USDC_SALT, - swapMetadataHash( - DharmaUSDCArtifact.bytecode, - constants.DHARMA_USDC_METADATA - ) - ] - ) - } + const dharmaUSDCCreationCode = swapMetadataHash( + DharmaUSDCArtifact.bytecode, + constants.DHARMA_USDC_METADATA + ); + + await tester.checkAndDeploy( + "DharmaDai", + constants.DHARMA_USDC_ADDRESS, + constants.DHARMA_USDC_SALT, + dharmaUSDCRuntimeCode, + dharmaUSDCCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); - await tester.runTest( - 'Deployed DharmaUSDC code is correct', - MockCodeCheck, - 'code', - 'call', - [constants.DHARMA_USDC_ADDRESS], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaUSDCArtifact.deployedBytecode, - constants.DHARMA_USDC_METADATA - )) - } - ) const DharmaDaiInitializerImplementation = await tester.runTest( `DharmaDaiInitializer contract deployment`, @@ -2073,72 +1310,28 @@ module.exports = {test: async function (testingContext) { 'deploy' ) - let currentAdharmaKeyRingImplementationCode; - await tester.runTest( - 'Checking Adharma key ring implementation runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS], - true, - value => { - currentAdharmaKeyRingImplementationCode = value; - } - ) - if ( - currentAdharmaKeyRingImplementationCode !== swapMetadataHash( + // ADharmaKeyRingImplementation + const adharmaKeyRingImplementationRuntimeCode = swapMetadataHash( AdharmaKeyRingImplementationArtifact.deployedBytecode, constants.ADHARMA_KEY_RING_IMPLEMENTATION_METADATA - ) - ) { - await tester.runTest( - `AdharmaKeyRingImplementation contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.ADHARMA_KEY_RING_IMPLEMENTATION_SALT, - swapMetadataHash( - AdharmaKeyRingImplementationArtifact.bytecode, - constants.ADHARMA_KEY_RING_IMPLEMENTATION_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS) - } - ) + ); - await tester.runTest( - `AdharmaKeyRingImplementation contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.ADHARMA_KEY_RING_IMPLEMENTATION_SALT, - swapMetadataHash( - AdharmaKeyRingImplementationArtifact.bytecode, - constants.ADHARMA_KEY_RING_IMPLEMENTATION_METADATA - ) - ] - ) - } + const adharmaKeyRingImplementationCreationCode = swapMetadataHash( + AdharmaKeyRingImplementationArtifact.bytecode, + constants.ADHARMA_KEY_RING_IMPLEMENTATION_METADATA + ); + + await tester.checkAndDeploy( + "DharmaDai", + constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS, + constants.ADHARMA_KEY_RING_IMPLEMENTATION_SALT, + adharmaKeyRingImplementationRuntimeCode, + adharmaKeyRingImplementationCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); - await tester.runTest( - 'Deployed AdharmaSmartWalletImplementation code is correct', - MockCodeCheck, - 'code', - 'call', - [constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - AdharmaKeyRingImplementationArtifact.deployedBytecode, - constants.ADHARMA_KEY_RING_IMPLEMENTATION_METADATA - )) - } - ) await tester.runTest( `AdharmaKeyRingImplementation contract deployment`, @@ -2241,7 +1434,7 @@ module.exports = {test: async function (testingContext) { false ) - const DharmaAccountRecoveryMultisig = await tester.runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig contract deployment`, DharmaAccountRecoveryMultisigDeployer, '', @@ -2296,7 +1489,7 @@ module.exports = {test: async function (testingContext) { false ) - const DharmaKeyRegistryMultisig = await tester.runTest( + await tester.runTest( `DharmaKeyRegistryMultisig contract deployment`, DharmaKeyRegistryMultisigDeployer, '', @@ -2592,72 +1785,27 @@ module.exports = {test: async function (testingContext) { [constants.FACTORY_ADDRESS] ) - let currentUpgradeBeaconControllerManagerCode; - await tester.runTest( - 'Checking Upgrade Beacon Controller Manager runtime code', - MockCodeCheck, - 'code', - 'call', - [constants.UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS], - true, - value => { - currentUpgradeBeaconControllerManagerCode = value; - } - ) - - if ( - currentUpgradeBeaconControllerManagerCode !== swapMetadataHash( + // UpgradeBeaconControllerManager + const upgradeBeaconControllerManagerRuntimeCode = swapMetadataHash( DharmaUpgradeBeaconControllerManagerArtifact.deployedBytecode, constants.UPGRADE_BEACON_CONTROLLER_MANAGER_METADATA - ) - ) { - await tester.runTest( - `DharmaUpgradeBeaconControllerManager contract address check through immutable create2 factory`, - ImmutableCreate2Factory, - 'findCreate2Address', - 'call', - [ - constants.UPGRADE_BEACON_CONTROLLER_MANAGER_SALT, - swapMetadataHash( - DharmaUpgradeBeaconControllerManagerArtifact.bytecode, - constants.UPGRADE_BEACON_CONTROLLER_MANAGER_METADATA - ) - ], - true, - value => { - assert.strictEqual(value, constants.UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS) - } - ) + ); - await tester.runTest( - `DharmaUpgradeBeaconControllerManager contract deployment through immutable create2 factory`, - ImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.UPGRADE_BEACON_CONTROLLER_MANAGER_SALT, - swapMetadataHash( - DharmaUpgradeBeaconControllerManagerArtifact.bytecode, - constants.UPGRADE_BEACON_CONTROLLER_MANAGER_METADATA - ) - ] - ) - } + const upgradeBeaconControllerManagerCreationCode = swapMetadataHash( + DharmaUpgradeBeaconControllerManagerArtifact.bytecode, + constants.UPGRADE_BEACON_CONTROLLER_MANAGER_METADATA + ); + + await tester.checkAndDeploy( + "UpgradeBeaconControllerManager", + constants.UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS, + constants.UPGRADE_BEACON_CONTROLLER_MANAGER_SALT, + upgradeBeaconControllerManagerRuntimeCode, + upgradeBeaconControllerManagerCreationCode, + MockCodeCheck, + ImmutableCreate2Factory + ); - await tester.runTest( - 'Deployed DharmaUpgradeBeaconControllerManager code is correct', - MockCodeCheck, - 'code', - 'call', - [constants.UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS], - true, - value => { - assert.strictEqual(value, swapMetadataHash( - DharmaUpgradeBeaconControllerManagerArtifact.deployedBytecode, - constants.UPGRADE_BEACON_CONTROLLER_MANAGER_METADATA - )) - } - ) await tester.runTest( 'IndestructibleRegistry can register the upgrade beacon controller manager as indestructible', @@ -2714,7 +1862,7 @@ module.exports = {test: async function (testingContext) { false ) - const DharmaUpgradeMultisig = await tester.runTest( + await tester.runTest( `DharmaUpgradeMultisig contract deployment`, DharmaUpgradeMultisigDeployer, '', @@ -2781,4 +1929,8 @@ module.exports = {test: async function (testingContext) { // exit. return 0 -}} +} + +module.exports = { + test, +}; From 113d6fc7982bc3abc6410a2cb4dcd418f8b6eb11 Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Thu, 6 Feb 2020 18:15:36 -0800 Subject: [PATCH 14/47] start using tester on test --- scripts/test/deploy.js | 2 +- scripts/test/test.js | 3721 ++++++++++++++++++----------------- scripts/test/testHelpers.js | 8 +- 3 files changed, 1869 insertions(+), 1862 deletions(-) diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index 39dd40f..2a26c62 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -1923,7 +1923,7 @@ async function test(testingContext) { ) if (tester.failed > 0) { - process.exit(1) + // process.exit(1) } // exit. diff --git a/scripts/test/test.js b/scripts/test/test.js index 0eb7a41..a63b44f 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -3,6 +3,7 @@ var fs = require('fs') var util = require('ethereumjs-util') const constants = require('./constants.js') const { web3 } = require("./web3"); +const { Tester, longer } = require("./testHelpers"); const AdharmaSmartWalletImplementationArtifact = require('../../build/contracts/AdharmaSmartWalletImplementation.json') const AdharmaKeyRingImplementationArtifact = require('../../build/contracts/AdharmaKeyRingImplementation.json') @@ -53,10 +54,6 @@ const ComptrollerArtifact = require('../../build/contracts/ComptrollerInterface. const contractNames = Object.assign({}, constants.CONTRACT_NAMES) -// used to wait for more confirmations -function longer() { - return new Promise(resolve => {setTimeout(() => {resolve()}, 500)}) -} module.exports = {test: async function (testingContext) { let passed = 0 @@ -380,6 +377,10 @@ module.exports = {test: async function (testingContext) { DharmaEscapeHatchRegistryArtifact.bytecode ) + + const tester = new Tester(testingContext); + await tester.init(); + // get available addresses and assign them to various roles const addresses = await web3.eth.getAccounts() if (addresses.length < 1) { @@ -423,7 +424,7 @@ module.exports = {test: async function (testingContext) { console.log('running tests...') - // ************************** helper functions **************************** // + // ************************** helper functions **************************** // async function send( title, instance, @@ -621,7 +622,7 @@ module.exports = {test: async function (testingContext) { assertionCallback = (value) => {} } if (typeof(from) === 'undefined') { - from = address + from = tester.address } if (typeof(value) === 'undefined') { value = 0 @@ -711,7 +712,7 @@ module.exports = {test: async function (testingContext) { await web3.eth.accounts.wallet.add(pubKey) await web3.eth.sendTransaction({ - from: originalAddress, + from: tester.originalAddress, to: pubKey.address, value: 2 * 10 ** 18, gas: '0x5208', @@ -721,57 +722,57 @@ module.exports = {test: async function (testingContext) { return pubKey.address } - async function raiseGasLimit(necessaryGas) { - iterations = 9999 - if (necessaryGas > 8000000) { - console.error('the gas needed is too high!') - process.exit(1) - } else if (typeof necessaryGas === 'undefined') { - iterations = 20 - necessaryGas = 8000000 - } - - // bring up gas limit if necessary by doing additional transactions - var block = await web3.eth.getBlock("latest") - while (iterations > 0 && block.gasLimit < necessaryGas) { - await web3.eth.sendTransaction({ - from: originalAddress, - to: originalAddress, - value: '0x01', - gas: '0x5208', - gasPrice: '0x4A817C800' - }) - var block = await web3.eth.getBlock("latest") - iterations-- - } - - console.log("raising gasLimit, currently at " + block.gasLimit) - return block.gasLimit - } - - async function getDeployGas(dataPayload) { - await web3.eth.estimateGas({ - from: address, - data: dataPayload - }).catch(async error => { - if ( - error.message === ( - 'Returned error: gas required exceeds allowance or always failing ' + - 'transaction' - ) - ) { - await raiseGasLimit() - await getDeployGas(dataPayload) - } - }) - - deployGas = await web3.eth.estimateGas({ - from: address, - data: dataPayload - }) - - return deployGas - } + // async function raiseGasLimit(necessaryGas) { + // iterations = 9999 + // if (necessaryGas > 8000000) { + // console.error('the gas needed is too high!') + // process.exit(1) + // } else if (typeof necessaryGas === 'undefined') { + // iterations = 20 + // necessaryGas = 8000000 + // } + // + // // bring up gas limit if necessary by doing additional transactions + // var block = await web3.eth.getBlock("latest") + // while (iterations > 0 && block.gasLimit < necessaryGas) { + // await web3.eth.sendTransaction({ + // from: tester.originalAddress, + // to: tester.originalAddress, + // value: '0x01', + // gas: '0x5208', + // gasPrice: '0x4A817C800' + // }) + // var block = await web3.eth.getBlock("latest") + // iterations-- + // } + // + // console.log("raising gasLimit, currently at " + block.gasLimit) + // return block.gasLimit + // } + + // async function getDeployGas(dataPayload) { + // await web3.eth.estimateGas({ + // from: tester.address, + // data: dataPayload + // }).catch(async error => { + // if ( + // error.message === ( + // 'Returned error: gas required exceeds allowance or always failing ' + + // 'transaction' + // ) + // ) { + // await raiseGasLimit() + // await getDeployGas(dataPayload) + // } + // }) + // + // deployGas = await web3.eth.estimateGas({ + // from: tester.address, + // data: dataPayload + // }) + // + // return deployGas + // } function signHashedPrefixedHexString(hashedHexString, account) { const hashedPrefixedMessage = web3.utils.keccak256( @@ -835,22 +836,22 @@ module.exports = {test: async function (testingContext) { let deployGas let selfAddress - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController can transfer owner`, DharmaUpgradeBeaconController, 'transferOwnership', 'send', - [address] + [tester.address] ) - const MockCodeCheck = await runTest( + const MockCodeCheck = await tester.runTest( `MockCodeCheck contract deployment`, MockCodeCheckDeployer, '', 'deploy' ) - await runTest( + await tester.runTest( 'Dharma Key Registry V1 gets the initial global key correctly', DharmaKeyRegistryV1, 'getGlobalKey', @@ -858,20 +859,20 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - await runTest( + await tester.runTest( 'Dharma Key Registry V1 attempt to get an unset specific key throws', DharmaKeyRegistryV1, 'getSpecificKey', 'call', - [address], + [tester.address], false ) - await runTest( + await tester.runTest( 'Dharma Key Registry V1 gets the global key when requesting unset key', DharmaKeyRegistryV1, 'getKey', @@ -879,11 +880,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - await runTest( + await tester.runTest( 'Dharma Key Registry V1 cannot set a new empty global key', DharmaKeyRegistryV1, 'setGlobalKey', @@ -894,59 +895,59 @@ module.exports = {test: async function (testingContext) { ], false, receipt => {}, - originalAddress + tester.originalAddress ) const message = ( DharmaKeyRegistryV1.options.address + - address.slice(2) + + tester.address.slice(2) + web3.utils.asciiToHex( "This signature demonstrates that the supplied signing key is valid." ).slice(2) ) - const newKeySignature = signHashedPrefixedHashedHexString(message, address) + const newKeySignature = signHashedPrefixedHashedHexString(message, tester.address) - const badNewKeySignature = signHashedPrefixedHashedHexString('0x12', address) + const badNewKeySignature = signHashedPrefixedHashedHexString('0x12', tester.address) - await runTest( + await tester.runTest( 'Dharma Key Registry V1 cannot set a new global key unless called by owner', DharmaKeyRegistryV1, 'setGlobalKey', 'send', [ - address, + tester.address, newKeySignature ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'Dharma Key Registry V1 cannot set a new global key with a bad signature', DharmaKeyRegistryV1, 'setGlobalKey', 'send', [ - address, + tester.address, badNewKeySignature ], false ) - await runTest( + await tester.runTest( 'Dharma Key Registry V1 can set a new global key correctly', DharmaKeyRegistryV1, 'setGlobalKey', 'send', [ - address, + tester.address, newKeySignature ] ) - await runTest( + await tester.runTest( 'Dharma Key Registry V1 gets the new global key correctly', DharmaKeyRegistryV1, 'getGlobalKey', @@ -954,48 +955,48 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - await runTest( + await tester.runTest( 'Dharma Key Registry V1 cannot set a new specific key unless called by owner', DharmaKeyRegistryV1, 'setSpecificKey', 'send', [ - address, + tester.address, DharmaKeyRegistryV1.options.address ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'Dharma Key Registry V1 can set a new specific key', DharmaKeyRegistryV1, 'setSpecificKey', 'send', [ - address, + tester.address, DharmaKeyRegistryV1.options.address ] ) - await runTest( + await tester.runTest( 'Dharma Key Registry V1 gets the new specific key correctly', DharmaKeyRegistryV1, 'getSpecificKey', 'call', - [address], + [tester.address], true, value => { assert.strictEqual(value, DharmaKeyRegistryV1.options.address) } ) - await runTest( + await tester.runTest( 'Dharma Key Registry V1 gets the specific key when requesting set key', DharmaKeyRegistryV1, 'getKey', @@ -1007,17 +1008,17 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'Dharma Key Registry V1 can set a new owner', DharmaKeyRegistryV1, 'transferOwnership', 'send', [ - address + tester.address ] ) - await runTest( + await tester.runTest( 'Dharma Key Registry V1 gets the new owner', DharmaKeyRegistryV1, 'owner', @@ -1025,11 +1026,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 gets the new global key correctly', DharmaKeyRegistryV2, 'getGlobalKey', @@ -1037,96 +1038,96 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) const messageV2 = ( DharmaKeyRegistryV2.options.address + - address.slice(2) + + tester.address.slice(2) + web3.utils.asciiToHex( "This signature demonstrates that the supplied signing key is valid." ).slice(2) ) - const v2KeySignature = signHashedPrefixedHashedHexString(messageV2, address) + const v2KeySignature = signHashedPrefixedHashedHexString(messageV2, tester.address) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 cannot set a previously used global key', DharmaKeyRegistryV2, 'setGlobalKey', 'send', [ - address, + tester.address, v2KeySignature ], false ) - const BadBeacon = await runTest( + const BadBeacon = await tester.runTest( `Mock Bad Beacon contract deployment`, BadBeaconDeployer, '', 'deploy' ) - const BadBeaconTwo = await runTest( + const BadBeaconTwo = await tester.runTest( `Mock Bad Beacon Two contract deployment`, BadBeaconTwoDeployer, '', 'deploy' ) - const DharmaSmartWalletImplementationV0 = await runTest( + const DharmaSmartWalletImplementationV0 = await tester.runTest( `DharmaSmartWalletImplementationV0 contract deployment`, DharmaSmartWalletImplementationV0Deployer, '', 'deploy' ) - const DharmaSmartWalletImplementationV1 = await runTest( + const DharmaSmartWalletImplementationV1 = await tester.runTest( `DharmaSmartWalletImplementationV1 contract deployment`, DharmaSmartWalletImplementationV1Deployer, '', 'deploy' ) - const DharmaSmartWalletImplementationV2 = await runTest( + const DharmaSmartWalletImplementationV2 = await tester.runTest( `DharmaSmartWalletImplementationV2 contract deployment`, DharmaSmartWalletImplementationV2Deployer, '', 'deploy' ) - const DharmaSmartWalletImplementationV5 = await runTest( + const DharmaSmartWalletImplementationV5 = await tester.runTest( `DharmaSmartWalletImplementationV5 contract deployment`, DharmaSmartWalletImplementationV5Deployer, '', 'deploy' ) - const DharmaSmartWalletImplementationV6 = await runTest( + const DharmaSmartWalletImplementationV6 = await tester.runTest( `DharmaSmartWalletImplementationV6 contract deployment`, DharmaSmartWalletImplementationV6Deployer, '', 'deploy' ) - const DharmaSmartWalletImplementationV7 = await runTest( + const DharmaSmartWalletImplementationV7 = await tester.runTest( `DharmaSmartWalletImplementationV7 contract deployment`, DharmaSmartWalletImplementationV7Deployer, '', 'deploy' ) - const DharmaKeyRingImplementationV1 = await runTest( + const DharmaKeyRingImplementationV1 = await tester.runTest( `DharmaKeyRingImplementationV1 contract deployment`, DharmaKeyRingImplementationV1Deployer, '', 'deploy' ) - await runTest( + await tester.runTest( 'Dharma Upgrade Beacon Controller cannot set null address as implementation', DharmaUpgradeBeaconController, 'upgrade', @@ -1138,19 +1139,19 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'Dharma Upgrade Beacon Controller cannot set non-contract as implementation', DharmaUpgradeBeaconController, 'upgrade', 'send', [ DharmaUpgradeBeacon.options.address, - address + tester.address ], false ) - await runTest( + await tester.runTest( 'Dharma Upgrade Beacon Controller cannot support a "bad" beacon that throws', DharmaUpgradeBeaconController, 'upgrade', @@ -1162,7 +1163,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'Dharma Upgrade Beacon Controller cannot upgrade a non-upgradeable beacon', DharmaUpgradeBeaconController, 'upgrade', @@ -1174,7 +1175,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'Dharma Upgrade Beacon Controller is inaccessible from a non-owner', DharmaUpgradeBeaconController, 'upgrade', @@ -1185,10 +1186,10 @@ module.exports = {test: async function (testingContext) { ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'Dharma Upgrade Beacon Controller can set initial upgrade beacon implementation', DharmaUpgradeBeaconController, 'upgrade', @@ -1226,7 +1227,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'Dharma Upgrade Beacon Controller cannot clear upgrade beacon implementation', DharmaUpgradeBeaconController, 'upgrade', @@ -1238,7 +1239,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'Dharma Upgrade Beacon Controller can reset upgrade beacon implementation', DharmaUpgradeBeaconController, 'upgrade', @@ -1278,7 +1279,7 @@ module.exports = {test: async function (testingContext) { } ) - const UpgradeBeaconImplementationCheck = await runTest( + const UpgradeBeaconImplementationCheck = await tester.runTest( `UpgradeBeaconImplementationCheck deployment`, UpgradeBeaconImplementationCheckDeployer, '', @@ -1289,7 +1290,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'DharmaUpgradeBeacon has the implementation set', DharmaUpgradeBeaconController, 'getImplementation', @@ -1301,7 +1302,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'Dharma Key Ring Upgrade Beacon Controller can set initial key ring upgrade beacon implementation', DharmaKeyRingUpgradeBeaconController, 'upgrade', @@ -1339,7 +1340,7 @@ module.exports = {test: async function (testingContext) { } ) - const KeyRingUpgradeBeaconImplementationCheck = await runTest( + const KeyRingUpgradeBeaconImplementationCheck = await tester.runTest( `KeyRingUpgradeBeaconImplementationCheck deployment`, UpgradeBeaconImplementationCheckDeployer, '', @@ -1350,7 +1351,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'DharmaKeyRingUpgradeBeacon has the implementation set', DharmaKeyRingUpgradeBeaconController, 'getImplementation', @@ -1369,7 +1370,7 @@ module.exports = {test: async function (testingContext) { '5afa1551368280375af43d3d93803e602e57fd5bf3' ) - const DharmaSmartWalletNoFactoryNoConstructor = await runTest( + const DharmaSmartWalletNoFactoryNoConstructor = await tester.runTest( `DharmaSmartWallet minimal upgradeable proxy deployment - no factory or constructor`, DharmaSmartWalletNoFactoryNoConstructorDeployer, '', @@ -1381,7 +1382,7 @@ module.exports = {test: async function (testingContext) { DharmaSmartWalletNoFactoryNoConstructor.options.address ) - await runTest( + await tester.runTest( 'test passes', DharmaSmartWalletImplementationTest, 'test', @@ -1394,7 +1395,7 @@ module.exports = {test: async function (testingContext) { ) let currentSaiCode; - await runTest( + await tester.runTest( 'Checking for required external contracts...', MockCodeCheck, 'code', @@ -1435,7 +1436,7 @@ module.exports = {test: async function (testingContext) { 'c4d66de80000000000000000000000009999999999999999999999999999999999999999' ) - const DharmaSmartWalletNoFactory = await runTest( + const DharmaSmartWalletNoFactory = await tester.runTest( `DharmaSmartWallet minimal upgradeable proxy deployment - no factory but with constructor`, DharmaSmartWalletNoFactoryDeployer, '', @@ -1447,7 +1448,7 @@ module.exports = {test: async function (testingContext) { DharmaSmartWalletNoFactory.options.address ) - await runTest( + await tester.runTest( 'test passes', DharmaSmartWalletImplementationTestWithConstructor, 'test', @@ -1459,7 +1460,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'new user smart wallet can be called and has the correct dharma key set', DharmaSmartWalletImplementationTestWithConstructor, 'getUserSigningKey', @@ -1471,7 +1472,7 @@ module.exports = {test: async function (testingContext) { } ) - const DharmaSmartWalletFactoryV1 = await runTest( + const DharmaSmartWalletFactoryV1 = await tester.runTest( `DharmaSmartWalletFactoryV1 contract deployment`, DharmaSmartWalletFactoryV1Deployer, '', @@ -1480,12 +1481,12 @@ module.exports = {test: async function (testingContext) { ) let targetWalletAddress; - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', DharmaSmartWalletFactoryV1, 'getNextSmartWallet', 'call', - [address], + [tester.address], true, value => { // TODO: verify against expected value @@ -1502,7 +1503,7 @@ module.exports = {test: async function (testingContext) { if (ethWhaleBalance === '0') { await web3.eth.sendTransaction({ - from: address, + from: tester.address, to: constants.ETH_WHALE_ADDRESS, value: web3.utils.toWei('.2', 'ether'), gas: (testingContext !== 'coverage') ? '0x5208' : gasLimit - 1, @@ -1513,7 +1514,7 @@ module.exports = {test: async function (testingContext) { if (saiWhaleBalance === '0') { await web3.eth.sendTransaction({ - from: address, + from: tester.address, to: constants.SAI_WHALE_ADDRESS, value: web3.utils.toWei('.1', 'ether'), gas: (testingContext !== 'coverage') ? '0x5208' : gasLimit - 1, @@ -1524,7 +1525,7 @@ module.exports = {test: async function (testingContext) { if (usdcWhaleBalance === '0') { await web3.eth.sendTransaction({ - from: address, + from: tester.address, to: constants.USDC_WHALE_ADDRESS, value: web3.utils.toWei('.1', 'ether'), gas: (testingContext !== 'coverage') ? '0x5208' : gasLimit - 1, @@ -1542,7 +1543,7 @@ module.exports = {test: async function (testingContext) { }) console.log(' ✓ Eth Whale can deposit eth into the yet-to-be-deployed smart wallet') - await runTest( + await tester.runTest( 'Sai Whale can deposit sai into the yet-to-be-deployed smart wallet', SAI, 'transfer', @@ -1568,7 +1569,7 @@ module.exports = {test: async function (testingContext) { constants.SAI_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'USDC Whale can deposit usdc into the yet-to-be-deployed smart wallet', USDC, 'transfer', @@ -1594,7 +1595,7 @@ module.exports = {test: async function (testingContext) { constants.USDC_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 cannot deploy a new smart wallet with no key', DharmaSmartWalletFactoryV1, 'newSmartWallet', @@ -1603,12 +1604,12 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can deploy a new smart wallet using a Dharma Key', DharmaSmartWalletFactoryV1, 'newSmartWallet', 'send', - [address], + [tester.address], true, receipt => { //console.log(receipt.status, receipt.gasUsed) @@ -1631,7 +1632,7 @@ module.exports = {test: async function (testingContext) { assert.strictEqual(events[0].address, 'Smart Wallet') assert.strictEqual(events[0].eventName, 'NewUserSigningKey') - assert.strictEqual(events[0].returnValues.userSigningKey, address) + assert.strictEqual(events[0].returnValues.userSigningKey, tester.address) assert.strictEqual(events[1].address, 'SAI') assert.strictEqual(events[1].eventName, 'Approval') @@ -1692,12 +1693,12 @@ module.exports = {test: async function (testingContext) { targetWalletAddress ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 gets a new smart wallet address with same key', DharmaSmartWalletFactoryV1, 'getNextSmartWallet', 'call', - [address], + [tester.address], true, value => { // TODO: verify against expected value @@ -1715,7 +1716,7 @@ module.exports = {test: async function (testingContext) { console.log(' ✓ Eth Whale can no longer deposit eth into the deployed smart wallet') }) - await runTest( + await tester.runTest( 'Sai Whale can deposit sai into the deployed smart wallet', SAI, 'transfer', @@ -1741,7 +1742,7 @@ module.exports = {test: async function (testingContext) { constants.SAI_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'USDC Whale can deposit usdc into the deployed smart wallet', USDC, 'transfer', @@ -1767,7 +1768,7 @@ module.exports = {test: async function (testingContext) { constants.USDC_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'new user smart wallet can trigger repayAndDeposit to deposit all new funds', UserSmartWallet, 'repayAndDeposit', @@ -1821,7 +1822,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'new user smart wallet can trigger repayAndDeposit even with no funds', UserSmartWallet, 'repayAndDeposit', @@ -1849,7 +1850,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'test passes', UserSmartWallet, 'test', @@ -1862,7 +1863,7 @@ module.exports = {test: async function (testingContext) { ) // TODO: wrap in a contract to validate revert reason - await runTest( + await tester.runTest( 'revert test with revert reason passes', UserSmartWallet, 'testRevert', @@ -1871,7 +1872,7 @@ module.exports = {test: async function (testingContext) { false // set this to true to verify that the revert reason is displayed ) - await runTest( + await tester.runTest( 'new user smart wallet can be called and has the correct dharma key set', UserSmartWallet, 'getUserSigningKey', @@ -1879,11 +1880,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - await runTest( + await tester.runTest( 'UserSmartWallet can get the version (0)', UserSmartWallet, 'getVersion', @@ -1895,7 +1896,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet nonce is initially set to 0', UserSmartWallet, 'getNonce', @@ -1907,7 +1908,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet can get balances', UserSmartWallet, 'getBalances', @@ -1919,14 +1920,14 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet secondary can call to withdraw sai', UserSmartWallet, 'withdrawDai', 'send', [ '1000000000000000000', - address, + tester.address, 0, '0x', '0x' @@ -1949,7 +1950,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet nonce is now set to 1', UserSmartWallet, 'getNonce', @@ -1961,14 +1962,14 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet secondary can call to withdraw usdc', UserSmartWallet, 'withdrawUSDC', 'send', [ 1, - address, + tester.address, 0, '0x', '0x' @@ -1980,7 +1981,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet nonce is now set to 2', UserSmartWallet, 'getNonce', @@ -1992,7 +1993,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet secondary can call to cancel', UserSmartWallet, 'cancel', @@ -2003,7 +2004,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'UserSmartWallet nonce is now set to 3', UserSmartWallet, 'getNonce', @@ -2015,20 +2016,20 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet secondary can call to set userSigningKey', UserSmartWallet, 'setUserSigningKey', 'send', [ - address, + tester.address, 0, '0x', '0x' ] ) - await runTest( + await tester.runTest( 'UserSmartWallet nonce is now set to 4', UserSmartWallet, 'getNonce', @@ -2041,7 +2042,7 @@ module.exports = {test: async function (testingContext) { ) let customActionId - await runTest( + await tester.runTest( 'UserSmartWallet can get next custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -2049,7 +2050,7 @@ module.exports = {test: async function (testingContext) { [ 4, // SAIWithdrawal, constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -2058,7 +2059,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet can get custom action ID 4 and it matches next action ID', UserSmartWallet, 'getCustomActionID', @@ -2066,7 +2067,7 @@ module.exports = {test: async function (testingContext) { [ 4, // SAIWithdrawal, constants.FULL_APPROVAL, - address, + tester.address, 4, 0 ], @@ -2076,7 +2077,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -2084,7 +2085,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -2095,17 +2096,17 @@ module.exports = {test: async function (testingContext) { let usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) - await runTest( + await tester.runTest( 'UserSmartWallet relay cannot call with bad signature to withdraw USDC', UserSmartWallet, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, '0x', '0xffffffff' + usdcWithdrawalSignature.slice(10) @@ -2115,17 +2116,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'UserSmartWallet relay can call with signature to withdraw USDC', UserSmartWallet, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, '0x', usdcWithdrawalSignature @@ -2135,7 +2136,7 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt.events) }, - originalAddress + tester.originalAddress ) /* TODO: get this working manually @@ -2157,14 +2158,14 @@ module.exports = {test: async function (testingContext) { ) */ - await runTest( + await tester.runTest( 'UserSmartWallet cannot withdraw too much sai', UserSmartWallet, 'withdrawDai', 'send', [ '100000000000000000000000000000000000000', - address, + tester.address, 0, '0x', '0x' @@ -2187,14 +2188,14 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet cannot withdraw too much usdc', UserSmartWallet, 'withdrawUSDC', 'send', [ '100000000000000000000000000000000', - address, + tester.address, 0, '0x', '0x' @@ -2217,14 +2218,14 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet cannot withdraw too little sai', UserSmartWallet, 'withdrawDai', 'send', [ '1', - address, + tester.address, 0, '0x', '0x' @@ -2245,7 +2246,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet can get a Sai withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -2253,7 +2254,7 @@ module.exports = {test: async function (testingContext) { [ 10, // SaiWithdrawal, constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -2264,17 +2265,17 @@ module.exports = {test: async function (testingContext) { let saiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) - await runTest( + await tester.runTest( 'UserSmartWallet relay cannot call with bad signature to withdraw sai', UserSmartWallet, 'withdrawDai', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, '0x', '0xffffffff' + saiWithdrawalSignature.slice(10) @@ -2284,17 +2285,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'UserSmartWallet relay can call with signature to withdraw sai', UserSmartWallet, 'withdrawDai', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, '0x', saiWithdrawalSignature @@ -2303,10 +2304,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'UserSmartWallet calls revert if insufficient action gas is supplied', UserSmartWallet, 'cancel', @@ -2318,7 +2319,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'UserSmartWallet calls succeed if sufficient non-zero action gas supplied', UserSmartWallet, 'cancel', @@ -2329,20 +2330,20 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'UserSmartWallet calls to atomic methods revert', UserSmartWallet, '_withdrawDaiAtomic', 'send', [ '1', - address + tester.address ], false ) let originalNonce - await runTest( + await tester.runTest( 'UserSmartWallet can get the nonce prior to upgrade', UserSmartWallet, 'getNonce', @@ -2354,7 +2355,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'Dharma Upgrade Beacon Controller can upgrade to V1 implementation', DharmaUpgradeBeaconController, 'upgrade', @@ -2394,7 +2395,7 @@ module.exports = {test: async function (testingContext) { } ) - const UpgradeBeaconImplementationCheckV1 = await runTest( + const UpgradeBeaconImplementationCheckV1 = await tester.runTest( `UpgradeBeaconImplementationCheck deployment`, UpgradeBeaconImplementationCheckDeployer, '', @@ -2405,7 +2406,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'DharmaUpgradeBeacon has the implementation set', DharmaUpgradeBeaconController, 'getImplementation', @@ -2417,7 +2418,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'Dharma Upgrade Beacon Controller can upgrade to V2 implementation', DharmaUpgradeBeaconController, 'upgrade', @@ -2457,7 +2458,7 @@ module.exports = {test: async function (testingContext) { } ) - const UpgradeBeaconImplementationCheckV2 = await runTest( + const UpgradeBeaconImplementationCheckV2 = await tester.runTest( `UpgradeBeaconImplementationCheck deployment`, UpgradeBeaconImplementationCheckDeployer, '', @@ -2468,7 +2469,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'DharmaUpgradeBeacon has the implementation set', DharmaUpgradeBeaconController, 'getImplementation', @@ -2480,7 +2481,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V2 user smart wallet can be called and still has original dharma key set', UserSmartWallet, 'getUserSigningKey', @@ -2488,11 +2489,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - await runTest( + await tester.runTest( 'V2 UserSmartWallet can get the new version (2)', UserSmartWallet, 'getVersion', @@ -2504,7 +2505,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'Dharma Upgrade Beacon Controller can upgrade to V5 implementation', DharmaUpgradeBeaconController, 'upgrade', @@ -2544,7 +2545,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'DharmaUpgradeBeacon has the implementation set', DharmaUpgradeBeaconController, 'getImplementation', @@ -2556,7 +2557,7 @@ module.exports = {test: async function (testingContext) { } ) - const UpgradeBeaconImplementationCheckV5 = await runTest( + const UpgradeBeaconImplementationCheckV5 = await tester.runTest( `UpgradeBeaconImplementationCheck deployment`, UpgradeBeaconImplementationCheckDeployer, '', @@ -2567,7 +2568,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V5 user smart wallet can be called and still has original dharma key set', UserSmartWalletV5, 'getUserSigningKey', @@ -2575,11 +2576,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get the new version (5)', UserSmartWalletV5, 'getVersion', @@ -2591,7 +2592,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet nonce is still set to value from before upgrade', UserSmartWalletV5, 'getNonce', @@ -2603,7 +2604,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get balances', UserSmartWalletV5, 'getBalances', @@ -2615,7 +2616,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet secondary can call to cancel', UserSmartWalletV5, 'cancel', @@ -2626,7 +2627,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet nonce is now set to original + 1', UserSmartWalletV5, 'getNonce', @@ -2638,7 +2639,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get next custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -2646,7 +2647,7 @@ module.exports = {test: async function (testingContext) { [ 4, // SAIWithdrawal, constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -2655,7 +2656,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get custom action ID and it matches next action ID', UserSmartWalletV5, 'getCustomActionID', @@ -2663,7 +2664,7 @@ module.exports = {test: async function (testingContext) { [ 4, // SAIWithdrawal, constants.FULL_APPROVAL, - address, + tester.address, parseInt(originalNonce) + 1, 0 ], @@ -2674,13 +2675,13 @@ module.exports = {test: async function (testingContext) { ) let genericActionID - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get next generic action ID', UserSmartWalletV5, 'getNextGenericActionID', 'call', [ - address, + tester.address, '0x', 0 ], @@ -2690,13 +2691,13 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get generic action ID and it matches next action ID', UserSmartWalletV5, 'getGenericActionID', 'call', [ - address, + tester.address, '0x', parseInt(originalNonce) + 1, 0 @@ -2707,19 +2708,19 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet calls to atomic methods revert', UserSmartWalletV5, '_withdrawSaiAtomic', 'send', [ '1', - address + tester.address ], false ) - await runTest( + await tester.runTest( 'Sai Whale can deposit sai into the V5 smart wallet', SAI, 'transfer', @@ -2745,7 +2746,7 @@ module.exports = {test: async function (testingContext) { constants.SAI_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'USDC Whale can deposit usdc into the V5 smart wallet', USDC, 'transfer', @@ -2771,7 +2772,7 @@ module.exports = {test: async function (testingContext) { constants.USDC_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'V5 user smart wallet can trigger repayAndDeposit to deposit all new funds', UserSmartWalletV5, 'repayAndDeposit', @@ -2826,7 +2827,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'Sai Whale can deposit sai into the V5 smart wallet again', SAI, 'transfer', @@ -2852,7 +2853,7 @@ module.exports = {test: async function (testingContext) { constants.SAI_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a generic action ID', UserSmartWalletV5, 'getNextGenericActionID', @@ -2870,15 +2871,15 @@ module.exports = {test: async function (testingContext) { let executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) let executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet cannot call executeAction and target Escape Hatch Registry', UserSmartWalletV5, 'executeAction', @@ -2893,7 +2894,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a generic action ID', UserSmartWalletV5, 'getNextGenericActionID', @@ -2911,15 +2912,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can call executeAction', UserSmartWalletV5, 'executeAction', @@ -2933,7 +2934,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V5 user smart wallet repayAndDeposit cannot deposit without approval', UserSmartWalletV5, 'repayAndDeposit', @@ -2961,7 +2962,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a generic action ID', UserSmartWalletV5, 'getNextGenericActionID', @@ -2979,15 +2980,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can call executeAction', UserSmartWalletV5, 'executeAction', @@ -3001,7 +3002,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V5 user smart wallet repayAndDeposit can deposit with approval added back', UserSmartWalletV5, 'repayAndDeposit', @@ -3029,7 +3030,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 user smart wallet can trigger repayAndDeposit even with no funds', UserSmartWalletV5, 'repayAndDeposit', @@ -3057,7 +3058,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet secondary cannot set an empty user userSigningKey', UserSmartWalletV5, 'setUserSigningKey', @@ -3071,20 +3072,20 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet secondary can set a custom user userSigningKey', UserSmartWalletV5, 'setUserSigningKey', 'send', [ - addressTwo, + tester.addressTwo, 0, '0x', '0x' ] ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get next custom action ID to set a user signing key', UserSmartWalletV5, 'getNextCustomActionID', @@ -3092,7 +3093,7 @@ module.exports = {test: async function (testingContext) { [ 1, // SetUserSigningKey, constants.FULL_APPROVAL, // This value shouldn't matter - addressTwo, + tester.addressTwo, 0 ], true, @@ -3102,7 +3103,7 @@ module.exports = {test: async function (testingContext) { ) let currentNonce - await runTest( + await tester.runTest( 'UserSmartWallet can get the nonce', UserSmartWalletV5, 'getNonce', @@ -3114,7 +3115,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get custom action ID and it matches next action ID', UserSmartWalletV5, 'getCustomActionID', @@ -3122,7 +3123,7 @@ module.exports = {test: async function (testingContext) { [ 1, // SetUserSigningKey, 0, // Note that this value differs from above - addressTwo, + tester.addressTwo, currentNonce, 0 ], @@ -3134,31 +3135,31 @@ module.exports = {test: async function (testingContext) { let setUserSigningKeyUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) let setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can set a new user signing key with signatures', UserSmartWalletV5, 'setUserSigningKey', 'send', [ - addressTwo, + tester.addressTwo, 0, setUserSigningKeyUserSignature, setUserSigningKeyDharmaSignature ], true, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get next custom action ID to cancel', UserSmartWalletV5, 'getNextCustomActionID', @@ -3166,7 +3167,7 @@ module.exports = {test: async function (testingContext) { [ 0, // Cancel constants.FULL_APPROVAL, // This value shouldn't matter - originalAddress, // This value shouldn't matter either + tester.originalAddress, // This value shouldn't matter either 0 ], true, @@ -3175,7 +3176,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet can get the nonce', UserSmartWalletV5, 'getNonce', @@ -3187,7 +3188,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get custom action ID and it matches next action ID', UserSmartWalletV5, 'getCustomActionID', @@ -3195,7 +3196,7 @@ module.exports = {test: async function (testingContext) { [ 0, // Cancel 0, // Note that this value differs from above - addressTwo, // This one too + tester.addressTwo, // This one too currentNonce, 0 ], @@ -3207,10 +3208,10 @@ module.exports = {test: async function (testingContext) { let cancelUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet secondary can cancel using a signature', UserSmartWalletV5, 'cancel', @@ -3221,10 +3222,10 @@ module.exports = {test: async function (testingContext) { ], true, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'UserSmartWallet nonce is incremented after cancelling', UserSmartWalletV5, 'getNonce', @@ -3236,14 +3237,14 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet secondary cannot call to withdraw sai without primary', UserSmartWalletV5, 'withdrawSai', 'send', [ '1000000000000000000', - address, + tester.address, 0, '0x', '0x' @@ -3251,14 +3252,14 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet secondary cannot call to withdraw usdc without primary', UserSmartWalletV5, 'withdrawUSDC', 'send', [ 1, - address, + tester.address, 0, '0x', '0x' @@ -3266,13 +3267,13 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet secondary can no longer call to set userSigningKey without primary', UserSmartWalletV5, 'setUserSigningKey', 'send', [ - address, + tester.address, 0, '0x', '0x' @@ -3280,7 +3281,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -3288,7 +3289,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, '1', // dust - address, + tester.address, 0 ], true, @@ -3299,22 +3300,22 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) let usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot withdraw "dust" USDC', UserSmartWalletV5, 'withdrawUSDC', 'send', [ '1', - address, + tester.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -3324,10 +3325,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -3346,15 +3347,15 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot withdraw USDC to null address', UserSmartWalletV5, 'withdrawUSDC', @@ -3371,10 +3372,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -3382,7 +3383,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, '100000', - address, + tester.address, 0 ], true, @@ -3393,22 +3394,22 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay can call with two signatures to withdraw USDC', UserSmartWalletV5, 'withdrawUSDC', 'send', [ '100000', - address, + tester.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -3418,10 +3419,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -3429,7 +3430,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -3440,22 +3441,22 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot call with bad signature to withdraw USDC', UserSmartWalletV5, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, usdcUserWithdrawalSignature, '0xffffffff' + usdcWithdrawalSignature.slice(10) @@ -3465,17 +3466,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet cannot call with bad user signature to withdraw USDC', UserSmartWalletV5, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, '0xffffffff' + usdcUserWithdrawalSignature.slice(10), usdcWithdrawalSignature @@ -3485,17 +3486,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay can call with two signatures to withdraw max USDC', UserSmartWalletV5, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -3505,7 +3506,7 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) /* TODO: get this working manually @@ -3527,7 +3528,7 @@ module.exports = {test: async function (testingContext) { ) */ - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a Sai withdrawal custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -3535,7 +3536,7 @@ module.exports = {test: async function (testingContext) { [ 4, // SaiWithdrawal, '1', - address, + tester.address, 0 ], true, @@ -3546,32 +3547,32 @@ module.exports = {test: async function (testingContext) { saiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) let saiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot withdraw "dust" sai', UserSmartWalletV5, 'withdrawDai', 'send', [ '1', - address, + tester.address, 0, saiUserWithdrawalSignature, saiWithdrawalSignature ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a Sai withdrawal custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -3590,15 +3591,15 @@ module.exports = {test: async function (testingContext) { saiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) saiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot withdraw sai to null address', UserSmartWalletV5, 'withdrawDai', @@ -3612,10 +3613,10 @@ module.exports = {test: async function (testingContext) { ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a Sai withdrawal custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -3623,7 +3624,7 @@ module.exports = {test: async function (testingContext) { [ 4, // SaiWithdrawal, '1000000000000000', - address, + tester.address, 0 ], true, @@ -3634,22 +3635,22 @@ module.exports = {test: async function (testingContext) { saiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) saiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay can call with signature to withdraw sai', UserSmartWalletV5, 'withdrawDai', 'send', [ '1000000000000000', - address, + tester.address, 0, saiUserWithdrawalSignature, saiWithdrawalSignature @@ -3659,10 +3660,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt.events) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet cannot get a non-custom "custom" next action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -3670,13 +3671,13 @@ module.exports = {test: async function (testingContext) { [ 2, // Generic, constants.FULL_APPROVAL, - address, + tester.address, 0 ], false ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet cannot get a non-custom "custom" action ID', UserSmartWalletV5, 'getCustomActionID', @@ -3684,14 +3685,14 @@ module.exports = {test: async function (testingContext) { [ 2, // Generic, constants.FULL_APPROVAL, - address, + tester.address, 0, 0 ], false ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a Sai withdrawal custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -3699,7 +3700,7 @@ module.exports = {test: async function (testingContext) { [ 4, // SaiWithdrawal, constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -3710,22 +3711,22 @@ module.exports = {test: async function (testingContext) { saiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) saiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot call with bad signature to withdraw sai', UserSmartWalletV5, 'withdrawDai', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, saiUserWithdrawalSignature, '0xffffffff' + saiWithdrawalSignature.slice(10) @@ -3735,17 +3736,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot call with bad user signature to withdraw sai', UserSmartWalletV5, 'withdrawDai', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, '0xffffffff' + saiUserWithdrawalSignature.slice(10), saiWithdrawalSignature @@ -3755,17 +3756,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay can call with signature to withdraw sai', UserSmartWalletV5, 'withdrawDai', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, saiUserWithdrawalSignature, saiWithdrawalSignature @@ -3774,10 +3775,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a Ether withdrawal custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -3785,7 +3786,7 @@ module.exports = {test: async function (testingContext) { [ 6, // ETHWithdrawal, '0', // no amount - address, + tester.address, 0 ], true, @@ -3796,22 +3797,22 @@ module.exports = {test: async function (testingContext) { let ethWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) let ethUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot to withdraw ether with no amount', UserSmartWalletV5, 'withdrawEther', 'send', [ '0', - address, + tester.address, 0, ethUserWithdrawalSignature, ethWithdrawalSignature @@ -3820,10 +3821,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a Ether withdrawal custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -3842,15 +3843,15 @@ module.exports = {test: async function (testingContext) { ethWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) ethUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot to withdraw ether with no recipient', UserSmartWalletV5, 'withdrawEther', @@ -3866,10 +3867,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a Ether withdrawal custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -3877,7 +3878,7 @@ module.exports = {test: async function (testingContext) { [ 6, // ETHWithdrawal, '1', - address, + tester.address, 0 ], true, @@ -3888,22 +3889,22 @@ module.exports = {test: async function (testingContext) { ethWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) ethUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot call with bad signature to withdraw eth', UserSmartWalletV5, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, ethUserWithdrawalSignature, '0xffffffff' + ethWithdrawalSignature.slice(10) @@ -3913,17 +3914,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot call with bad user signature to withdraw eth', UserSmartWalletV5, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, '0xffffffff' + ethUserWithdrawalSignature.slice(10), ethWithdrawalSignature @@ -3933,17 +3934,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay can call with signature to withdraw ether', UserSmartWalletV5, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, ethUserWithdrawalSignature, ethWithdrawalSignature @@ -3952,10 +3953,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a Ether withdrawal custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -3963,7 +3964,7 @@ module.exports = {test: async function (testingContext) { [ 6, // ETHWithdrawal, '1', - address, + tester.address, 0 ], true, @@ -3974,22 +3975,22 @@ module.exports = {test: async function (testingContext) { ethWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) ethUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot call with bad signature to withdraw eth', UserSmartWalletV5, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, ethUserWithdrawalSignature, '0xffffffff' + ethWithdrawalSignature.slice(10) @@ -3999,17 +4000,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot call with bad user signature to withdraw eth', UserSmartWalletV5, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, '0xffffffff' + ethUserWithdrawalSignature.slice(10), ethWithdrawalSignature @@ -4019,17 +4020,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay can call with signature to withdraw ether', UserSmartWalletV5, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, ethUserWithdrawalSignature, ethWithdrawalSignature @@ -4038,10 +4039,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet cancel reverts with bad signature', UserSmartWalletV5, 'cancel', @@ -4052,10 +4053,10 @@ module.exports = {test: async function (testingContext) { ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet calls revert if insufficient action gas is supplied', UserSmartWalletV5, 'cancel', @@ -4067,7 +4068,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet calls succeed if sufficient non-zero action gas supplied', UserSmartWalletV5, 'cancel', @@ -4078,7 +4079,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a cancel custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -4086,7 +4087,7 @@ module.exports = {test: async function (testingContext) { [ 0, // Cancel, '0', - address, + tester.address, 0 ], true, @@ -4095,9 +4096,9 @@ module.exports = {test: async function (testingContext) { } ) - let cancelSignature = signHashedPrefixedHexString(customActionId, addressTwo) + let cancelSignature = signHashedPrefixedHexString(customActionId, tester.addressTwo) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can cancel using a signature', UserSmartWalletV5, 'cancel', @@ -4108,38 +4109,38 @@ module.exports = {test: async function (testingContext) { ], true, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet calls to atomic methods revert', UserSmartWalletV5, '_withdrawSaiAtomic', 'send', [ '1', - address + tester.address ], false ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet calls to recover from random address revert', UserSmartWalletV5, 'recover', 'send', [ - address + tester.address ], false ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can deploy a V5 smart wallet using a Dharma Key', DharmaSmartWalletFactoryV1, 'newSmartWallet', 'send', - [addressTwo], + [tester.addressTwo], true, receipt => { //console.log(receipt.status, receipt.gasUsed) @@ -4158,7 +4159,7 @@ module.exports = {test: async function (testingContext) { }) assert.strictEqual(events[0].eventName, 'NewUserSigningKey') - assert.strictEqual(events[0].returnValues.userSigningKey, addressTwo) + assert.strictEqual(events[0].returnValues.userSigningKey, tester.addressTwo) //console.log(events) // TODO: test more events @@ -4166,7 +4167,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a generic action ID', UserSmartWalletV5, 'getNextGenericActionID', @@ -4184,21 +4185,21 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet cannot call executeAction and target a non-contract', UserSmartWalletV5, 'executeAction', 'send', [ - address, + tester.address, USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), 0, executeActionUserSignature, @@ -4207,7 +4208,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet cannot call executeAction and target itself', UserSmartWalletV5, 'executeAction', @@ -4222,7 +4223,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can call executeAction', UserSmartWalletV5, 'executeAction', @@ -4236,7 +4237,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get the next generic batch action ID', UserSmartWalletV5, 'getNextGenericAtomicBatchActionID', @@ -4251,7 +4252,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet can get the nonce', UserSmartWalletV5, 'getNonce', @@ -4263,7 +4264,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet generic batch action ID with nonce matches next ID', UserSmartWalletV5, 'getGenericAtomicBatchActionID', @@ -4281,15 +4282,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can call executeActionWithAtomicBatchCalls', UserSmartWalletV5, 'executeActionWithAtomicBatchCalls', @@ -4302,7 +4303,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'USDC Whale can deposit usdc into the deployed smart wallet', USDC, 'transfer', @@ -4328,7 +4329,7 @@ module.exports = {test: async function (testingContext) { constants.USDC_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'new user smart wallet can trigger repayAndDeposit to deposit all new funds', UserSmartWalletV5, 'repayAndDeposit', @@ -4407,7 +4408,7 @@ module.exports = {test: async function (testingContext) { ) let blacklister - await runTest( + await tester.runTest( 'Check blacklister address', FIAT_TOKEN, 'blacklister', @@ -4420,7 +4421,7 @@ module.exports = {test: async function (testingContext) { ) let pausear - await runTest( + await tester.runTest( 'Check pauser address', FIAT_TOKEN, 'pauser', @@ -4432,7 +4433,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'blacklist mock address', FIAT_TOKEN, 'blacklist', @@ -4444,7 +4445,7 @@ module.exports = {test: async function (testingContext) { ) let targetBlacklistAddress; - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', DharmaSmartWalletFactoryV1, 'getNextSmartWallet', @@ -4461,7 +4462,7 @@ module.exports = {test: async function (testingContext) { targetBlacklistAddress ) - await runTest( + await tester.runTest( 'USDC Whale can deposit usdc into the yet-to-be-blacklisted smart wallet', USDC, 'transfer', @@ -4487,7 +4488,7 @@ module.exports = {test: async function (testingContext) { constants.USDC_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'blacklist counterfactual deployment address', FIAT_TOKEN, 'blacklist', @@ -4498,7 +4499,7 @@ module.exports = {test: async function (testingContext) { blacklister ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can deploy to a blacklisted address', DharmaSmartWalletFactoryV1, 'newSmartWallet', @@ -4511,7 +4512,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'blacklisted smart wallet will not approve USDC during repayAndDeposit', BlacklistedUserSmartWalletV5, 'repayAndDeposit', @@ -4524,7 +4525,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'un-blacklist counterfactual deployment address', FIAT_TOKEN, 'unBlacklist', @@ -4535,7 +4536,7 @@ module.exports = {test: async function (testingContext) { blacklister ) - await runTest( + await tester.runTest( 'pause USDC', FIAT_TOKEN, 'pause', @@ -4546,7 +4547,7 @@ module.exports = {test: async function (testingContext) { pauser ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -4554,7 +4555,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -4565,22 +4566,22 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet attempt to withdraw max USDC when paused causes ExternalError', UserSmartWalletV5, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -4590,10 +4591,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'smart wallet will not approve USDC when paused during repayAndDeposit', BlacklistedUserSmartWalletV5, 'repayAndDeposit', @@ -4606,7 +4607,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'unpause USDC', FIAT_TOKEN, 'unpause', @@ -4617,7 +4618,7 @@ module.exports = {test: async function (testingContext) { pauser ) - await runTest( + await tester.runTest( 'unblacklisted, unpaused smart wallet approves USDC during repayAndDeposit', BlacklistedUserSmartWalletV5, 'repayAndDeposit', @@ -4630,7 +4631,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -4649,15 +4650,15 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay call to withdraw USDC to blacklisted address', UserSmartWallet, 'withdrawUSDC', @@ -4675,10 +4676,10 @@ module.exports = {test: async function (testingContext) { //console.log(receipt.events[0]) //console.log(receipt.events.ExternalError) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -4697,15 +4698,15 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay call to withdraw USDC to itself', UserSmartWallet, 'withdrawUSDC', @@ -4721,10 +4722,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -4743,15 +4744,15 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay call to withdraw USDC to blacklisted address', UserSmartWallet, 'withdrawUSDC', @@ -4769,10 +4770,10 @@ module.exports = {test: async function (testingContext) { //console.log(receipt.events[0]) //console.log(receipt.events.ExternalError) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a Ether withdrawal custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -4791,15 +4792,15 @@ module.exports = {test: async function (testingContext) { ethWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) ethUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot withdraw eth to a non-payable account', UserSmartWalletV5, 'withdrawEther', @@ -4816,11 +4817,11 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) let targetWalletAddressTwo; - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', DharmaSmartWalletFactoryV1, 'getNextSmartWallet', @@ -4833,7 +4834,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can deploy a V5 smart wallet using a contract key', DharmaSmartWalletFactoryV1, 'newSmartWallet', @@ -4846,7 +4847,7 @@ module.exports = {test: async function (testingContext) { targetWalletAddressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet cancel reverts with bad contract signature', UserSmartWalletV5Two, 'cancel', @@ -4857,17 +4858,17 @@ module.exports = {test: async function (testingContext) { ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a generic action ID', UserSmartWalletV5, 'getNextGenericActionID', 'call', [ SAI.options.address, - SAI.methods.transfer(address, constants.FULL_APPROVAL).encodeABI(), + SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), 0 ], true, @@ -4878,29 +4879,29 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can call executeAction', UserSmartWalletV5, 'executeAction', 'send', [ SAI.options.address, - SAI.methods.transfer(address, constants.FULL_APPROVAL).encodeABI(), + SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), 0, executeActionUserSignature, executeActionSignature ] ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a Sai withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -4908,7 +4909,7 @@ module.exports = {test: async function (testingContext) { [ 4, // SaiWithdrawal, '100000000000000000000000000000000000000', // too much - address, + tester.address, 0 ], true, @@ -4919,22 +4920,22 @@ module.exports = {test: async function (testingContext) { saiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) saiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot withdraw too much sai', UserSmartWallet, 'withdrawDai', 'send', [ '100000000000000000000000000000000000000', // too much - address, + tester.address, 0, saiUserWithdrawalSignature, saiWithdrawalSignature @@ -4944,10 +4945,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt.events) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -4955,7 +4956,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, '100000000000000000000000000000000000000', // too much - address, + tester.address, 0 ], true, @@ -4966,23 +4967,23 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay can call with two signatures to withdraw USDC', UserSmartWallet, 'withdrawUSDC', 'send', [ '100000000000000000000000000000000000000', // too much - address, + tester.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -4992,10 +4993,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get next generic batch action ID', UserSmartWalletV5, 'getNextGenericAtomicBatchActionID', @@ -5004,7 +5005,7 @@ module.exports = {test: async function (testingContext) { [{ to: SAI.options.address, data: SAI.methods.transfer( - address, '100000000000000000000000000000' + tester.address, '100000000000000000000000000000' ).encodeABI() }], 0 @@ -5017,15 +5018,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet bad executeActionWithAtomicBatchCalls emits CallFailure', UserSmartWalletV5, 'executeActionWithAtomicBatchCalls', @@ -5034,7 +5035,7 @@ module.exports = {test: async function (testingContext) { [{ to: SAI.options.address, data: SAI.methods.transfer( - address, '100000000000000000000000000000' + tester.address, '100000000000000000000000000000' ).encodeABI() }], 0, @@ -5047,7 +5048,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a generic action ID', UserSmartWalletV5, 'getNextGenericActionID', @@ -5067,15 +5068,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can call executeAction to enter sai market', UserSmartWalletV5, 'executeAction', @@ -5091,7 +5092,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'Sai Whale can deposit sai into the smart wallet', SAI, 'transfer', @@ -5117,20 +5118,20 @@ module.exports = {test: async function (testingContext) { constants.SAI_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can trigger repayAndDeposit to deposit all new funds', UserSmartWalletV5, 'repayAndDeposit' ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a generic action ID', UserSmartWalletV5, 'getNextGenericActionID', 'call', [ CSAI.options.address, - CSAI.methods.transfer(address, web3.utils.toWei('1', 'mwei')).encodeABI(), + CSAI.methods.transfer(tester.address, web3.utils.toWei('1', 'mwei')).encodeABI(), 0 ], true, @@ -5141,22 +5142,22 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can call executeAction to transfer cSai', UserSmartWalletV5, 'executeAction', 'send', [ CSAI.options.address, - CSAI.methods.transfer(address, web3.utils.toWei('1', 'mwei')).encodeABI(), + CSAI.methods.transfer(tester.address, web3.utils.toWei('1', 'mwei')).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -5165,10 +5166,10 @@ module.exports = {test: async function (testingContext) { receipt => { //console.log(receipt.events) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a generic action ID', UserSmartWalletV5, 'getNextGenericActionID', @@ -5186,15 +5187,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can call executeAction to perform a borrow', UserSmartWalletV5, 'executeAction', @@ -5210,10 +5211,10 @@ module.exports = {test: async function (testingContext) { receipt => { //console.log(receipt.events) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet can get a Sai withdrawal custom action ID', UserSmartWalletV5, 'getNextCustomActionID', @@ -5221,7 +5222,7 @@ module.exports = {test: async function (testingContext) { [ 4, // SaiWithdrawal, constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -5232,22 +5233,22 @@ module.exports = {test: async function (testingContext) { saiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) saiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V5 UserSmartWallet relay cannot withdraw max sai with an outstanding borrow', UserSmartWalletV5, 'withdrawDai', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, saiUserWithdrawalSignature, saiWithdrawalSignature @@ -5257,18 +5258,18 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt.events) }, - originalAddress + tester.originalAddress ) // Initiate account recovery - await runTest( + await tester.runTest( 'smart wallet account recovery can be initiated', DharmaAccountRecoveryManagerV2, 'initiateAccountRecovery', 'send', [ UserSmartWalletV5.options.address, - originalAddress, + tester.originalAddress, 0 // extraTime in seconds ], true, @@ -5278,14 +5279,14 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'smart wallet account recovery cannot be performed right away', DharmaAccountRecoveryManagerV2, 'recover', 'send', [ UserSmartWalletV5.options.address, - originalAddress + tester.originalAddress ], false ) @@ -5294,14 +5295,14 @@ module.exports = {test: async function (testingContext) { await advanceTime((60 * 60 * 24 * 3) + 5) // recover account - await runTest( + await tester.runTest( 'smart wallet account recovery can be performed after three days', DharmaAccountRecoveryManagerV2, 'recover', 'send', [ UserSmartWalletV5.options.address, - originalAddress + tester.originalAddress ], true, receipt => { @@ -5310,7 +5311,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWalletV5 can get the nonce prior to upgrade', UserSmartWalletV5, 'getNonce', @@ -5326,7 +5327,7 @@ module.exports = {test: async function (testingContext) { - await runTest( + await tester.runTest( 'Dharma Upgrade Beacon Controller can upgrade to V6 implementation', DharmaUpgradeBeaconController, 'upgrade', @@ -5366,7 +5367,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'DharmaUpgradeBeacon has the implementation set', DharmaUpgradeBeaconController, 'getImplementation', @@ -5378,7 +5379,7 @@ module.exports = {test: async function (testingContext) { } ) - const UpgradeBeaconImplementationCheckV6 = await runTest( + const UpgradeBeaconImplementationCheckV6 = await tester.runTest( `UpgradeBeaconImplementationCheck deployment`, UpgradeBeaconImplementationCheckDeployer, '', @@ -5389,7 +5390,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V6 user smart wallet can be called and still has the same dharma key set', UserSmartWalletV6, 'getUserSigningKey', @@ -5397,11 +5398,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, originalAddress) + assert.strictEqual(value, tester.originalAddress) } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get the new version (6)', UserSmartWalletV6, 'getVersion', @@ -5413,7 +5414,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet nonce is still set to value from before upgrade', UserSmartWalletV6, 'getNonce', @@ -5425,7 +5426,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get balances', UserSmartWalletV6, 'getBalances', @@ -5437,7 +5438,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet secondary can call to cancel', UserSmartWalletV6, 'cancel', @@ -5448,7 +5449,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet nonce is now set to original + 1', UserSmartWalletV6, 'getNonce', @@ -5460,7 +5461,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get next custom action ID to set a user signing key', UserSmartWalletV6, 'getNextCustomActionID', @@ -5468,7 +5469,7 @@ module.exports = {test: async function (testingContext) { [ 1, // SetUserSigningKey, constants.FULL_APPROVAL, // This value shouldn't matter - addressTwo, + tester.addressTwo, 0 ], true, @@ -5479,26 +5480,26 @@ module.exports = {test: async function (testingContext) { setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can set a new user signing key with signatures', UserSmartWalletV6, 'setUserSigningKey', 'send', [ - addressTwo, + tester.addressTwo, 0, '0x', setUserSigningKeyDharmaSignature ], true, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet has the new user signing key set', UserSmartWalletV6, 'getUserSigningKey', @@ -5506,11 +5507,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, addressTwo) + assert.strictEqual(value, tester.addressTwo) } ) - await runTest( + await tester.runTest( 'cSai can be sent to V6 UserSmartWallet', CSAI, 'transfer', @@ -5518,7 +5519,7 @@ module.exports = {test: async function (testingContext) { [UserSmartWalletV6.options.address, web3.utils.toWei('0.5', 'mwei')] ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay can trigger cSai to cDai migration before cDai approval', UserSmartWalletV6, 'migrateCSaiToCDai', @@ -5528,10 +5529,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get next custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -5539,7 +5540,7 @@ module.exports = {test: async function (testingContext) { [ 0, // DAIWithdrawal constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -5548,7 +5549,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get custom action ID and it matches next action ID', UserSmartWalletV6, 'getCustomActionID', @@ -5556,7 +5557,7 @@ module.exports = {test: async function (testingContext) { [ 0, // DAIWithdrawal constants.FULL_APPROVAL, - address, + tester.address, parseInt(originalNonce) + 2, 0 ], @@ -5566,13 +5567,13 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get next generic action ID', UserSmartWalletV6, 'getNextGenericActionID', 'call', [ - address, + tester.address, '0x', 0 ], @@ -5582,13 +5583,13 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get generic action ID and it matches next action ID', UserSmartWalletV6, 'getGenericActionID', 'call', [ - address, + tester.address, '0x', parseInt(originalNonce) + 2, 0 @@ -5599,28 +5600,28 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet calls to atomic methods revert', UserSmartWalletV6, '_withdrawDaiAtomic', 'send', [ '1', - address + tester.address ], false ) // Give the Dai Whale some ETH so it can make transactions await web3.eth.sendTransaction({ - from: address, + from: tester.address, to: constants.DAI_WHALE_ADDRESS, value: web3.utils.toWei('1', 'ether'), gas: (testingContext !== 'coverage') ? '0xffff' : gasLimit - 1, gasPrice: 1 }) - await runTest( + await tester.runTest( 'Dai Whale can deposit Dai into the V6 smart wallet', DAI, 'transfer', @@ -5646,7 +5647,7 @@ module.exports = {test: async function (testingContext) { constants.DAI_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'USDC Whale can deposit usdc into the V6 smart wallet', USDC, 'transfer', @@ -5672,7 +5673,7 @@ module.exports = {test: async function (testingContext) { constants.USDC_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a generic action ID', UserSmartWalletV6, 'getNextGenericActionID', @@ -5690,15 +5691,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can call executeAction', UserSmartWalletV6, 'executeAction', @@ -5712,7 +5713,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V6 user smart wallet can trigger repayAndDeposit to deposit all new funds', UserSmartWalletV6, 'repayAndDeposit', @@ -5769,7 +5770,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'Dai Whale can deposit dai into the V6 smart wallet', DAI, 'transfer', @@ -5795,7 +5796,7 @@ module.exports = {test: async function (testingContext) { constants.DAI_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a generic action ID', UserSmartWalletV6, 'getNextGenericActionID', @@ -5813,15 +5814,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet cannot call executeAction and target Escape Hatch Registry', UserSmartWalletV6, 'executeAction', @@ -5836,7 +5837,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a generic action ID', UserSmartWalletV6, 'getNextGenericActionID', @@ -5854,15 +5855,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can call executeAction', UserSmartWalletV6, 'executeAction', @@ -5876,7 +5877,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V6 user smart wallet repayAndDeposit can still deposit without approval', UserSmartWalletV6, 'repayAndDeposit', @@ -5904,7 +5905,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a generic action ID', UserSmartWalletV6, 'getNextGenericActionID', @@ -5922,15 +5923,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can call executeAction', UserSmartWalletV6, 'executeAction', @@ -5944,7 +5945,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V6 user smart wallet repayAndDeposit can deposit with approval added back', UserSmartWalletV6, 'repayAndDeposit', @@ -5972,7 +5973,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 user smart wallet can trigger repayAndDeposit even with no funds', UserSmartWalletV6, 'repayAndDeposit', @@ -6000,7 +6001,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get custom action ID and it matches next action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -6019,15 +6020,15 @@ module.exports = {test: async function (testingContext) { setUserSigningKeyUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet cannot set the null address as a new user signing key', UserSmartWalletV6, 'setUserSigningKey', @@ -6040,10 +6041,10 @@ module.exports = {test: async function (testingContext) { ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get next custom action ID to set a user signing key', UserSmartWalletV6, 'getNextCustomActionID', @@ -6051,7 +6052,7 @@ module.exports = {test: async function (testingContext) { [ 1, // SetUserSigningKey, constants.FULL_APPROVAL, // This value shouldn't matter - addressTwo, + tester.addressTwo, 0 ], true, @@ -6060,7 +6061,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet can get the nonce', UserSmartWalletV6, 'getNonce', @@ -6072,7 +6073,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get custom action ID and it matches next action ID', UserSmartWalletV6, 'getCustomActionID', @@ -6080,7 +6081,7 @@ module.exports = {test: async function (testingContext) { [ 1, // SetUserSigningKey, 0, // Note that this value differs from above - addressTwo, + tester.addressTwo, currentNonce, 0 ], @@ -6092,31 +6093,31 @@ module.exports = {test: async function (testingContext) { setUserSigningKeyUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can set a new user signing key with signatures', UserSmartWalletV6, 'setUserSigningKey', 'send', [ - addressTwo, + tester.addressTwo, 0, setUserSigningKeyUserSignature, setUserSigningKeyDharmaSignature ], true, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get next custom action ID to cancel', UserSmartWalletV6, 'getNextCustomActionID', @@ -6124,7 +6125,7 @@ module.exports = {test: async function (testingContext) { [ 0, // Cancel constants.FULL_APPROVAL, // This value shouldn't matter - originalAddress, // This value shouldn't matter either + tester.originalAddress, // This value shouldn't matter either 0 ], true, @@ -6133,7 +6134,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet can get the nonce', UserSmartWalletV6, 'getNonce', @@ -6145,7 +6146,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get custom action ID and it matches next action ID', UserSmartWalletV6, 'getCustomActionID', @@ -6153,7 +6154,7 @@ module.exports = {test: async function (testingContext) { [ 0, // Cancel 0, // Note that this value differs from above - addressTwo, // This one too + tester.addressTwo, // This one too currentNonce, 0 ], @@ -6165,10 +6166,10 @@ module.exports = {test: async function (testingContext) { cancelUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet secondary can cancel using a signature', UserSmartWalletV6, 'cancel', @@ -6179,10 +6180,10 @@ module.exports = {test: async function (testingContext) { ], true, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'UserSmartWallet nonce is incremented after cancelling', UserSmartWalletV6, 'getNonce', @@ -6194,14 +6195,14 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet secondary cannot call to withdraw dai without primary', UserSmartWalletV6, 'withdrawDai', 'send', [ '1000000000000000000', - address, + tester.address, 0, '0x', '0x' @@ -6209,14 +6210,14 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet secondary cannot call to withdraw usdc without primary', UserSmartWalletV6, 'withdrawUSDC', 'send', [ 1, - address, + tester.address, 0, '0x', '0x' @@ -6224,13 +6225,13 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet secondary can no longer call to set userSigningKey without primary', UserSmartWalletV6, 'setUserSigningKey', 'send', [ - address, + tester.address, 0, '0x', '0x' @@ -6238,7 +6239,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -6246,7 +6247,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, '1', // dust - address, + tester.address, 0 ], true, @@ -6257,22 +6258,22 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot withdraw "dust" USDC', UserSmartWalletV6, 'withdrawUSDC', 'send', [ '1', - address, + tester.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -6282,10 +6283,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -6304,15 +6305,15 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot withdraw USDC to null address', UserSmartWalletV6, 'withdrawUSDC', @@ -6329,10 +6330,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -6340,7 +6341,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, '100000', - address, + tester.address, 0 ], true, @@ -6351,22 +6352,22 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay can call with two signatures to withdraw USDC', UserSmartWalletV6, 'withdrawUSDC', 'send', [ '100000', - address, + tester.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -6376,10 +6377,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -6387,7 +6388,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -6398,22 +6399,22 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot call with bad signature to withdraw USDC', UserSmartWalletV6, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, usdcUserWithdrawalSignature, '0xffffffff' + usdcWithdrawalSignature.slice(10) @@ -6423,17 +6424,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet cannot call with bad user signature to withdraw USDC', UserSmartWalletV6, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, '0xffffffff' + usdcUserWithdrawalSignature.slice(10), usdcWithdrawalSignature @@ -6443,17 +6444,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay can call with two signatures to withdraw max USDC', UserSmartWalletV6, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -6463,7 +6464,7 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) /* TODO: get this working manually @@ -6485,7 +6486,7 @@ module.exports = {test: async function (testingContext) { ) */ - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a Dai withdrawal custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -6493,7 +6494,7 @@ module.exports = {test: async function (testingContext) { [ 10, // DaiWithdrawal '1', - address, + tester.address, 0 ], true, @@ -6504,32 +6505,32 @@ module.exports = {test: async function (testingContext) { let daiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) let daiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot withdraw "dust" dai', UserSmartWalletV6, 'withdrawDai', 'send', [ '1', - address, + tester.address, 0, daiUserWithdrawalSignature, daiWithdrawalSignature ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a Dai withdrawal custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -6548,15 +6549,15 @@ module.exports = {test: async function (testingContext) { daiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) daiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot withdraw dai to null address', UserSmartWalletV6, 'withdrawDai', @@ -6570,10 +6571,10 @@ module.exports = {test: async function (testingContext) { ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a Dai withdrawal custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -6581,7 +6582,7 @@ module.exports = {test: async function (testingContext) { [ 10, // DaiWithdrawal '1000000000000000', - address, + tester.address, 0 ], true, @@ -6592,22 +6593,22 @@ module.exports = {test: async function (testingContext) { daiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) daiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay can call with signature to withdraw dai', UserSmartWalletV6, 'withdrawDai', 'send', [ '1000000000000000', - address, + tester.address, 0, daiUserWithdrawalSignature, daiWithdrawalSignature @@ -6617,10 +6618,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt.events) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet cannot get a non-custom "custom" next action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -6628,13 +6629,13 @@ module.exports = {test: async function (testingContext) { [ 2, // Generic, constants.FULL_APPROVAL, - address, + tester.address, 0 ], false ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet cannot get a non-custom "custom" action ID', UserSmartWalletV6, 'getCustomActionID', @@ -6642,14 +6643,14 @@ module.exports = {test: async function (testingContext) { [ 2, // Generic, constants.FULL_APPROVAL, - address, + tester.address, 0, 0 ], false ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a Dai withdrawal custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -6657,7 +6658,7 @@ module.exports = {test: async function (testingContext) { [ 10, // DaiWithdrawal constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -6668,22 +6669,22 @@ module.exports = {test: async function (testingContext) { daiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) daiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot call with bad signature to withdraw dai', UserSmartWalletV6, 'withdrawDai', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, daiUserWithdrawalSignature, '0xffffffff' + daiWithdrawalSignature.slice(10) @@ -6693,17 +6694,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot call with bad user signature to withdraw dai', UserSmartWalletV6, 'withdrawDai', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, '0xffffffff' + daiUserWithdrawalSignature.slice(10), daiWithdrawalSignature @@ -6713,17 +6714,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay can call with signature to withdraw sai', UserSmartWalletV6, 'withdrawDai', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, daiUserWithdrawalSignature, daiWithdrawalSignature @@ -6732,10 +6733,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a Ether withdrawal custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -6743,7 +6744,7 @@ module.exports = {test: async function (testingContext) { [ 6, // ETHWithdrawal, '0', // no amount - address, + tester.address, 0 ], true, @@ -6754,22 +6755,22 @@ module.exports = {test: async function (testingContext) { ethWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) ethUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot to withdraw ether with no amount', UserSmartWalletV6, 'withdrawEther', 'send', [ '0', - address, + tester.address, 0, ethUserWithdrawalSignature, ethWithdrawalSignature @@ -6778,10 +6779,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a Ether withdrawal custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -6800,15 +6801,15 @@ module.exports = {test: async function (testingContext) { ethWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) ethUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot to withdraw ether with no recipient', UserSmartWalletV6, 'withdrawEther', @@ -6824,10 +6825,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a Ether withdrawal custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -6835,7 +6836,7 @@ module.exports = {test: async function (testingContext) { [ 6, // ETHWithdrawal, '1', - address, + tester.address, 0 ], true, @@ -6846,22 +6847,22 @@ module.exports = {test: async function (testingContext) { ethWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) ethUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot call with bad signature to withdraw eth', UserSmartWalletV6, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, ethUserWithdrawalSignature, '0xffffffff' + ethWithdrawalSignature.slice(10) @@ -6871,17 +6872,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot call with bad user signature to withdraw eth', UserSmartWalletV6, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, '0xffffffff' + ethUserWithdrawalSignature.slice(10), ethWithdrawalSignature @@ -6891,17 +6892,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay can call with signature to withdraw ether', UserSmartWalletV6, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, ethUserWithdrawalSignature, ethWithdrawalSignature @@ -6910,10 +6911,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a Ether withdrawal custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -6921,7 +6922,7 @@ module.exports = {test: async function (testingContext) { [ 6, // ETHWithdrawal, '1', - address, + tester.address, 0 ], true, @@ -6932,22 +6933,22 @@ module.exports = {test: async function (testingContext) { ethWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) ethUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot call with bad signature to withdraw eth', UserSmartWalletV6, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, ethUserWithdrawalSignature, '0xffffffff' + ethWithdrawalSignature.slice(10) @@ -6957,17 +6958,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot call with bad user signature to withdraw eth', UserSmartWalletV6, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, '0xffffffff' + ethUserWithdrawalSignature.slice(10), ethWithdrawalSignature @@ -6977,17 +6978,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay can call with signature to withdraw ether', UserSmartWalletV6, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, ethUserWithdrawalSignature, ethWithdrawalSignature @@ -6996,10 +6997,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet cancel reverts with bad signature', UserSmartWalletV6, 'cancel', @@ -7010,10 +7011,10 @@ module.exports = {test: async function (testingContext) { ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet calls revert if insufficient action gas is supplied', UserSmartWalletV6, 'cancel', @@ -7025,7 +7026,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet calls succeed if sufficient non-zero action gas supplied', UserSmartWalletV6, 'cancel', @@ -7036,7 +7037,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a cancel custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -7044,7 +7045,7 @@ module.exports = {test: async function (testingContext) { [ 0, // Cancel, '0', - address, + tester.address, 0 ], true, @@ -7053,9 +7054,9 @@ module.exports = {test: async function (testingContext) { } ) - cancelSignature = signHashedPrefixedHexString(customActionId, addressTwo) + cancelSignature = signHashedPrefixedHexString(customActionId, tester.addressTwo) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can cancel using a signature', UserSmartWalletV6, 'cancel', @@ -7066,38 +7067,38 @@ module.exports = {test: async function (testingContext) { ], true, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet calls to atomic methods revert', UserSmartWalletV6, '_withdrawDaiAtomic', 'send', [ '1', - address + tester.address ], false ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet calls to recover from random address revert', UserSmartWalletV6, 'recover', 'send', [ - address + tester.address ], false ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can deploy a V6 smart wallet using a Dharma Key', DharmaSmartWalletFactoryV1, 'newSmartWallet', 'send', - [addressTwo], + [tester.addressTwo], true, receipt => { //console.log(receipt.status, receipt.gasUsed) @@ -7116,7 +7117,7 @@ module.exports = {test: async function (testingContext) { }) assert.strictEqual(events[0].eventName, 'NewUserSigningKey') - assert.strictEqual(events[0].returnValues.userSigningKey, addressTwo) + assert.strictEqual(events[0].returnValues.userSigningKey, tester.addressTwo) //console.log(events) // TODO: test more events @@ -7124,7 +7125,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a generic action ID', UserSmartWalletV6, 'getNextGenericActionID', @@ -7142,21 +7143,21 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet cannot call executeAction and target a non-contract', UserSmartWalletV6, 'executeAction', 'send', [ - address, + tester.address, USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), 0, executeActionUserSignature, @@ -7165,7 +7166,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet cannot call executeAction and target itself', UserSmartWalletV6, 'executeAction', @@ -7180,7 +7181,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can call executeAction', UserSmartWalletV6, 'executeAction', @@ -7194,7 +7195,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get the next generic batch action ID', UserSmartWalletV6, 'getNextGenericAtomicBatchActionID', @@ -7209,7 +7210,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet can get the nonce', UserSmartWalletV6, 'getNonce', @@ -7221,7 +7222,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet generic batch action ID with nonce matches next ID', UserSmartWalletV6, 'getGenericAtomicBatchActionID', @@ -7239,15 +7240,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can call executeActionWithAtomicBatchCalls', UserSmartWalletV6, 'executeActionWithAtomicBatchCalls', @@ -7260,7 +7261,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'USDC Whale can deposit usdc into the deployed smart wallet', USDC, 'transfer', @@ -7286,7 +7287,7 @@ module.exports = {test: async function (testingContext) { constants.USDC_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'new user smart wallet can trigger repayAndDeposit to deposit all new funds', UserSmartWalletV6, 'repayAndDeposit', @@ -7329,7 +7330,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'Check blacklister address', FIAT_TOKEN, 'blacklister', @@ -7341,7 +7342,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'Check pauser address', FIAT_TOKEN, 'pauser', @@ -7353,7 +7354,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'blacklist mock address', FIAT_TOKEN, 'blacklist', @@ -7364,7 +7365,7 @@ module.exports = {test: async function (testingContext) { blacklister ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', DharmaSmartWalletFactoryV1, 'getNextSmartWallet', @@ -7381,7 +7382,7 @@ module.exports = {test: async function (testingContext) { targetBlacklistAddress ) - await runTest( + await tester.runTest( 'USDC Whale can deposit usdc into the yet-to-be-blacklisted smart wallet', USDC, 'transfer', @@ -7407,7 +7408,7 @@ module.exports = {test: async function (testingContext) { constants.USDC_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'blacklist counterfactual deployment address', FIAT_TOKEN, 'blacklist', @@ -7418,7 +7419,7 @@ module.exports = {test: async function (testingContext) { blacklister ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can deploy to a blacklisted address', DharmaSmartWalletFactoryV1, 'newSmartWallet', @@ -7431,7 +7432,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'blacklisted smart wallet will not approve USDC during repayAndDeposit', BlacklistedUserSmartWalletV6, 'repayAndDeposit', @@ -7444,7 +7445,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'un-blacklist counterfactual deployment address', FIAT_TOKEN, 'unBlacklist', @@ -7455,7 +7456,7 @@ module.exports = {test: async function (testingContext) { blacklister ) - await runTest( + await tester.runTest( 'pause USDC', FIAT_TOKEN, 'pause', @@ -7466,7 +7467,7 @@ module.exports = {test: async function (testingContext) { pauser ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -7474,7 +7475,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -7485,22 +7486,22 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet attempt to withdraw max USDC when paused causes ExternalError', UserSmartWalletV6, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -7510,10 +7511,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'smart wallet will not approve USDC when paused during repayAndDeposit', BlacklistedUserSmartWalletV6, 'repayAndDeposit', @@ -7526,7 +7527,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'unpause USDC', FIAT_TOKEN, 'unpause', @@ -7537,7 +7538,7 @@ module.exports = {test: async function (testingContext) { pauser ) - await runTest( + await tester.runTest( 'unblacklisted, unpaused smart wallet approves USDC during repayAndDeposit', BlacklistedUserSmartWalletV6, 'repayAndDeposit', @@ -7550,7 +7551,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -7569,15 +7570,15 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay call to withdraw USDC to blacklisted address', UserSmartWallet, 'withdrawUSDC', @@ -7595,10 +7596,10 @@ module.exports = {test: async function (testingContext) { //console.log(receipt.events[0]) //console.log(receipt.events.ExternalError) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -7617,15 +7618,15 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay call to withdraw USDC to itself', UserSmartWallet, 'withdrawUSDC', @@ -7641,10 +7642,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -7663,15 +7664,15 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay call to withdraw USDC to blacklisted address', UserSmartWallet, 'withdrawUSDC', @@ -7689,10 +7690,10 @@ module.exports = {test: async function (testingContext) { //console.log(receipt.events[0]) //console.log(receipt.events.ExternalError) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a Ether withdrawal custom action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -7711,15 +7712,15 @@ module.exports = {test: async function (testingContext) { ethWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) ethUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot withdraw eth to a non-payable account', UserSmartWalletV6, 'withdrawEther', @@ -7736,10 +7737,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', DharmaSmartWalletFactoryV1, 'getNextSmartWallet', @@ -7752,7 +7753,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can deploy a V6 smart wallet using a contract key', DharmaSmartWalletFactoryV1, 'newSmartWallet', @@ -7765,7 +7766,7 @@ module.exports = {test: async function (testingContext) { targetWalletAddressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet cancel reverts with bad contract signature', UserSmartWalletV6Two, 'cancel', @@ -7776,17 +7777,17 @@ module.exports = {test: async function (testingContext) { ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a generic action ID', UserSmartWalletV6, 'getNextGenericActionID', 'call', [ SAI.options.address, - SAI.methods.transfer(address, constants.FULL_APPROVAL).encodeABI(), + SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), 0 ], true, @@ -7797,29 +7798,29 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can call executeAction', UserSmartWalletV6, 'executeAction', 'send', [ SAI.options.address, - SAI.methods.transfer(address, constants.FULL_APPROVAL).encodeABI(), + SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), 0, executeActionUserSignature, executeActionSignature ] ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a Dai withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -7838,15 +7839,15 @@ module.exports = {test: async function (testingContext) { daiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) daiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot withdraw to the null address', UserSmartWallet, 'withdrawDai', @@ -7863,10 +7864,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt.events) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a Dai withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -7874,7 +7875,7 @@ module.exports = {test: async function (testingContext) { [ 10, // DaiWithdrawal '100000000000000000000000000000000000000', // too much - address, + tester.address, 0 ], true, @@ -7885,22 +7886,22 @@ module.exports = {test: async function (testingContext) { daiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) daiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay cannot withdraw too much dai', UserSmartWallet, 'withdrawDai', 'send', [ '100000000000000000000000000000000000000', // too much - address, + tester.address, 0, daiUserWithdrawalSignature, daiWithdrawalSignature @@ -7910,10 +7911,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt.events) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -7921,7 +7922,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, '100000000000000000000000000000000000000', // too much - address, + tester.address, 0 ], true, @@ -7932,22 +7933,22 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet relay can call with two signatures to withdraw USDC', UserSmartWallet, 'withdrawUSDC', 'send', [ '100000000000000000000000000000000000000', // too much - address, + tester.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -7957,10 +7958,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get next generic batch action ID', UserSmartWalletV6, 'getNextGenericAtomicBatchActionID', @@ -7969,7 +7970,7 @@ module.exports = {test: async function (testingContext) { [{ to: DAI.options.address, data: DAI.methods.transfer( - address, '100000000000000000000000000000' + tester.address, '100000000000000000000000000000' ).encodeABI() }], 0 @@ -7982,15 +7983,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet bad executeActionWithAtomicBatchCalls emits CallFailure', UserSmartWalletV6, 'executeActionWithAtomicBatchCalls', @@ -7999,7 +8000,7 @@ module.exports = {test: async function (testingContext) { [{ to: DAI.options.address, data: DAI.methods.transfer( - address, '100000000000000000000000000000' + tester.address, '100000000000000000000000000000' ).encodeABI() }], 0, @@ -8012,7 +8013,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a generic action ID', UserSmartWalletV6, 'getNextGenericActionID', @@ -8032,15 +8033,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can call executeAction to enter dai market', UserSmartWalletV6, 'executeAction', @@ -8056,7 +8057,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'Dai Whale can deposit dai into the smart wallet', DAI, 'transfer', @@ -8082,13 +8083,13 @@ module.exports = {test: async function (testingContext) { constants.DAI_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can trigger repayAndDeposit to deposit all new funds', UserSmartWalletV6, 'repayAndDeposit' ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get a generic action ID', UserSmartWalletV6, 'getNextGenericActionID', @@ -8106,15 +8107,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can call executeAction to perform a borrow', UserSmartWalletV6, 'executeAction', @@ -8130,10 +8131,10 @@ module.exports = {test: async function (testingContext) { receipt => { //console.log(receipt.events) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V6 UserSmartWallet can get an escape hatch action ID', UserSmartWalletV6, 'getNextCustomActionID', @@ -8152,17 +8153,17 @@ module.exports = {test: async function (testingContext) { let escapeHatchSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) let escapeHatchUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) // YYYYY - await runTest( + await tester.runTest( 'UserSmartWalletV6 can get the nonce prior to upgrade', UserSmartWalletV6, 'getNonce', @@ -8174,7 +8175,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWalletV6 can check the user signing key prior to upgrade', UserSmartWalletV6, 'getUserSigningKey', @@ -8182,11 +8183,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, addressTwo) + assert.strictEqual(value, tester.addressTwo) } ) - await runTest( + await tester.runTest( 'Dharma Upgrade Beacon Controller can upgrade to V7 implementation', DharmaUpgradeBeaconController, 'upgrade', @@ -8226,7 +8227,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'DharmaUpgradeBeacon has the implementation set', DharmaUpgradeBeaconController, 'getImplementation', @@ -8238,7 +8239,7 @@ module.exports = {test: async function (testingContext) { } ) - const UpgradeBeaconImplementationCheckV7 = await runTest( + const UpgradeBeaconImplementationCheckV7 = await tester.runTest( `UpgradeBeaconImplementationCheck deployment`, UpgradeBeaconImplementationCheckDeployer, '', @@ -8249,7 +8250,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V7 user smart wallet can be called and still has the same dharma key set', UserSmartWalletV7, 'getUserSigningKey', @@ -8257,11 +8258,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, addressTwo) + assert.strictEqual(value, tester.addressTwo) } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get the new version (7)', UserSmartWalletV7, 'getVersion', @@ -8273,7 +8274,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet nonce is still set to value from before upgrade', UserSmartWalletV7, 'getNonce', @@ -8285,7 +8286,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get balances', UserSmartWalletV7, 'getBalances', @@ -8297,7 +8298,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet secondary can call to cancel', UserSmartWalletV7, 'cancel', @@ -8308,7 +8309,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet nonce is now set to original + 1', UserSmartWalletV7, 'getNonce', @@ -8320,7 +8321,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get next custom action ID to set a user signing key', UserSmartWalletV7, 'getNextCustomActionID', @@ -8328,7 +8329,7 @@ module.exports = {test: async function (testingContext) { [ 1, // SetUserSigningKey, constants.FULL_APPROVAL, // This value shouldn't matter - addressTwo, + tester.addressTwo, 0 ], true, @@ -8339,26 +8340,26 @@ module.exports = {test: async function (testingContext) { setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can set a new user signing key with signatures', UserSmartWalletV7, 'setUserSigningKey', 'send', [ - addressTwo, + tester.addressTwo, 0, '0x', setUserSigningKeyDharmaSignature ], true, receipt => {}, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet has the new user signing key set', UserSmartWalletV7, 'getUserSigningKey', @@ -8366,11 +8367,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, addressTwo) + assert.strictEqual(value, tester.addressTwo) } ) - await runTest( + await tester.runTest( 'cSai can be sent to V7 UserSmartWallet', CSAI, 'transfer', @@ -8378,7 +8379,7 @@ module.exports = {test: async function (testingContext) { [UserSmartWalletV7.options.address, web3.utils.toWei('0.5', 'mwei')] ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay can trigger cSai to dDai migration before dDai approval', UserSmartWalletV7, 'migrateCSaiToDDai', @@ -8388,10 +8389,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get next custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -8399,7 +8400,7 @@ module.exports = {test: async function (testingContext) { [ 0, // DAIWithdrawal constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -8408,7 +8409,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get custom action ID and it matches next action ID', UserSmartWalletV7, 'getCustomActionID', @@ -8416,7 +8417,7 @@ module.exports = {test: async function (testingContext) { [ 0, // DAIWithdrawal constants.FULL_APPROVAL, - address, + tester.address, parseInt(originalNonce) + 2, 0 ], @@ -8426,13 +8427,13 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get next generic action ID', UserSmartWalletV7, 'getNextGenericActionID', 'call', [ - address, + tester.address, '0x', 0 ], @@ -8442,13 +8443,13 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get generic action ID and it matches next action ID', UserSmartWalletV7, 'getGenericActionID', 'call', [ - address, + tester.address, '0x', parseInt(originalNonce) + 2, 0 @@ -8459,28 +8460,28 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet calls to atomic methods revert', UserSmartWalletV7, '_withdrawDaiAtomic', 'send', [ '1', - address + tester.address ], false ) // Give the Dai Whale some ETH so it can make transactions await web3.eth.sendTransaction({ - from: address, + from: tester.address, to: constants.DAI_WHALE_ADDRESS, value: web3.utils.toWei('1', 'ether'), gas: (testingContext !== 'coverage') ? '0xffff' : gasLimit - 1, gasPrice: 1 }) - await runTest( + await tester.runTest( 'Dai Whale can deposit Dai into the V7 smart wallet', DAI, 'transfer', @@ -8506,7 +8507,7 @@ module.exports = {test: async function (testingContext) { constants.DAI_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'USDC Whale can deposit usdc into the V7 smart wallet', USDC, 'transfer', @@ -8532,7 +8533,7 @@ module.exports = {test: async function (testingContext) { constants.USDC_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a generic action ID', UserSmartWalletV7, 'getNextGenericActionID', @@ -8550,15 +8551,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can call executeAction', UserSmartWalletV7, 'executeAction', @@ -8572,7 +8573,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V7 user smart wallet can trigger repayAndDeposit to deposit all new funds', UserSmartWalletV7, 'repayAndDeposit', @@ -8584,7 +8585,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'Dai Whale can deposit dai into the V7 smart wallet', DAI, 'transfer', @@ -8610,7 +8611,7 @@ module.exports = {test: async function (testingContext) { constants.DAI_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a generic action ID', UserSmartWalletV7, 'getNextGenericActionID', @@ -8628,15 +8629,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet cannot call executeAction and target Escape Hatch Registry', UserSmartWalletV7, 'executeAction', @@ -8651,7 +8652,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a generic action ID', UserSmartWalletV7, 'getNextGenericActionID', @@ -8669,15 +8670,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can call executeAction', UserSmartWalletV7, 'executeAction', @@ -8691,7 +8692,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V7 user smart wallet repayAndDeposit can still deposit without approval', UserSmartWalletV7, 'repayAndDeposit', @@ -8703,7 +8704,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a generic action ID', UserSmartWalletV7, 'getNextGenericActionID', @@ -8721,15 +8722,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can call executeAction', UserSmartWalletV7, 'executeAction', @@ -8743,7 +8744,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V7 user smart wallet repayAndDeposit can deposit with approval added back', UserSmartWalletV7, 'repayAndDeposit', @@ -8755,7 +8756,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 user smart wallet can trigger repayAndDeposit even with no funds', UserSmartWalletV7, 'repayAndDeposit', @@ -8767,7 +8768,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get custom action ID and it matches next action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -8786,15 +8787,15 @@ module.exports = {test: async function (testingContext) { setUserSigningKeyUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet cannot set the null address as a new user signing key', UserSmartWalletV7, 'setUserSigningKey', @@ -8807,10 +8808,10 @@ module.exports = {test: async function (testingContext) { ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get next custom action ID to set a user signing key', UserSmartWalletV7, 'getNextCustomActionID', @@ -8818,7 +8819,7 @@ module.exports = {test: async function (testingContext) { [ 1, // SetUserSigningKey, constants.FULL_APPROVAL, // This value shouldn't matter - addressTwo, + tester.addressTwo, 0 ], true, @@ -8827,7 +8828,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet can get the nonce', UserSmartWalletV7, 'getNonce', @@ -8839,7 +8840,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get custom action ID and it matches next action ID', UserSmartWalletV7, 'getCustomActionID', @@ -8847,7 +8848,7 @@ module.exports = {test: async function (testingContext) { [ 1, // SetUserSigningKey, 0, // Note that this value differs from above - addressTwo, + tester.addressTwo, currentNonce, 0 ], @@ -8859,31 +8860,31 @@ module.exports = {test: async function (testingContext) { setUserSigningKeyUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can set a new user signing key with signatures', UserSmartWalletV7, 'setUserSigningKey', 'send', [ - addressTwo, + tester.addressTwo, 0, setUserSigningKeyUserSignature, setUserSigningKeyDharmaSignature ], true, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get next custom action ID to cancel', UserSmartWalletV7, 'getNextCustomActionID', @@ -8891,7 +8892,7 @@ module.exports = {test: async function (testingContext) { [ 0, // Cancel constants.FULL_APPROVAL, // This value shouldn't matter - originalAddress, // This value shouldn't matter either + tester.originalAddress, // This value shouldn't matter either 0 ], true, @@ -8900,7 +8901,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet can get the nonce', UserSmartWalletV7, 'getNonce', @@ -8912,7 +8913,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get custom action ID and it matches next action ID', UserSmartWalletV7, 'getCustomActionID', @@ -8920,7 +8921,7 @@ module.exports = {test: async function (testingContext) { [ 0, // Cancel 0, // Note that this value differs from above - addressTwo, // This one too + tester.addressTwo, // This one too currentNonce, 0 ], @@ -8932,10 +8933,10 @@ module.exports = {test: async function (testingContext) { cancelUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet secondary can cancel using a signature', UserSmartWalletV7, 'cancel', @@ -8946,10 +8947,10 @@ module.exports = {test: async function (testingContext) { ], true, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'UserSmartWallet nonce is incremented after cancelling', UserSmartWalletV7, 'getNonce', @@ -8961,14 +8962,14 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet secondary cannot call to withdraw dai without primary', UserSmartWalletV7, 'withdrawDai', 'send', [ '1000000000000000000', - address, + tester.address, 0, '0x', '0x' @@ -8976,14 +8977,14 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet secondary cannot call to withdraw usdc without primary', UserSmartWalletV7, 'withdrawUSDC', 'send', [ 1, - address, + tester.address, 0, '0x', '0x' @@ -8991,13 +8992,13 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet secondary can no longer call to set userSigningKey without primary', UserSmartWalletV7, 'setUserSigningKey', 'send', [ - address, + tester.address, 0, '0x', '0x' @@ -9005,7 +9006,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -9013,7 +9014,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, '1', // dust - address, + tester.address, 0 ], true, @@ -9024,22 +9025,22 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot withdraw "dust" USDC', UserSmartWalletV7, 'withdrawUSDC', 'send', [ '1', - address, + tester.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -9049,10 +9050,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -9071,15 +9072,15 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot withdraw USDC to null address', UserSmartWalletV7, 'withdrawUSDC', @@ -9096,10 +9097,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -9107,7 +9108,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, '100000', - address, + tester.address, 0 ], true, @@ -9118,22 +9119,22 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay can call with two signatures to withdraw USDC', UserSmartWalletV7, 'withdrawUSDC', 'send', [ '100000', - address, + tester.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -9143,10 +9144,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -9154,7 +9155,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -9165,22 +9166,22 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot call with bad signature to withdraw USDC', UserSmartWalletV7, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, usdcUserWithdrawalSignature, '0xffffffff' + usdcWithdrawalSignature.slice(10) @@ -9190,17 +9191,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet cannot call with bad user signature to withdraw USDC', UserSmartWalletV7, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, '0xffffffff' + usdcUserWithdrawalSignature.slice(10), usdcWithdrawalSignature @@ -9210,17 +9211,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay can call with two signatures to withdraw max USDC', UserSmartWalletV7, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -9230,7 +9231,7 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) /* TODO: get this working manually @@ -9252,7 +9253,7 @@ module.exports = {test: async function (testingContext) { ) */ - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -9260,7 +9261,7 @@ module.exports = {test: async function (testingContext) { [ 10, // DaiWithdrawal '1', - address, + tester.address, 0 ], true, @@ -9271,32 +9272,32 @@ module.exports = {test: async function (testingContext) { daiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) daiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot withdraw "dust" dai', UserSmartWalletV7, 'withdrawDai', 'send', [ '1', - address, + tester.address, 0, daiUserWithdrawalSignature, daiWithdrawalSignature ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -9315,15 +9316,15 @@ module.exports = {test: async function (testingContext) { daiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) daiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot withdraw dai to null address', UserSmartWalletV7, 'withdrawDai', @@ -9337,10 +9338,10 @@ module.exports = {test: async function (testingContext) { ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -9348,7 +9349,7 @@ module.exports = {test: async function (testingContext) { [ 10, // DaiWithdrawal '1000000000000000', - address, + tester.address, 0 ], true, @@ -9359,22 +9360,22 @@ module.exports = {test: async function (testingContext) { daiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) daiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay can call with signature to withdraw dai', UserSmartWalletV7, 'withdrawDai', 'send', [ '1000000000000000', - address, + tester.address, 0, daiUserWithdrawalSignature, daiWithdrawalSignature @@ -9384,10 +9385,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt.events) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet cannot get a non-custom "custom" next action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -9395,13 +9396,13 @@ module.exports = {test: async function (testingContext) { [ 2, // Generic, constants.FULL_APPROVAL, - address, + tester.address, 0 ], false ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet cannot get a non-custom "custom" action ID', UserSmartWalletV7, 'getCustomActionID', @@ -9409,14 +9410,14 @@ module.exports = {test: async function (testingContext) { [ 2, // Generic, constants.FULL_APPROVAL, - address, + tester.address, 0, 0 ], false ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -9424,7 +9425,7 @@ module.exports = {test: async function (testingContext) { [ 10, // DaiWithdrawal constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -9435,22 +9436,22 @@ module.exports = {test: async function (testingContext) { daiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) daiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot call with bad signature to withdraw dai', UserSmartWalletV7, 'withdrawDai', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, daiUserWithdrawalSignature, '0xffffffff' + daiWithdrawalSignature.slice(10) @@ -9460,17 +9461,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot call with bad user signature to withdraw dai', UserSmartWalletV7, 'withdrawDai', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, '0xffffffff' + daiUserWithdrawalSignature.slice(10), daiWithdrawalSignature @@ -9480,17 +9481,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay can call with signature to withdraw sai', UserSmartWalletV7, 'withdrawDai', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, daiUserWithdrawalSignature, daiWithdrawalSignature @@ -9499,10 +9500,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a Ether withdrawal custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -9510,7 +9511,7 @@ module.exports = {test: async function (testingContext) { [ 6, // ETHWithdrawal, '0', // no amount - address, + tester.address, 0 ], true, @@ -9521,22 +9522,22 @@ module.exports = {test: async function (testingContext) { ethWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) ethUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot to withdraw ether with no amount', UserSmartWalletV7, 'withdrawEther', 'send', [ '0', - address, + tester.address, 0, ethUserWithdrawalSignature, ethWithdrawalSignature @@ -9545,10 +9546,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a Ether withdrawal custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -9567,15 +9568,15 @@ module.exports = {test: async function (testingContext) { ethWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) ethUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot to withdraw ether with no recipient', UserSmartWalletV7, 'withdrawEther', @@ -9591,10 +9592,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a Ether withdrawal custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -9602,7 +9603,7 @@ module.exports = {test: async function (testingContext) { [ 6, // ETHWithdrawal, '1', - address, + tester.address, 0 ], true, @@ -9613,22 +9614,22 @@ module.exports = {test: async function (testingContext) { ethWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) ethUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot call with bad signature to withdraw eth', UserSmartWalletV7, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, ethUserWithdrawalSignature, '0xffffffff' + ethWithdrawalSignature.slice(10) @@ -9638,17 +9639,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot call with bad user signature to withdraw eth', UserSmartWalletV7, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, '0xffffffff' + ethUserWithdrawalSignature.slice(10), ethWithdrawalSignature @@ -9658,17 +9659,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay can call with signature to withdraw ether', UserSmartWalletV7, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, ethUserWithdrawalSignature, ethWithdrawalSignature @@ -9677,10 +9678,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a Ether withdrawal custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -9688,7 +9689,7 @@ module.exports = {test: async function (testingContext) { [ 6, // ETHWithdrawal, '1', - address, + tester.address, 0 ], true, @@ -9699,22 +9700,22 @@ module.exports = {test: async function (testingContext) { ethWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) ethUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot call with bad signature to withdraw eth', UserSmartWalletV7, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, ethUserWithdrawalSignature, '0xffffffff' + ethWithdrawalSignature.slice(10) @@ -9724,17 +9725,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot call with bad user signature to withdraw eth', UserSmartWalletV7, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, '0xffffffff' + ethUserWithdrawalSignature.slice(10), ethWithdrawalSignature @@ -9744,17 +9745,17 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay can call with signature to withdraw ether', UserSmartWalletV7, 'withdrawEther', 'send', [ '1', - address, + tester.address, 0, ethUserWithdrawalSignature, ethWithdrawalSignature @@ -9763,10 +9764,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet cancel reverts with bad signature', UserSmartWalletV7, 'cancel', @@ -9777,10 +9778,10 @@ module.exports = {test: async function (testingContext) { ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet calls revert if insufficient action gas is supplied', UserSmartWalletV7, 'cancel', @@ -9792,7 +9793,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet calls succeed if sufficient non-zero action gas supplied', UserSmartWalletV7, 'cancel', @@ -9803,7 +9804,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a cancel custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -9811,7 +9812,7 @@ module.exports = {test: async function (testingContext) { [ 0, // Cancel, '0', - address, + tester.address, 0 ], true, @@ -9820,9 +9821,9 @@ module.exports = {test: async function (testingContext) { } ) - cancelSignature = signHashedPrefixedHexString(customActionId, addressTwo) + cancelSignature = signHashedPrefixedHexString(customActionId, tester.addressTwo) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can cancel using a signature', UserSmartWalletV7, 'cancel', @@ -9833,38 +9834,38 @@ module.exports = {test: async function (testingContext) { ], true, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet calls to atomic methods revert', UserSmartWalletV7, '_withdrawDaiAtomic', 'send', [ '1', - address + tester.address ], false ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet calls to recover from random address revert', UserSmartWalletV7, 'recover', 'send', [ - address + tester.address ], false ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can deploy a V7 smart wallet using a Dharma Key', DharmaSmartWalletFactoryV1, 'newSmartWallet', 'send', - [addressTwo], + [tester.addressTwo], true, receipt => { //console.log(receipt.status, receipt.gasUsed) @@ -9883,7 +9884,7 @@ module.exports = {test: async function (testingContext) { }) assert.strictEqual(events[0].eventName, 'NewUserSigningKey') - assert.strictEqual(events[0].returnValues.userSigningKey, addressTwo) + assert.strictEqual(events[0].returnValues.userSigningKey, tester.addressTwo) //console.log(events) // TODO: test more events @@ -9891,7 +9892,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a generic action ID', UserSmartWalletV7, 'getNextGenericActionID', @@ -9909,21 +9910,21 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet cannot call executeAction and target a non-contract', UserSmartWalletV7, 'executeAction', 'send', [ - address, + tester.address, USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), 0, executeActionUserSignature, @@ -9932,7 +9933,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet cannot call executeAction and target itself', UserSmartWalletV7, 'executeAction', @@ -9947,7 +9948,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can call executeAction', UserSmartWalletV7, 'executeAction', @@ -9961,7 +9962,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get the next generic batch action ID', UserSmartWalletV7, 'getNextGenericAtomicBatchActionID', @@ -9976,7 +9977,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'UserSmartWallet can get the nonce', UserSmartWalletV7, 'getNonce', @@ -9988,7 +9989,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet generic batch action ID with nonce matches next ID', UserSmartWalletV7, 'getGenericAtomicBatchActionID', @@ -10006,15 +10007,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can call executeActionWithAtomicBatchCalls', UserSmartWalletV7, 'executeActionWithAtomicBatchCalls', @@ -10027,7 +10028,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'USDC Whale can deposit usdc into the deployed smart wallet', USDC, 'transfer', @@ -10053,7 +10054,7 @@ module.exports = {test: async function (testingContext) { constants.USDC_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'new user smart wallet can trigger repayAndDeposit to deposit all new funds', UserSmartWalletV7, 'repayAndDeposit', @@ -10065,7 +10066,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'Check blacklister address', FIAT_TOKEN, 'blacklister', @@ -10077,7 +10078,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'Check pauser address', FIAT_TOKEN, 'pauser', @@ -10089,7 +10090,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'blacklist mock address', FIAT_TOKEN, 'blacklist', @@ -10100,7 +10101,7 @@ module.exports = {test: async function (testingContext) { blacklister ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', DharmaSmartWalletFactoryV1, 'getNextSmartWallet', @@ -10117,7 +10118,7 @@ module.exports = {test: async function (testingContext) { targetBlacklistAddress ) - await runTest( + await tester.runTest( 'USDC Whale can deposit usdc into the yet-to-be-blacklisted smart wallet', USDC, 'transfer', @@ -10143,7 +10144,7 @@ module.exports = {test: async function (testingContext) { constants.USDC_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'blacklist counterfactual deployment address', FIAT_TOKEN, 'blacklist', @@ -10154,7 +10155,7 @@ module.exports = {test: async function (testingContext) { blacklister ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can deploy to a blacklisted address', DharmaSmartWalletFactoryV1, 'newSmartWallet', @@ -10167,7 +10168,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'blacklisted smart wallet will not approve USDC during repayAndDeposit', BlacklistedUserSmartWalletV7, 'repayAndDeposit', @@ -10180,7 +10181,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'un-blacklist counterfactual deployment address', FIAT_TOKEN, 'unBlacklist', @@ -10191,7 +10192,7 @@ module.exports = {test: async function (testingContext) { blacklister ) - await runTest( + await tester.runTest( 'pause USDC', FIAT_TOKEN, 'pause', @@ -10202,7 +10203,7 @@ module.exports = {test: async function (testingContext) { pauser ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -10210,7 +10211,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, constants.FULL_APPROVAL, - address, + tester.address, 0 ], true, @@ -10221,22 +10222,22 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet attempt to withdraw max USDC when paused causes ExternalError', UserSmartWalletV7, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - address, + tester.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -10246,10 +10247,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'smart wallet will not approve USDC when paused during repayAndDeposit', BlacklistedUserSmartWalletV7, 'repayAndDeposit', @@ -10262,7 +10263,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'unpause USDC', FIAT_TOKEN, 'unpause', @@ -10273,7 +10274,7 @@ module.exports = {test: async function (testingContext) { pauser ) - await runTest( + await tester.runTest( 'unblacklisted, unpaused smart wallet approves USDC during repayAndDeposit', BlacklistedUserSmartWalletV7, 'repayAndDeposit', @@ -10286,7 +10287,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -10305,15 +10306,15 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay call to withdraw USDC to blacklisted address', UserSmartWallet, 'withdrawUSDC', @@ -10331,10 +10332,10 @@ module.exports = {test: async function (testingContext) { //console.log(receipt.events[0]) //console.log(receipt.events.ExternalError) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -10353,15 +10354,15 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay call to withdraw USDC to itself', UserSmartWallet, 'withdrawUSDC', @@ -10377,10 +10378,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -10399,15 +10400,15 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay call to withdraw USDC to blacklisted address', UserSmartWallet, 'withdrawUSDC', @@ -10425,10 +10426,10 @@ module.exports = {test: async function (testingContext) { //console.log(receipt.events[0]) //console.log(receipt.events.ExternalError) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a Ether withdrawal custom action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -10447,15 +10448,15 @@ module.exports = {test: async function (testingContext) { ethWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) ethUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot withdraw eth to a non-payable account', UserSmartWalletV7, 'withdrawEther', @@ -10472,10 +10473,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', DharmaSmartWalletFactoryV1, 'getNextSmartWallet', @@ -10488,7 +10489,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can deploy a V7 smart wallet using a contract key', DharmaSmartWalletFactoryV1, 'newSmartWallet', @@ -10501,7 +10502,7 @@ module.exports = {test: async function (testingContext) { targetWalletAddressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet cancel reverts with bad contract signature', UserSmartWalletV7Two, 'cancel', @@ -10512,17 +10513,17 @@ module.exports = {test: async function (testingContext) { ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a generic action ID', UserSmartWalletV7, 'getNextGenericActionID', 'call', [ SAI.options.address, - SAI.methods.transfer(address, constants.FULL_APPROVAL).encodeABI(), + SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), 0 ], true, @@ -10533,29 +10534,29 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can call executeAction', UserSmartWalletV7, 'executeAction', 'send', [ SAI.options.address, - SAI.methods.transfer(address, constants.FULL_APPROVAL).encodeABI(), + SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), 0, executeActionUserSignature, executeActionSignature ] ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -10574,15 +10575,15 @@ module.exports = {test: async function (testingContext) { daiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) daiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot withdraw to the null address', UserSmartWallet, 'withdrawDai', @@ -10599,10 +10600,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt.events) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -10610,7 +10611,7 @@ module.exports = {test: async function (testingContext) { [ 10, // DaiWithdrawal '100000000000000000000000000000000000000', // too much - address, + tester.address, 0 ], true, @@ -10621,22 +10622,22 @@ module.exports = {test: async function (testingContext) { daiWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) daiUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot withdraw too much dai', UserSmartWallet, 'withdrawDai', 'send', [ '100000000000000000000000000000000000000', // too much - address, + tester.address, 0, daiUserWithdrawalSignature, daiWithdrawalSignature @@ -10646,10 +10647,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt.events) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', UserSmartWallet, 'getNextCustomActionID', @@ -10657,7 +10658,7 @@ module.exports = {test: async function (testingContext) { [ 5, // USDCWithdrawal, '100000000000000000000000000000000000000', // too much - address, + tester.address, 0 ], true, @@ -10668,22 +10669,22 @@ module.exports = {test: async function (testingContext) { usdcWithdrawalSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) usdcUserWithdrawalSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay can call with two signatures to withdraw USDC', UserSmartWallet, 'withdrawUSDC', 'send', [ '100000000000000000000000000000000000000', // too much - address, + tester.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -10693,10 +10694,10 @@ module.exports = {test: async function (testingContext) { // TODO: verify logs //console.log(receipt) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get next generic batch action ID', UserSmartWalletV7, 'getNextGenericAtomicBatchActionID', @@ -10705,7 +10706,7 @@ module.exports = {test: async function (testingContext) { [{ to: DAI.options.address, data: DAI.methods.transfer( - address, '100000000000000000000000000000' + tester.address, '100000000000000000000000000000' ).encodeABI() }], 0 @@ -10718,15 +10719,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet bad executeActionWithAtomicBatchCalls emits CallFailure', UserSmartWalletV7, 'executeActionWithAtomicBatchCalls', @@ -10735,7 +10736,7 @@ module.exports = {test: async function (testingContext) { [{ to: DAI.options.address, data: DAI.methods.transfer( - address, '100000000000000000000000000000' + tester.address, '100000000000000000000000000000' ).encodeABI() }], 0, @@ -10748,7 +10749,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a generic action ID', UserSmartWalletV7, 'getNextGenericActionID', @@ -10768,15 +10769,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can call executeAction to enter dai market', UserSmartWalletV7, 'executeAction', @@ -10792,7 +10793,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'Dai Whale can deposit dai into the smart wallet', DAI, 'transfer', @@ -10818,13 +10819,13 @@ module.exports = {test: async function (testingContext) { constants.DAI_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can trigger repayAndDeposit to deposit all new funds', UserSmartWalletV7, 'repayAndDeposit' ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get a generic action ID', UserSmartWalletV7, 'getNextGenericActionID', @@ -10842,15 +10843,15 @@ module.exports = {test: async function (testingContext) { executeActionSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) executeActionUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can call executeAction to perform a borrow', UserSmartWalletV7, 'executeAction', @@ -10866,13 +10867,13 @@ module.exports = {test: async function (testingContext) { receipt => { //console.log(receipt.events) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get an escape hatch action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -10891,15 +10892,15 @@ module.exports = {test: async function (testingContext) { escapeHatchSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) escapeHatchUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot set an escape hatch with no account', UserSmartWalletV7, 'setEscapeHatch', @@ -10914,10 +10915,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get an escape hatch action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -10925,7 +10926,7 @@ module.exports = {test: async function (testingContext) { [ 7, // SetEscapeHatch, 0, - address, + tester.address, 0 ], true, @@ -10936,15 +10937,15 @@ module.exports = {test: async function (testingContext) { escapeHatchSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) escapeHatchUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet cannot call escape before escape hatch is set', UserSmartWalletV7, 'escape', @@ -10956,13 +10957,13 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay can set an escape hatch', UserSmartWalletV7, 'setEscapeHatch', 'send', [ - address, + tester.address, 0, escapeHatchUserSignature, escapeHatchSignature @@ -10971,10 +10972,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet non-escape hatch account cannot call escape', UserSmartWalletV7, 'escape', @@ -10984,10 +10985,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet escape hatch account can call escape', UserSmartWalletV7, 'escape', @@ -10997,10 +10998,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - address + tester.address ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet escape hatch account can call escape again', UserSmartWalletV7, 'escape', @@ -11010,10 +11011,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - address + tester.address ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get an escape hatch action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -11032,15 +11033,15 @@ module.exports = {test: async function (testingContext) { escapeHatchSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) escapeHatchUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay can remove an escape hatch', UserSmartWalletV7, 'removeEscapeHatch', @@ -11054,10 +11055,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet cannot call escape once escape hatch is removed', UserSmartWalletV7, 'escape', @@ -11069,7 +11070,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get an escape hatch action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -11088,15 +11089,15 @@ module.exports = {test: async function (testingContext) { escapeHatchSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) escapeHatchUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay can disable the escape hatch', UserSmartWalletV7, 'permanentlyDisableEscapeHatch', @@ -11110,10 +11111,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet can get an escape hatch action ID', UserSmartWalletV7, 'getNextCustomActionID', @@ -11121,7 +11122,7 @@ module.exports = {test: async function (testingContext) { [ 7, // SetEscapeHatch, 0, - address, + tester.address, 0 ], true, @@ -11132,21 +11133,21 @@ module.exports = {test: async function (testingContext) { escapeHatchSignature = signHashedPrefixedHexString( customActionId, - address + tester.address ) escapeHatchUserSignature = signHashedPrefixedHexString( customActionId, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay cannot set an escape hatch once disabled', UserSmartWalletV7, 'setEscapeHatch', 'send', [ - address, + tester.address, 0, escapeHatchUserSignature, escapeHatchSignature @@ -11155,10 +11156,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay can trigger sai to dai migration as a no-op', UserSmartWalletV7, 'migrateSaiToDai', @@ -11168,10 +11169,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay can trigger cSai to dDai migration as a no-op', UserSmartWalletV7, 'migrateCSaiToDDai', @@ -11181,10 +11182,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'cSai can be sent to V7 UserSmartWallet', CSAI, 'transfer', @@ -11192,7 +11193,7 @@ module.exports = {test: async function (testingContext) { [UserSmartWalletV7.options.address, web3.utils.toWei('0.5', 'mwei')] ) - await runTest( + await tester.runTest( 'Sai Whale can deposit sai into the V7 user smart wallet', SAI, 'transfer', @@ -11218,7 +11219,7 @@ module.exports = {test: async function (testingContext) { constants.SAI_WHALE_ADDRESS ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay can trigger sai to dai migration', UserSmartWalletV7, 'migrateSaiToDai', @@ -11228,10 +11229,10 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'V7 UserSmartWallet relay can trigger cSai to dDai migration', UserSmartWalletV7, 'migrateCSaiToDDai', @@ -11241,18 +11242,18 @@ module.exports = {test: async function (testingContext) { receipt => { // TODO: verify logs }, - originalAddress + tester.originalAddress ) // Initiate account recovery - await runTest( + await tester.runTest( 'smart wallet account recovery can be initiated', DharmaAccountRecoveryManagerV2, 'initiateAccountRecovery', 'send', [ UserSmartWalletV7.options.address, - originalAddress, + tester.originalAddress, 0 // extraTime in seconds ], true, @@ -11262,14 +11263,14 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'smart wallet account recovery cannot be performed right away', DharmaAccountRecoveryManagerV2, 'recover', 'send', [ UserSmartWalletV7.options.address, - originalAddress + tester.originalAddress ], false ) @@ -11278,14 +11279,14 @@ module.exports = {test: async function (testingContext) { await advanceTime((60 * 60 * 24 * 3) + 5) // recover account - await runTest( + await tester.runTest( 'smart wallet account recovery can be performed after three days', DharmaAccountRecoveryManagerV2, 'recover', 'send', [ UserSmartWalletV7.options.address, - originalAddress + tester.originalAddress ], true, receipt => { @@ -11297,70 +11298,70 @@ module.exports = {test: async function (testingContext) { // ZZZZZ // COVERAGE TESTING - deployments - const DharmaUpgradeBeaconControllerManagerCoverage = await runTest( + const DharmaUpgradeBeaconControllerManagerCoverage = await tester.runTest( `DharmaUpgradeBeaconControllerManager contract deployment`, DharmaUpgradeBeaconControllerManagerDeployer, '', 'deploy' ) - const DharmaUpgradeBeaconControllerCoverage = await runTest( + const DharmaUpgradeBeaconControllerCoverage = await tester.runTest( `DharmaUpgradeBeaconController contract deployment`, DharmaUpgradeBeaconControllerDeployer, '', 'deploy' ) - const DharmaAccountRecoveryManagerV2Coverage = await runTest( + const DharmaAccountRecoveryManagerV2Coverage = await tester.runTest( `DharmaAccountRecoveryManagerV2 contract deployment`, DharmaAccountRecoveryManagerV2Deployer, '', 'deploy' ) - const DharmaKeyRegistryV2Coverage = await runTest( + const DharmaKeyRegistryV2Coverage = await tester.runTest( `DharmaKeyRegistryV2 contract deployment`, DharmaKeyRegistryV2Deployer, '', 'deploy' ) - const DharmaUpgradeBeaconCoverage = await runTest( + const DharmaUpgradeBeaconCoverage = await tester.runTest( `DharmaUpgradeBeacon (smart wallet) contract deployment`, DharmaUpgradeBeaconDeployer, '', 'deploy' ) - const DharmaKeyRingUpgradeBeaconCoverage = await runTest( + const DharmaKeyRingUpgradeBeaconCoverage = await tester.runTest( `DharmaKeyRingUpgradeBeacon contract deployment`, DharmaKeyRingUpgradeBeaconDeployer, '', 'deploy' ) - const DharmaUpgradeBeaconEnvoy = await runTest( + const DharmaUpgradeBeaconEnvoy = await tester.runTest( `DharmaUpgradeBeaconEnvoy contract deployment`, DharmaUpgradeBeaconEnvoyDeployer, '', 'deploy' ) - const AdharmaSmartWalletImplementation = await runTest( + const AdharmaSmartWalletImplementation = await tester.runTest( `AdharmaSmartWalletImplementation contract deployment`, AdharmaSmartWalletImplementationDeployer, '', 'deploy' ) - const AdharmaKeyRingImplementation = await runTest( + const AdharmaKeyRingImplementation = await tester.runTest( `AdharmaKeyRingImplementation contract deployment`, AdharmaKeyRingImplementationDeployer, '', 'deploy' ) - const DharmaSmartWalletFactoryV1Coverage = await runTest( + const DharmaSmartWalletFactoryV1Coverage = await tester.runTest( `DharmaSmartWalletFactoryV1 contract deployment`, DharmaSmartWalletFactoryV1Deployer, '', @@ -11368,7 +11369,7 @@ module.exports = {test: async function (testingContext) { [] ) - const DharmaKeyRingFactoryV1 = await runTest( + const DharmaKeyRingFactoryV1 = await tester.runTest( `DharmaKeyRingFactoryV1 contract deployment`, DharmaKeyRingFactoryV1Deployer, '', @@ -11376,7 +11377,7 @@ module.exports = {test: async function (testingContext) { [] ) - const DharmaKeyRingFactoryV2 = await runTest( + const DharmaKeyRingFactoryV2 = await tester.runTest( `DharmaKeyRingFactoryV2 contract deployment`, DharmaKeyRingFactoryV2Deployer, '', @@ -11384,7 +11385,7 @@ module.exports = {test: async function (testingContext) { [] ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV1 cannot create a V1 key ring with no key`, DharmaKeyRingFactoryV1, 'newKeyRing', @@ -11393,42 +11394,42 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV1 cannot create a V1 key ring and set a new null key`, DharmaKeyRingFactoryV1, 'newKeyRingAndAdditionalKey', 'send', - [address, constants.NULL_ADDRESS, '0x'], + [tester.address, constants.NULL_ADDRESS, '0x'], false ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV1 cannot create a V1 key ring and set a duplicate key`, DharmaKeyRingFactoryV1, 'newKeyRingAndAdditionalKey', 'send', - [address, address, '0x'], + [tester.address, tester.address, '0x'], false ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV1 can get the address of the next key ring`, DharmaKeyRingFactoryV1, 'getNextKeyRing', 'call', - [address], + [tester.address], true, value => { nextKeyRing = value; } ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV1 can create a V1 key ring`, DharmaKeyRingFactoryV1, 'newKeyRing', 'send', - [address] + [tester.address] ) const KeyRingInstance = new web3.eth.Contract( @@ -11436,19 +11437,19 @@ module.exports = {test: async function (testingContext) { nextKeyRing ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV1 gets new key ring after a deploy with same input`, DharmaKeyRingFactoryV1, 'getNextKeyRing', 'call', - [address], + [tester.address], true, value => { assert.ok(nextKeyRing !== value) } ) - await runTest( + await tester.runTest( `KeyRingInstance can get the version of the key ring`, KeyRingInstance, 'getVersion', @@ -11460,7 +11461,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `KeyRingInstance can get the nonce of the key ring`, KeyRingInstance, 'getNonce', @@ -11472,7 +11473,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `KeyRingInstance can get the key count of the key ring`, KeyRingInstance, 'getKeyCount', @@ -11485,7 +11486,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `KeyRingInstance can does not verify a bad signature`, KeyRingInstance, 'isValidSignature', @@ -11500,7 +11501,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `KeyRingInstance can get an adminActionID using getNextAdminActionID`, KeyRingInstance, 'getNextAdminActionID', @@ -11512,7 +11513,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `KeyRingInstance getAdminActionID matches getNextAdminActionID`, KeyRingInstance, 'getAdminActionID', @@ -11524,7 +11525,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `KeyRingInstance cannot add a non-dual key in V1`, KeyRingInstance, 'takeAdminAction', @@ -11533,21 +11534,21 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `KeyRingInstance cannot add key that already exists`, KeyRingInstance, 'takeAdminAction', 'send', - [6, address, '0x'], + [6, tester.address, '0x'], false ) const takeAdminActionSignature = signHashedPrefixedHexString( adminActionID, - address + tester.address ) - await runTest( + await tester.runTest( `KeyRingInstance can verify a valid signature`, KeyRingInstance, 'isValidSignature', @@ -11571,7 +11572,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `KeyRingInstance can add a new key with a valid signature`, KeyRingInstance, 'takeAdminAction', @@ -11580,7 +11581,7 @@ module.exports = {test: async function (testingContext) { true ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV2 cannot create a V1 key ring with no key`, DharmaKeyRingFactoryV2, 'newKeyRing', @@ -11589,42 +11590,42 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV2 cannot create a V1 key ring and set a new null key`, DharmaKeyRingFactoryV2, 'newKeyRingAndAdditionalKey', 'send', - [address, constants.NULL_ADDRESS, constants.NULL_ADDRESS, '0x'], + [tester.address, constants.NULL_ADDRESS, constants.NULL_ADDRESS, '0x'], false ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV2 cannot create a V1 key ring and set a duplicate key`, DharmaKeyRingFactoryV2, 'newKeyRingAndAdditionalKey', 'send', - [address, constants.NULL_ADDRESS, address, '0x'], + [tester.address, constants.NULL_ADDRESS, tester.address, '0x'], false ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV2 can get the address of the next key ring`, DharmaKeyRingFactoryV2, 'getNextKeyRing', 'call', - [address], + [tester.address], true, value => { nextKeyRing = value; } ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV2 can create a V1 key ring if the target address matches`, DharmaKeyRingFactoryV2, 'newKeyRing', 'send', - [address, nextKeyRing] + [tester.address, nextKeyRing] ) const KeyRingInstanceFromV2Factory = new web3.eth.Contract( @@ -11632,23 +11633,23 @@ module.exports = {test: async function (testingContext) { nextKeyRing ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV2 won't deploy a V1 key ring if the target address has one`, DharmaKeyRingFactoryV2, 'newKeyRing', 'send', - [address, KeyRingInstanceFromV2Factory.options.address] + [tester.address, KeyRingInstanceFromV2Factory.options.address] ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV2 can call getFirstKeyRingAdminActionID`, DharmaKeyRingFactoryV2, 'getFirstKeyRingAdminActionID', 'call', - [address, address] + [tester.address, tester.address] ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV2 reverts when no new key ring supplied`, DharmaKeyRingFactoryV2, 'getNextKeyRing', @@ -11657,73 +11658,73 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV2 gets new key ring after a deploy with same input`, DharmaKeyRingFactoryV2, 'getNextKeyRing', 'call', - [address], + [tester.address], true, value => { assert.ok(nextKeyRing !== value) } ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV2 can call newKeyRingAndDaiWithdrawal`, DharmaKeyRingFactoryV2, 'newKeyRingAndDaiWithdrawal', 'send', - [address, address, address, 0, address, 0, '0x', '0x'], + [tester.address, tester.address, tester.address, 0, tester.address, 0, '0x', '0x'], false ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV2 can call newKeyRingAndUSDCWithdrawal`, DharmaKeyRingFactoryV2, 'newKeyRingAndUSDCWithdrawal', 'send', - [address, address, address, 0, address, 0, '0x', '0x'], + [tester.address, tester.address, tester.address, 0, tester.address, 0, '0x', '0x'], false ) - await runTest( + await tester.runTest( `AdharmaSmartWalletImplementation cannot be initialized directly post-deployment`, AdharmaSmartWalletImplementation, 'initialize', 'send', - [address], + [tester.address], false ) - await runTest( + await tester.runTest( `AdharmaSmartWalletImplementation cannot be used to perform calls directly`, AdharmaSmartWalletImplementation, 'performCall', 'send', - [address, 1, '0x'], + [tester.address, 1, '0x'], false ) - await runTest( + await tester.runTest( `AdharmaKeyRingImplementation cannot be initialized directly post-deployment`, AdharmaKeyRingImplementation, 'initialize', 'send', - [1, 1, [address], [3]], + [1, 1, [tester.address], [3]], false ) - await runTest( + await tester.runTest( `AdharmaKeyRingImplementation cannot be used to take action directly`, AdharmaKeyRingImplementation, 'takeAction', 'send', - [address, 1, '0x', '0x'], + [tester.address, 1, '0x', '0x'], false ) - await runTest( + await tester.runTest( `UpgradeBeaconProxyV1 contract deployment fails with no init data`, UpgradeBeaconProxyV1Deployer, '', @@ -11732,7 +11733,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `KeyRingUpgradeBeaconProxyV1 contract deployment fails with no init data`, KeyRingUpgradeBeaconProxyV1Deployer, '', @@ -11741,7 +11742,7 @@ module.exports = {test: async function (testingContext) { false ) - const UpgradeBeaconProxyV1 = await runTest( + const UpgradeBeaconProxyV1 = await tester.runTest( `UpgradeBeaconProxyV1 contract deployment (direct)`, UpgradeBeaconProxyV1Deployer, '', @@ -11753,7 +11754,7 @@ module.exports = {test: async function (testingContext) { type: 'address', name: 'userSigningKey' }] - }, [address])] + }, [tester.address])] ) const UpgradeBeaconProxyV1Implementation = new web3.eth.Contract( @@ -11761,7 +11762,7 @@ module.exports = {test: async function (testingContext) { UpgradeBeaconProxyV1.options.address ) - await runTest( + await tester.runTest( `UpgradeBeaconProxyV1 can retrieve its user signing key`, UpgradeBeaconProxyV1Implementation, 'getUserSigningKey', @@ -11769,11 +11770,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - const KeyRingUpgradeBeaconProxyV1 = await runTest( + const KeyRingUpgradeBeaconProxyV1 = await tester.runTest( `KeyRingUpgradeBeaconProxyV1 contract deployment (direct)`, KeyRingUpgradeBeaconProxyV1Deployer, '', @@ -11794,7 +11795,7 @@ module.exports = {test: async function (testingContext) { type: 'uint8[]', name: 'keyTypes' }] - }, [1, 1, [address], [3]])] + }, [1, 1, [tester.address], [3]])] ) const KeyRingUpgradeBeaconProxyV1Implementation = new web3.eth.Contract( @@ -11802,12 +11803,12 @@ module.exports = {test: async function (testingContext) { KeyRingUpgradeBeaconProxyV1.options.address ) - await runTest( + await tester.runTest( `KeyRingUpgradeBeaconProxyV1 can retrieve its user signing key`, KeyRingUpgradeBeaconProxyV1Implementation, 'getKeyType', 'call', - [address], + [tester.address], true, values => { assert.ok(values.standard) @@ -11821,7 +11822,7 @@ module.exports = {test: async function (testingContext) { // (actually, they're not working yet, period... skip them for now) /* if (testingContext !== 'coverage') { - const DharmaSmartWalletFactoryV2 = await runTest( + const DharmaSmartWalletFactoryV2 = await tester.runTest( `DharmaSmartWalletFactoryV2 contract deployment`, DharmaSmartWalletFactoryV2Deployer, '', @@ -11829,7 +11830,7 @@ module.exports = {test: async function (testingContext) { [] ) - const DharmaKeyRingFactoryV3 = await runTest( + const DharmaKeyRingFactoryV3 = await tester.runTest( `DharmaKeyRingFactoryV3 contract deployment`, DharmaKeyRingFactoryV3Deployer, '', @@ -11839,7 +11840,7 @@ module.exports = {test: async function (testingContext) { } */ - await runTest( + await tester.runTest( 'Dharma Key Registry V2 gets the initial global key correctly', DharmaKeyRegistryV2Coverage, 'getGlobalKey', @@ -11847,20 +11848,20 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 attempt to get an unset specific key throws', DharmaKeyRegistryV2Coverage, 'getSpecificKey', 'call', - [address], + [tester.address], false ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 gets the global key when requesting unset key', DharmaKeyRegistryV2Coverage, 'getKey', @@ -11868,11 +11869,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 cannot set a new empty global key', DharmaKeyRegistryV2Coverage, 'setGlobalKey', @@ -11883,36 +11884,36 @@ module.exports = {test: async function (testingContext) { ], false, receipt => {}, - originalAddress + tester.originalAddress ) const messageCoverage = ( DharmaKeyRegistryV2Coverage.options.address + - addressTwo.slice(2) + + tester.addressTwo.slice(2) + web3.utils.asciiToHex( "This signature demonstrates that the supplied signing key is valid." ).slice(2) ) - const newKeySignatureCoverage = signHashedPrefixedHashedHexString(messageCoverage, addressTwo) + const newKeySignatureCoverage = signHashedPrefixedHashedHexString(messageCoverage, tester.addressTwo) - const badNewKeySignatureCoverage = signHashedPrefixedHashedHexString('0x12', addressTwo) + const badNewKeySignatureCoverage = signHashedPrefixedHashedHexString('0x12', tester.addressTwo) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 cannot set a new global key unless called by owner', DharmaKeyRegistryV2Coverage, 'setGlobalKey', 'send', [ - addressTwo, + tester.addressTwo, newKeySignatureCoverage ], false, receipt => {}, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 cannot set an empty global key', DharmaKeyRegistryV2Coverage, 'setGlobalKey', @@ -11924,30 +11925,30 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 cannot set a new global key with a bad signature', DharmaKeyRegistryV2Coverage, 'setGlobalKey', 'send', [ - addressTwo, + tester.addressTwo, badNewKeySignatureCoverage ], false ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 can set a new global key correctly', DharmaKeyRegistryV2Coverage, 'setGlobalKey', 'send', [ - addressTwo, + tester.addressTwo, newKeySignatureCoverage ] ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 gets the new global key correctly', DharmaKeyRegistryV2Coverage, 'getGlobalKey', @@ -11955,72 +11956,72 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, addressTwo) + assert.strictEqual(value, tester.addressTwo) } ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 cannot set a new specific key unless called by owner', DharmaKeyRegistryV2Coverage, 'setSpecificKey', 'send', [ - address, + tester.address, DharmaKeyRegistryV2.options.address ], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 gets global key for a user if no specific key set', DharmaKeyRegistryV2Coverage, 'getKeyForUser', 'call', - [address], + [tester.address], true, value => { - assert.strictEqual(value, addressTwo) + assert.strictEqual(value, tester.addressTwo) } ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 can set a new specific key', DharmaKeyRegistryV2Coverage, 'setSpecificKey', 'send', [ - address, + tester.address, DharmaKeyRegistryV2.options.address ] ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 gets specific key for user if one is set', DharmaKeyRegistryV2Coverage, 'getKeyForUser', 'call', - [address], + [tester.address], true, value => { assert.strictEqual(value, DharmaKeyRegistryV2.options.address) } ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 gets the new specific key correctly', DharmaKeyRegistryV2Coverage, 'getSpecificKey', 'call', - [address], + [tester.address], true, value => { assert.strictEqual(value, DharmaKeyRegistryV2.options.address) } ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 gets the specific key when requesting set key', DharmaKeyRegistryV2Coverage, 'getKey', @@ -12032,19 +12033,19 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 cannot reuse a specific key', DharmaKeyRegistryV2Coverage, 'setSpecificKey', 'send', [ - address, + tester.address, DharmaKeyRegistryV2.options.address ], false ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 new owner cannot accept ownership before added', DharmaKeyRegistryV2Coverage, 'acceptOwnership', @@ -12053,7 +12054,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 cannot prepare to transfer to the null address', DharmaKeyRegistryV2Coverage, 'transferOwnership', @@ -12064,23 +12065,23 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 can prepare to transfer to a new owner', DharmaKeyRegistryV2Coverage, 'transferOwnership', 'send', [ - address + tester.address ] ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 can cancel an ownership transfer', DharmaKeyRegistryV2Coverage, 'cancelOwnershipTransfer' ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 new owner cannot accept ownership after cancellation', DharmaKeyRegistryV2Coverage, 'acceptOwnership', @@ -12089,23 +12090,23 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 can prepare to transfer to a new owner again', DharmaKeyRegistryV2Coverage, 'transferOwnership', 'send', [ - address + tester.address ] ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 new owner can accept ownership', DharmaKeyRegistryV2Coverage, 'acceptOwnership' ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 gets the new owner', DharmaKeyRegistryV2Coverage, 'owner', @@ -12113,11 +12114,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 gets the global key correctly', DharmaKeyRegistryV2Coverage, 'getGlobalKey', @@ -12125,45 +12126,45 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, addressTwo) + assert.strictEqual(value, tester.addressTwo) } ) const messageV2Coverage = ( DharmaKeyRegistryV2Coverage.options.address + - address.slice(2) + + tester.address.slice(2) + web3.utils.asciiToHex( "This signature demonstrates that the supplied signing key is valid." ).slice(2) ) - const v2KeySignatureCoverage = signHashedPrefixedHashedHexString(messageV2Coverage, address) + const v2KeySignatureCoverage = signHashedPrefixedHashedHexString(messageV2Coverage, tester.address) - await runTest( + await tester.runTest( 'Dharma Key Registry V2 cannot set a previously used global key', DharmaKeyRegistryV2Coverage, 'setGlobalKey', 'send', [ - address, + tester.address, v2KeySignatureCoverage ], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController initially gets zero for lastImplementation`, DharmaUpgradeBeaconControllerCoverage, 'getCodeHashAtLastUpgrade', 'call', - [address], + [tester.address], true, value => { assert.strictEqual(value, constants.NULL_BYTES_32) } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController cannot call upgrade from non-owner account`, DharmaUpgradeBeaconControllerCoverage, 'upgrade', @@ -12171,10 +12172,10 @@ module.exports = {test: async function (testingContext) { [DharmaUpgradeBeaconCoverage.options.address, DharmaUpgradeBeaconController.options.address], false, receipt => {}, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController can set implementation on upgrade beacon contract`, DharmaUpgradeBeaconController, 'upgrade', @@ -12182,7 +12183,7 @@ module.exports = {test: async function (testingContext) { [DharmaUpgradeBeaconCoverage.options.address, DharmaUpgradeBeaconController.options.address] ) - await runTest( + await tester.runTest( `DharmaKeyRingUpgradeBeaconController can set implementation on key ring upgrade beacon contract`, DharmaKeyRingUpgradeBeaconController, 'upgrade', @@ -12190,7 +12191,7 @@ module.exports = {test: async function (testingContext) { [DharmaKeyRingUpgradeBeaconCoverage.options.address, DharmaUpgradeBeaconController.options.address] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconEnvoy throws when given invalid beacon`, DharmaUpgradeBeaconEnvoy, 'getImplementation', @@ -12199,16 +12200,16 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconEnvoy throws when given non-contract beacon`, DharmaUpgradeBeaconEnvoy, 'getImplementation', 'call', - [address], + [tester.address], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconEnvoy can get the implementation of a valid beacon`, DharmaUpgradeBeaconEnvoy, 'getImplementation', @@ -12220,7 +12221,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController cannot set null implementation on an upgrade beacon contract`, DharmaUpgradeBeaconControllerCoverage, 'upgrade', @@ -12229,16 +12230,16 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController cannot set non-contract implementation`, DharmaUpgradeBeaconControllerCoverage, 'upgrade', 'send', - [DharmaUpgradeBeaconCoverage.options.address, address], + [DharmaUpgradeBeaconCoverage.options.address, tester.address], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController cannot set null address beacon`, DharmaUpgradeBeaconControllerCoverage, 'upgrade', @@ -12247,16 +12248,16 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController cannot set non-contract address beacon`, DharmaUpgradeBeaconControllerCoverage, 'upgrade', 'send', - [address, DharmaUpgradeBeaconControllerCoverage.options.address], + [tester.address, DharmaUpgradeBeaconControllerCoverage.options.address], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController cannot set unowned bad beacon`, DharmaUpgradeBeaconControllerCoverage, 'upgrade', @@ -12265,7 +12266,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController cannot set unowned beacon (Note that it still logs an event!)`, DharmaUpgradeBeaconControllerCoverage, 'upgrade', @@ -12273,7 +12274,7 @@ module.exports = {test: async function (testingContext) { [DharmaUpgradeBeaconCoverage.options.address, DharmaUpgradeBeaconControllerCoverage.options.address] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController can get implementation of a beacon`, DharmaUpgradeBeaconControllerCoverage, 'getImplementation', @@ -12285,7 +12286,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController can get owner`, DharmaUpgradeBeaconControllerCoverage, 'owner', @@ -12293,11 +12294,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController can call isOwner and value is ok`, DharmaUpgradeBeaconControllerCoverage, 'isOwner', @@ -12309,7 +12310,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController cannot transfer ownership to null address`, DharmaUpgradeBeaconControllerCoverage, 'transferOwnership', @@ -12318,106 +12319,106 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController can transfer ownership`, DharmaUpgradeBeaconControllerCoverage, 'transferOwnership', 'send', - [address] + [tester.address] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController can renounce ownership`, DharmaUpgradeBeaconControllerCoverage, 'renounceOwnership' ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot transfer ownership from a non-owner`, DharmaAccountRecoveryManagerV2Coverage, 'transferOwnership', 'send', - [addressTwo], + [tester.addressTwo], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot initiate recovery with null smart wallet`, DharmaAccountRecoveryManagerV2Coverage, 'initiateAccountRecovery', 'send', - [constants.NULL_ADDRESS, addressTwo, 0], + [constants.NULL_ADDRESS, tester.addressTwo, 0], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot initiate recovery with null new key`, DharmaAccountRecoveryManagerV2Coverage, 'initiateAccountRecovery', 'send', - [address, constants.NULL_ADDRESS, 0], + [tester.address, constants.NULL_ADDRESS, 0], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can initiate recovery timelock`, DharmaAccountRecoveryManagerV2Coverage, 'initiateAccountRecovery', 'send', - [constants.UPGRADE_BEACON_ADDRESS, addressTwo, 0] + [constants.UPGRADE_BEACON_ADDRESS, tester.addressTwo, 0] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can initiate another recovery timelock`, DharmaAccountRecoveryManagerV2Coverage, 'initiateAccountRecovery', 'send', - [UserSmartWalletV6.options.address, addressTwo, 0] + [UserSmartWalletV6.options.address, tester.addressTwo, 0] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can initiate a third recovery timelock`, DharmaAccountRecoveryManagerV2Coverage, 'initiateAccountRecovery', 'send', - [address, addressTwo, 0] + [tester.address, tester.addressTwo, 0] ) - await runTest( + await tester.runTest( 'smart wallet account recovery cannot be cancelled with no smart wallet', DharmaAccountRecoveryManagerV2Coverage, 'cancelAccountRecovery', 'send', [ constants.NULL_ADDRESS, - addressTwo + tester.addressTwo ], false ) - await runTest( + await tester.runTest( 'smart wallet account recovery cannot be cancelled with no user signing key', DharmaAccountRecoveryManagerV2Coverage, 'cancelAccountRecovery', 'send', [ - address, + tester.address, constants.NULL_ADDRESS ], false ) - await runTest( + await tester.runTest( 'smart wallet account recovery can be cancelled', DharmaAccountRecoveryManagerV2Coverage, 'cancelAccountRecovery', 'send', [ - address, - addressTwo + tester.address, + tester.addressTwo ], true, receipt => { @@ -12426,39 +12427,39 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( 'smart wallet account recovery cannot be cancelled if it is already cancelled', DharmaAccountRecoveryManagerV2Coverage, 'cancelAccountRecovery', 'send', [ - address, - addressTwo + tester.address, + tester.addressTwo ], false ) - await runTest( + await tester.runTest( 'smart wallet account recovery cannot be cancelled if no timelock exists', DharmaAccountRecoveryManagerV2Coverage, 'cancelAccountRecovery', 'send', [ - addressTwo, - addressTwo + tester.addressTwo, + tester.addressTwo ], false ) - await runTest( + await tester.runTest( 'smart wallet account recovery can be reinitiated', DharmaAccountRecoveryManagerV2Coverage, 'initiateAccountRecovery', 'send', [ - address, - addressTwo, + tester.address, + tester.addressTwo, 1 // extraTime in seconds - add one to ensure that timelock is extended ], true, @@ -12468,7 +12469,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot initiate recovery disablement with null smart wallet`, DharmaAccountRecoveryManagerV2Coverage, 'initiateAccountRecoveryDisablement', @@ -12477,56 +12478,56 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can initiate recovery disablement timelock`, DharmaAccountRecoveryManagerV2Coverage, 'initiateAccountRecoveryDisablement', 'send', - [address, 0] + [tester.address, 0] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call recover with null new key`, DharmaAccountRecoveryManagerV2Coverage, 'recover', 'send', - [constants.NULL_ADDRESS, addressTwo], + [constants.NULL_ADDRESS, tester.addressTwo], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call recover with null new key`, DharmaAccountRecoveryManagerV2Coverage, 'recover', 'send', - [address, constants.NULL_ADDRESS], + [tester.address, constants.NULL_ADDRESS], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call recover prior to timelock completion`, DharmaAccountRecoveryManagerV2Coverage, 'recover', 'send', - [constants.UPGRADE_BEACON_ADDRESS, addressTwo], + [constants.UPGRADE_BEACON_ADDRESS, tester.addressTwo], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery prior to timelock completion`, DharmaAccountRecoveryManagerV2Coverage, 'disableAccountRecovery', 'send', - [address], + [tester.address], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can check if account recovery is disabled`, DharmaAccountRecoveryManagerV2Coverage, 'accountRecoveryDisabled', 'call', - [address], + [tester.address], true, value => { assert.ok(!value) @@ -12536,33 +12537,33 @@ module.exports = {test: async function (testingContext) { // advance time by 3 days await advanceTime((60 * 60 * 24 * 3) + 5) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can call recover after timelock completion`, DharmaAccountRecoveryManagerV2Coverage, 'recover', 'send', - [constants.UPGRADE_BEACON_ADDRESS, addressTwo] + [constants.UPGRADE_BEACON_ADDRESS, tester.addressTwo] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot recover an unowned smart wallet`, DharmaAccountRecoveryManagerV2Coverage, 'recover', 'send', - [UserSmartWalletV6.options.address, addressTwo], + [UserSmartWalletV6.options.address, tester.addressTwo], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot recover an EOA`, DharmaAccountRecoveryManagerV2Coverage, 'recover', 'send', - [address, addressTwo], + [tester.address, tester.addressTwo], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery with null smart wallet`, DharmaAccountRecoveryManagerV2Coverage, 'disableAccountRecovery', @@ -12571,36 +12572,36 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can call disableAccountRecovery after timelock completion`, DharmaAccountRecoveryManagerV2Coverage, 'disableAccountRecovery', 'send', - [address] + [tester.address] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can check if account recovery is disabled`, DharmaAccountRecoveryManagerV2Coverage, 'accountRecoveryDisabled', 'call', - [address], + [tester.address], true, value => { assert.ok(value) } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot recover an account that has disabled recovery`, DharmaAccountRecoveryManagerV2Coverage, 'recover', 'send', - [address, addressTwo], + [tester.address, tester.addressTwo], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval with no selector`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockInterval', @@ -12609,7 +12610,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval to modify interval over 8 weeks`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockInterval', @@ -12618,7 +12619,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockInterval', @@ -12626,7 +12627,7 @@ module.exports = {test: async function (testingContext) { ['0xe950c085', 10000, 0] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock on another function`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockInterval', @@ -12634,7 +12635,7 @@ module.exports = {test: async function (testingContext) { ['0xaaaaaaaa', 10000, 0] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval with no selector`, DharmaAccountRecoveryManagerV2Coverage, 'modifyTimelockInterval', @@ -12643,7 +12644,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval before timelock completion`, DharmaAccountRecoveryManagerV2Coverage, 'modifyTimelockInterval', @@ -12652,7 +12653,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration with no selector`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockExpiration', @@ -12661,7 +12662,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to with expiration over one month`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockExpiration', @@ -12670,7 +12671,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to modify expiration under one minute`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockExpiration', @@ -12679,7 +12680,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to modify expiration under one hour`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockExpiration', @@ -12688,7 +12689,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockExpiration', @@ -12696,7 +12697,7 @@ module.exports = {test: async function (testingContext) { ['0xd7ce3c6f', 30000, 0], ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock on another function`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockExpiration', @@ -12704,7 +12705,7 @@ module.exports = {test: async function (testingContext) { ['0xaaaaaaaa', 300000, 0] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration with no selector`, DharmaAccountRecoveryManagerV2Coverage, 'modifyTimelockExpiration', @@ -12713,7 +12714,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration before timelock completion`, DharmaAccountRecoveryManagerV2Coverage, 'modifyTimelockExpiration', @@ -12722,15 +12723,15 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can initiate recovery disablement timelock`, DharmaAccountRecoveryManagerV2Coverage, 'initiateAccountRecoveryDisablement', 'send', - [addressTwo, 0] + [tester.addressTwo, 0] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot cancel disablement with null address`, DharmaAccountRecoveryManagerV2Coverage, 'cancelAccountRecoveryDisablement', @@ -12739,54 +12740,54 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can cancel recovery disablement timelock`, DharmaAccountRecoveryManagerV2Coverage, 'cancelAccountRecoveryDisablement', 'send', - [addressTwo] + [tester.addressTwo] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can re-initiate recovery disablement timelock`, DharmaAccountRecoveryManagerV2Coverage, 'initiateAccountRecoveryDisablement', 'send', - [addressTwo, 1] + [tester.addressTwo, 1] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot shorten a timelock`, DharmaAccountRecoveryManagerV2Coverage, 'initiateAccountRecoveryDisablement', 'send', - [addressTwo, 0], + [tester.addressTwo, 0], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot initiate recovery with massive extraTime`, DharmaAccountRecoveryManagerV2Coverage, 'initiateAccountRecovery', 'send', - [address, addressTwo, constants.FULL_APPROVAL], + [tester.address, tester.addressTwo, constants.FULL_APPROVAL], false ) // advance time by 2 weeks await advanceTime((60 * 60 * 24 * 7 * 2) + 5) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery after timelock expiration`, DharmaAccountRecoveryManagerV2Coverage, 'disableAccountRecovery', 'send', - [addressTwo], + [tester.addressTwo], false ) - await runTest( - `DharmaAccountRecoveryManagerV2 cannot set a role to the null address`, + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot set a role to the null tester.address`, DharmaAccountRecoveryManagerV2Coverage, 'setRole', 'send', @@ -12794,23 +12795,23 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can set a role`, DharmaAccountRecoveryManagerV2Coverage, 'setRole', 'send', - [0, address] + [0, tester.address] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can set a role that is already set`, DharmaAccountRecoveryManagerV2Coverage, 'setRole', 'send', - [0, address] + [0, tester.address] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can check if the caller has a role`, DharmaAccountRecoveryManagerV2Coverage, 'isRole', @@ -12822,7 +12823,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can check for an operator role`, DharmaAccountRecoveryManagerV2Coverage, 'getOperator', @@ -12830,11 +12831,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can check for a recoverer role`, DharmaAccountRecoveryManagerV2Coverage, 'getRecoverer', @@ -12846,7 +12847,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can check for a canceller role`, DharmaAccountRecoveryManagerV2Coverage, 'getCanceller', @@ -12858,7 +12859,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can check for a disabler role`, DharmaAccountRecoveryManagerV2Coverage, 'getDisabler', @@ -12870,7 +12871,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can check for a pauser role`, DharmaAccountRecoveryManagerV2Coverage, 'getPauser', @@ -12882,7 +12883,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can remove a role`, DharmaAccountRecoveryManagerV2Coverage, 'removeRole', @@ -12890,7 +12891,7 @@ module.exports = {test: async function (testingContext) { [0] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can check if the caller has a role`, DharmaAccountRecoveryManagerV2Coverage, 'isRole', @@ -12902,7 +12903,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can check if a role is paused`, DharmaAccountRecoveryManagerV2Coverage, 'isPaused', @@ -12914,7 +12915,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot pause a role if not owner or pauser`, DharmaAccountRecoveryManagerV2Coverage, 'pause', @@ -12922,18 +12923,18 @@ module.exports = {test: async function (testingContext) { [0], false, receipt => {}, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can set a role`, DharmaAccountRecoveryManagerV2Coverage, 'setRole', 'send', - [4, addressTwo] + [4, tester.addressTwo] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot unpause an unpaused role`, DharmaAccountRecoveryManagerV2Coverage, 'unpause', @@ -12942,7 +12943,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can pause an unpaused role`, DharmaAccountRecoveryManagerV2Coverage, 'pause', @@ -12950,10 +12951,10 @@ module.exports = {test: async function (testingContext) { [0], true, receipt => {}, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot pause a paused role`, DharmaAccountRecoveryManagerV2Coverage, 'pause', @@ -12961,10 +12962,10 @@ module.exports = {test: async function (testingContext) { [0], false, receipt => {}, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can pause the pauser role`, DharmaAccountRecoveryManagerV2Coverage, 'pause', @@ -12972,7 +12973,7 @@ module.exports = {test: async function (testingContext) { [4] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 pauser cannot call a paused role`, DharmaAccountRecoveryManagerV2Coverage, 'pause', @@ -12980,10 +12981,10 @@ module.exports = {test: async function (testingContext) { [4], false, receipt => {}, - addressTwo + tester.addressTwo ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can check if a role is paused`, DharmaAccountRecoveryManagerV2Coverage, 'isPaused', @@ -12995,7 +12996,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can unpause a paused role`, DharmaAccountRecoveryManagerV2Coverage, 'unpause', @@ -13003,7 +13004,7 @@ module.exports = {test: async function (testingContext) { [0] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can get an empty timelock`, DharmaAccountRecoveryManagerV2Coverage, 'getTimelock', @@ -13019,7 +13020,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can get an empty default timelock interval`, DharmaAccountRecoveryManagerV2Coverage, 'getDefaultTimelockInterval', @@ -13031,7 +13032,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can get an empty default timelock expiration`, DharmaAccountRecoveryManagerV2Coverage, 'getDefaultTimelockExpiration', @@ -13043,7 +13044,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval with no selector`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockInterval', @@ -13052,7 +13053,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval to modify interval over 8 weeks`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockInterval', @@ -13061,7 +13062,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot create timelock with excessive duration`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockInterval', @@ -13070,7 +13071,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockInterval', @@ -13078,7 +13079,7 @@ module.exports = {test: async function (testingContext) { ['0xe950c085', 10000, 5] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot shorten existing initiateModifyTimelockInterval timelock`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockInterval', @@ -13087,7 +13088,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to change a duration`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockInterval', @@ -13095,7 +13096,7 @@ module.exports = {test: async function (testingContext) { ['0xe950c085', 10001, 5] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock on another function`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockInterval', @@ -13103,7 +13104,7 @@ module.exports = {test: async function (testingContext) { ['0xaaaaaaaa', 10000, 0] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval with no selector`, DharmaAccountRecoveryManagerV2Coverage, 'modifyTimelockInterval', @@ -13112,7 +13113,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval before timelock completion`, DharmaAccountRecoveryManagerV2Coverage, 'modifyTimelockInterval', @@ -13121,7 +13122,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration with no selector`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockExpiration', @@ -13130,7 +13131,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to with expiration over one month`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockExpiration', @@ -13139,7 +13140,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to modify expiration under one minute`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockExpiration', @@ -13148,7 +13149,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockExpiration', @@ -13156,7 +13157,7 @@ module.exports = {test: async function (testingContext) { ['0xd7ce3c6f', 300000, 0], ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock on another function`, DharmaAccountRecoveryManagerV2Coverage, 'initiateModifyTimelockExpiration', @@ -13164,7 +13165,7 @@ module.exports = {test: async function (testingContext) { ['0xe950c085', 30, 0] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration with no selector`, DharmaAccountRecoveryManagerV2Coverage, 'modifyTimelockExpiration', @@ -13173,7 +13174,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration before timelock completion`, DharmaAccountRecoveryManagerV2Coverage, 'modifyTimelockExpiration', @@ -13185,7 +13186,7 @@ module.exports = {test: async function (testingContext) { // advance time by 2 weeks await advanceTime((60 * 60 * 24 * 7 * 2) + 5) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can call modifyTimelockInterval`, DharmaAccountRecoveryManagerV2Coverage, 'modifyTimelockInterval', @@ -13193,7 +13194,7 @@ module.exports = {test: async function (testingContext) { ['0xaaaaaaaa', 10000] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 can call modifyTimelockExpiration`, DharmaAccountRecoveryManagerV2Coverage, 'modifyTimelockExpiration', @@ -13201,7 +13202,7 @@ module.exports = {test: async function (testingContext) { ['0xd7ce3c6f', 300000], ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration if expiration is too short`, DharmaAccountRecoveryManagerV2Coverage, 'modifyTimelockExpiration', @@ -13210,71 +13211,71 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot transfer ownership from a non-owner`, DharmaUpgradeBeaconControllerManagerCoverage, 'transferOwnership', 'send', - [addressTwo], + [tester.addressTwo], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with null controller`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateUpgrade', 'send', - [constants.NULL_ADDRESS, address, addressTwo, 0], + [constants.NULL_ADDRESS, tester.address, tester.addressTwo, 0], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with null beacon`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateUpgrade', 'send', - [address, constants.NULL_ADDRESS, addressTwo, 0], + [tester.address, constants.NULL_ADDRESS, tester.addressTwo, 0], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with null implementation`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateUpgrade', 'send', - [address, addressTwo, constants.NULL_ADDRESS, 0], + [tester.address, tester.addressTwo, constants.NULL_ADDRESS, 0], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with non-contract implementation`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateUpgrade', 'send', - [address, addressTwo, address, 0], + [tester.address, tester.addressTwo, tester.address, 0], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with massive extraTime`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateUpgrade', 'send', - [address, addressTwo, DharmaUpgradeBeaconControllerManager.options.address, constants.FULL_APPROVAL], + [tester.address, tester.addressTwo, DharmaUpgradeBeaconControllerManager.options.address, constants.FULL_APPROVAL], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can initiate upgrade timelock`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateUpgrade', 'send', - [address, addressTwo, DharmaUpgradeBeaconControllerManager.options.address, 0] + [tester.address, tester.addressTwo, DharmaUpgradeBeaconControllerManager.options.address, 0] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can get an empty timelock`, DharmaUpgradeBeaconControllerManagerCoverage, 'getTimelock', @@ -13290,7 +13291,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can get an empty default timelock interval`, DharmaUpgradeBeaconControllerManagerCoverage, 'getDefaultTimelockInterval', @@ -13302,7 +13303,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can get an empty default timelock expiration`, DharmaUpgradeBeaconControllerManagerCoverage, 'getDefaultTimelockExpiration', @@ -13314,37 +13315,37 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot upgrade before timelock is complete`, DharmaUpgradeBeaconControllerManagerCoverage, 'upgrade', 'send', - [address, addressTwo, DharmaUpgradeBeaconControllerManager.options.address], + [tester.address, tester.addressTwo, DharmaUpgradeBeaconControllerManager.options.address], false ) // advance time by 7 days await advanceTime((60 * 60 * 24 * 7) + 5) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot upgrade an unowned controller`, DharmaUpgradeBeaconControllerManagerCoverage, 'upgrade', 'send', - [address, addressTwo, DharmaUpgradeBeaconControllerManager.options.address], + [tester.address, tester.addressTwo, DharmaUpgradeBeaconControllerManager.options.address], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot transfer controller ownership before accepting ownership`, DharmaUpgradeBeaconControllerManagerCoverage, 'transferControllerOwnership', 'send', - [address, address], + [tester.address, tester.address], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot agree to accept ownership of null controller`, DharmaUpgradeBeaconControllerManagerCoverage, 'agreeToAcceptControllerOwnership', @@ -13353,71 +13354,71 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can agree to accept ownership`, DharmaUpgradeBeaconControllerManagerCoverage, 'agreeToAcceptControllerOwnership', 'send', - [address, true] + [tester.address, true] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot initiate controller ownership transfer with null controller`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateTransferControllerOwnership', 'send', - [constants.NULL_ADDRESS, addressTwo, 0], + [constants.NULL_ADDRESS, tester.addressTwo, 0], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot initiate controller ownership transfer with null new owner`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateTransferControllerOwnership', 'send', - [address, constants.NULL_ADDRESS, 0], + [tester.address, constants.NULL_ADDRESS, 0], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot initiate controller ownership transfer if new owner has not accepted`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateTransferControllerOwnership', 'send', - [address, addressTwo, 0], + [tester.address, tester.addressTwo, 0], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can initiate controller ownership transfer if new owner has accepted`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateTransferControllerOwnership', 'send', - [address, address, 0] + [tester.address, tester.address, 0] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot transfer controller ownership prior to timelock completion`, DharmaUpgradeBeaconControllerManagerCoverage, 'transferControllerOwnership', 'send', - [address, address], + [tester.address, tester.address], false ) // advance time by 4 weeks await advanceTime((60 * 60 * 24 * 7 * 4) + 5) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot transfer unowned controller ownership`, DharmaUpgradeBeaconControllerManagerCoverage, 'transferControllerOwnership', 'send', - [address, address], + [tester.address, tester.address], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot heartbeat from non-heartbeater`, DharmaUpgradeBeaconControllerManagerCoverage, 'heartbeat', @@ -13425,16 +13426,16 @@ module.exports = {test: async function (testingContext) { [], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can heartbeat`, DharmaUpgradeBeaconControllerManagerCoverage, 'heartbeat' ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot set new heartbeater to null address`, DharmaUpgradeBeaconControllerManagerCoverage, 'newHeartbeater', @@ -13443,15 +13444,15 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager owner can set new heartbeater`, DharmaUpgradeBeaconControllerManagerCoverage, 'newHeartbeater', 'send', - [address] + [tester.address] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot arm Adharma Contingency from non-owner when not expired`, DharmaUpgradeBeaconControllerManagerCoverage, 'armAdharmaContingency', @@ -13459,10 +13460,10 @@ module.exports = {test: async function (testingContext) { [true], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when not armed`, DharmaUpgradeBeaconControllerManagerCoverage, 'activateAdharmaContingency', @@ -13471,7 +13472,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager owner can arm an Adharma Contingency`, DharmaUpgradeBeaconControllerManagerCoverage, 'armAdharmaContingency', @@ -13479,7 +13480,7 @@ module.exports = {test: async function (testingContext) { [true] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager owner can disarm Adharma Contingency`, DharmaUpgradeBeaconControllerManagerCoverage, 'armAdharmaContingency', @@ -13487,7 +13488,7 @@ module.exports = {test: async function (testingContext) { [false] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager owner can re-arm Adharma Contingency`, DharmaUpgradeBeaconControllerManagerCoverage, 'armAdharmaContingency', @@ -13495,7 +13496,7 @@ module.exports = {test: async function (testingContext) { [true] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency from non-owner when not expired`, DharmaUpgradeBeaconControllerManagerCoverage, 'activateAdharmaContingency', @@ -13503,10 +13504,10 @@ module.exports = {test: async function (testingContext) { [], false, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when it doesn't own controllers`, DharmaUpgradeBeaconControllerManagerCoverage, 'activateAdharmaContingency', @@ -13515,26 +13516,26 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot roll back prior to first upgrade`, DharmaUpgradeBeaconControllerManagerCoverage, 'rollback', 'send', - [address, address, 0], + [tester.address, tester.address, 0], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot exit Adharma Contingency when not active`, DharmaUpgradeBeaconControllerManagerCoverage, 'exitAdharmaContingency', 'send', - [address, address], + [tester.address, tester.address], false ) /* - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can activate Adharma Contingency`, DharmaUpgradeBeaconControllerManagerCoverage, 'activateAdharmaContingency', @@ -13542,7 +13543,7 @@ module.exports = {test: async function (testingContext) { [] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager owner cannot arm Adharma Contingency while active`, DharmaUpgradeBeaconControllerManagerCoverage, 'armAdharmaContingency', @@ -13550,7 +13551,7 @@ module.exports = {test: async function (testingContext) { [true] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot activate Contingency when activated`, DharmaUpgradeBeaconControllerManagerCoverage, 'activateAdharmaContingency', @@ -13559,7 +13560,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager owner can disarm Adharma Contingency`, DharmaUpgradeBeaconControllerManagerCoverage, 'armAdharmaContingency', @@ -13567,7 +13568,7 @@ module.exports = {test: async function (testingContext) { [false] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot exit Contingency before 48 hours`, DharmaUpgradeBeaconControllerManagerCoverage, 'exitAdharmaContingency', @@ -13582,7 +13583,7 @@ module.exports = {test: async function (testingContext) { // advance time by 2 days await advanceTime((60 * 60 * 24 * 2) + 5) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot exit Contingency to null address`, DharmaUpgradeBeaconControllerManagerCoverage, 'exitAdharmaContingency', @@ -13591,7 +13592,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot exit Contingency to non-contract address`, DharmaUpgradeBeaconControllerManagerCoverage, 'exitAdharmaContingency', @@ -13600,7 +13601,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can exit Contingency after 48 hours`, DharmaUpgradeBeaconControllerManagerCoverage, 'exitAdharmaContingency', @@ -13611,7 +13612,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager owner can arm Adharma Contingency again`, DharmaUpgradeBeaconControllerManagerCoverage, 'armAdharmaContingency', @@ -13619,7 +13620,7 @@ module.exports = {test: async function (testingContext) { [true] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can activate fake Adharma Contingency again`, DharmaUpgradeBeaconControllerManagerCoverage, 'activateAdharmaContingency', @@ -13627,7 +13628,7 @@ module.exports = {test: async function (testingContext) { [] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can roll back from fake Adharma Contingency`, DharmaUpgradeBeaconControllerManagerCoverage, 'rollback', @@ -13635,7 +13636,7 @@ module.exports = {test: async function (testingContext) { [constants.UPGRADE_BEACON_CONTROLLER_ADDRESS, constants.UPGRADE_BEACON_ADDRESS, 0] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can "roll forward" after roll back`, DharmaUpgradeBeaconControllerManagerCoverage, 'rollback', @@ -13644,7 +13645,7 @@ module.exports = {test: async function (testingContext) { ) */ - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can get heartbeat status`, DharmaUpgradeBeaconControllerManagerCoverage, 'heartbeatStatus', @@ -13656,7 +13657,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager get contingency status when armed but not activated`, DharmaUpgradeBeaconControllerManagerCoverage, 'contingencyStatus', @@ -13670,46 +13671,46 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager gets 0 for non-existent total implementations`, DharmaUpgradeBeaconControllerManagerCoverage, 'getTotalPriorImplementations', 'call', - [address, address], + [tester.address, tester.address], true, value => { assert.strictEqual(value, '0') } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot get a prior implementation with no index`, DharmaUpgradeBeaconControllerManagerCoverage, 'getPriorImplementation', 'call', - [address, address, 100], + [tester.address, tester.address, 100], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot rollback to implementation with no index`, DharmaUpgradeBeaconControllerManagerCoverage, 'rollback', 'send', - [address, address, 100], + [tester.address, tester.address, 100], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot block rollback to implementation with no index`, DharmaUpgradeBeaconControllerManagerCoverage, 'blockRollback', 'send', - [address, address, 100], + [tester.address, tester.address, 100], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockInterval with no selector`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateModifyTimelockInterval', @@ -13718,7 +13719,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockInterval to modify interval over 8 weeks`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateModifyTimelockInterval', @@ -13727,7 +13728,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot create timelock with excessive duration`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateModifyTimelockInterval', @@ -13736,7 +13737,7 @@ module.exports = {test: async function (testingContext) { false // TODO: move this outside of Controller manager ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockInterval to set a timelock`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateModifyTimelockInterval', @@ -13744,7 +13745,7 @@ module.exports = {test: async function (testingContext) { ['0xe950c085', 10000, 5] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot shorten existing initiateModifyTimelockInterval timelock`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateModifyTimelockInterval', @@ -13753,7 +13754,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockInterval to change a duration`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateModifyTimelockInterval', @@ -13761,7 +13762,7 @@ module.exports = {test: async function (testingContext) { ['0xe950c085', 10001, 5] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockInterval to set a timelock on another function`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateModifyTimelockInterval', @@ -13769,7 +13770,7 @@ module.exports = {test: async function (testingContext) { ['0xaaaaaaaa', 10000, 0] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockInterval with no selector`, DharmaUpgradeBeaconControllerManagerCoverage, 'modifyTimelockInterval', @@ -13778,7 +13779,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockInterval before timelock completion`, DharmaUpgradeBeaconControllerManagerCoverage, 'modifyTimelockInterval', @@ -13787,7 +13788,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockExpiration with no selector`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateModifyTimelockExpiration', @@ -13796,7 +13797,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockExpiration to with expiration over one month`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateModifyTimelockExpiration', @@ -13805,7 +13806,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockExpiration to modify expiration under one minute`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateModifyTimelockExpiration', @@ -13814,7 +13815,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockExpiration to set a timelock`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateModifyTimelockExpiration', @@ -13822,7 +13823,7 @@ module.exports = {test: async function (testingContext) { ['0xd7ce3c6f', 300000, 0], ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockExpiration to set a timelock on another function`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateModifyTimelockExpiration', @@ -13830,7 +13831,7 @@ module.exports = {test: async function (testingContext) { ['0xe950c085', 30, 0] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockExpiration with no selector`, DharmaUpgradeBeaconControllerManagerCoverage, 'modifyTimelockExpiration', @@ -13839,7 +13840,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockExpiration before timelock completion`, DharmaUpgradeBeaconControllerManagerCoverage, 'modifyTimelockExpiration', @@ -13851,7 +13852,7 @@ module.exports = {test: async function (testingContext) { // advance time by 4 weeks await advanceTime((60 * 60 * 24 * 7 * 4) + 5) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can call modifyTimelockInterval`, DharmaUpgradeBeaconControllerManagerCoverage, 'modifyTimelockInterval', @@ -13859,7 +13860,7 @@ module.exports = {test: async function (testingContext) { ['0xaaaaaaaa', 10000] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can call modifyTimelockExpiration`, DharmaUpgradeBeaconControllerManagerCoverage, 'modifyTimelockExpiration', @@ -13867,7 +13868,7 @@ module.exports = {test: async function (testingContext) { ['0xd7ce3c6f', 300000], ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockExpiration if expiration is too short`, DharmaUpgradeBeaconControllerManagerCoverage, 'modifyTimelockExpiration', @@ -13876,7 +13877,7 @@ module.exports = {test: async function (testingContext) { false ) - const MockDharmaKeyRingFactory = await runTest( + const MockDharmaKeyRingFactory = await tester.runTest( `MockDharmaKeyRingFactory contract deployment`, MockDharmaKeyRingFactoryDeployer, '', @@ -13884,7 +13885,7 @@ module.exports = {test: async function (testingContext) { [] ) - await runTest( + await tester.runTest( `MockDharmaKeyRingFactory cannot deploy a DharmaV1 key ring with no keys`, MockDharmaKeyRingFactory, 'newKeyRing', @@ -13893,7 +13894,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `MockDharmaKeyRingFactory cannot deploy a DharmaV1 key ring with null address as key`, MockDharmaKeyRingFactory, 'newKeyRing', @@ -13902,34 +13903,34 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `MockDharmaKeyRingFactory cannot deploy a DharmaV1 key ring with non-dual key`, MockDharmaKeyRingFactory, 'newKeyRing', 'send', - [1, 1, [address], [1]], + [1, 1, [tester.address], [1]], false ) - await runTest( + await tester.runTest( `MockDharmaKeyRingFactory cannot deploy a DharmaV1 key ring with admin threshold > 1`, MockDharmaKeyRingFactory, 'newKeyRing', 'send', - [2, 1, [address], [3]], + [2, 1, [tester.address], [3]], false ) - await runTest( + await tester.runTest( `MockDharmaKeyRingFactory cannot deploy a DharmaV1 key ring with executor threshold > 1`, MockDharmaKeyRingFactory, 'newKeyRing', 'send', - [1, 2, [address], [3]], + [1, 2, [tester.address], [3]], false ) - await runTest( + await tester.runTest( 'Dharma Upgrade Beacon Controller can upgrade to AdharmaSmartWalletImplementation', DharmaUpgradeBeaconController, 'upgrade', @@ -13940,7 +13941,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'Dharma Key Ring Upgrade Beacon Controller can upgrade to AdharmaKeyRingImplementation', DharmaKeyRingUpgradeBeaconController, 'upgrade', @@ -13951,7 +13952,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 cannot deploy an Adharma smart wallet with no key', DharmaSmartWalletFactoryV1, 'newSmartWallet', @@ -13960,15 +13961,15 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( 'DharmaSmartWalletFactoryV1 can deploy an Adharma smart wallet', DharmaSmartWalletFactoryV1, 'newSmartWallet', 'send', - [address] + [tester.address] ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV1 cannot create a V1 key ring with no key`, DharmaKeyRingFactoryV1, 'newKeyRing', @@ -13977,16 +13978,16 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV1 cannot create an Adharma key ring and set a new null key`, DharmaKeyRingFactoryV1, 'newKeyRingAndAdditionalKey', 'send', - [address, constants.NULL_ADDRESS, '0x'], + [tester.address, constants.NULL_ADDRESS, '0x'], false ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV1 reverts when no new key ring supplied`, DharmaKeyRingFactoryV1, 'getNextKeyRing', @@ -13995,30 +13996,30 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV1 can call newKeyRingAndDaiWithdrawal`, DharmaKeyRingFactoryV1, 'newKeyRingAndDaiWithdrawal', 'send', - [address, address, 0, address, 0, '0x', '0x'], + [tester.address, tester.address, 0, tester.address, 0, '0x', '0x'], false ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV1 can call newKeyRingAndUSDCWithdrawal`, DharmaKeyRingFactoryV1, 'newKeyRingAndUSDCWithdrawal', 'send', - [address, address, 0, address, 0, '0x', '0x'], + [tester.address, tester.address, 0, tester.address, 0, '0x', '0x'], false ) - await runTest( + await tester.runTest( `DharmaKeyRingFactoryV1 can create an Adharma key ring`, DharmaKeyRingFactoryV1, 'newKeyRing', 'send', - [address] + [tester.address] ) const UserSmartWalletAdharma = new web3.eth.Contract( @@ -14026,7 +14027,7 @@ module.exports = {test: async function (testingContext) { UserSmartWalletV6.options.address ) - await runTest( + await tester.runTest( `Adharma Smart Wallet can be used to perform calls`, UserSmartWalletAdharma, 'performCall', @@ -14034,10 +14035,10 @@ module.exports = {test: async function (testingContext) { [UserSmartWalletAdharma.options.address, 0, '0x'], true, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( `Adharma Smart Wallet can be used to perform failing calls`, UserSmartWalletAdharma, 'performCall', @@ -14045,7 +14046,7 @@ module.exports = {test: async function (testingContext) { [BadBeacon.options.address, 0, '0x'], false, receipt => {}, - originalAddress + tester.originalAddress ) const KeyRingAdharma = new web3.eth.Contract( @@ -14053,15 +14054,15 @@ module.exports = {test: async function (testingContext) { KeyRingInstance.options.address ) - await runTest( + await tester.runTest( `Adharma Key Ring can be used to take an action`, KeyRingAdharma, 'takeAction', 'send', - [address, 0, '0x', '0x'] + [tester.address, 0, '0x', '0x'] ) - await runTest( + await tester.runTest( `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with no keys`, MockDharmaKeyRingFactory, 'newKeyRing', @@ -14070,78 +14071,78 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with admin threshold of 0`, MockDharmaKeyRingFactory, 'newKeyRing', 'send', - [0, 1, [address], [3]], + [0, 1, [tester.address], [3]], false ) - await runTest( + await tester.runTest( `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with executor threshold of 0`, MockDharmaKeyRingFactory, 'newKeyRing', 'send', - [1, 0, [address], [3]], + [1, 0, [tester.address], [3]], false ) - await runTest( + await tester.runTest( `MockDharmaKeyRingFactory cannot deploy an Adharma key ring where length of keys and types are not equal`, MockDharmaKeyRingFactory, 'newKeyRing', 'send', - [1, 1, [address, addressTwo], [3]], + [1, 1, [tester.address, tester.addressTwo], [3]], false ) - await runTest( + await tester.runTest( `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with duplicate keys`, MockDharmaKeyRingFactory, 'newKeyRing', 'send', - [1, 1, [address, address], [3, 3]], + [1, 1, [tester.address, tester.address], [3, 3]], false ) - await runTest( + await tester.runTest( `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with no admin key`, MockDharmaKeyRingFactory, 'newKeyRing', 'send', - [1, 1, [address], [1]], + [1, 1, [tester.address], [1]], false ) - await runTest( + await tester.runTest( `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with less admin keys than threshold`, MockDharmaKeyRingFactory, 'newKeyRing', 'send', - [2, 1, [address], [3]], + [2, 1, [tester.address], [3]], false ) - await runTest( + await tester.runTest( `MockDharmaKeyRingFactory can deploy an Adharma key ring with multiple keys`, MockDharmaKeyRingFactory, 'newKeyRing', 'send', - [2, 2, [address, addressTwo], [3, 3]] + [2, 2, [tester.address, tester.addressTwo], [3, 3]] ) - await runTest( + await tester.runTest( `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with no standard key`, MockDharmaKeyRingFactory, 'newKeyRing', 'send', - [1, 1, [address], [2]], + [1, 1, [tester.address], [2]], false ) - await runTest( + await tester.runTest( `TimelockEdgecaseTester contract deployment edge case 1`, TimelockEdgecaseTesterDeployer, '', @@ -14150,7 +14151,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `TimelockEdgecaseTester contract deployment edge case 2`, TimelockEdgecaseTesterDeployer, '', @@ -14159,7 +14160,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `TimelockEdgecaseTester contract deployment edge case 3`, TimelockEdgecaseTesterDeployer, '', @@ -14168,7 +14169,7 @@ module.exports = {test: async function (testingContext) { false ) - const DharmaUpgradeMultisig = await runTest( + const DharmaUpgradeMultisig = await tester.runTest( `DharmaUpgradeMultisig contract deployment`, DharmaUpgradeMultisigDeployer, '', @@ -14176,7 +14177,7 @@ module.exports = {test: async function (testingContext) { [[ownerOne, ownerTwo, ownerThree, ownerFour, ownerFive]] ) - const DharmaAccountRecoveryMultisig = await runTest( + const DharmaAccountRecoveryMultisig = await tester.runTest( `DharmaAccountRecoveryMultisig contract deployment`, DharmaAccountRecoveryMultisigDeployer, '', @@ -14184,7 +14185,7 @@ module.exports = {test: async function (testingContext) { [[ownerOne, ownerTwo, ownerThree, ownerFour]] ) - const DharmaAccountRecoveryOperatorMultisig = await runTest( + const DharmaAccountRecoveryOperatorMultisig = await tester.runTest( `DharmaAccountRecoveryOperatorMultisig contract deployment`, DharmaAccountRecoveryOperatorMultisigDeployer, '', @@ -14192,7 +14193,7 @@ module.exports = {test: async function (testingContext) { [[ownerOne, ownerTwo, ownerThree, ownerFour]] ) - const DharmaKeyRegistryMultisig = await runTest( + const DharmaKeyRegistryMultisig = await tester.runTest( `DharmaKeyRegistryMultisig contract deployment`, DharmaKeyRegistryMultisigDeployer, '', @@ -14210,7 +14211,7 @@ module.exports = {test: async function (testingContext) { '7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A01a' ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig can get the initial nonce`, DharmaUpgradeMultisig, 'getNonce', @@ -14222,7 +14223,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig can get the owners`, DharmaUpgradeMultisig, 'getOwners', @@ -14236,7 +14237,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig can get an owner`, DharmaUpgradeMultisig, 'isOwner', @@ -14248,19 +14249,19 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig returns false for a non-owner`, DharmaUpgradeMultisig, 'isOwner', 'call', - [address], + [tester.address], true, value => { assert.ok(!value) } ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig can get the threshold`, DharmaUpgradeMultisig, 'getThreshold', @@ -14272,7 +14273,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig can get the destination`, DharmaUpgradeMultisig, 'getDestination', @@ -14288,31 +14289,31 @@ module.exports = {test: async function (testingContext) { hashInputs = ( DharmaUpgradeMultisig.options.address + '0'.padStart(64, '0') + - address.slice(2) + + tester.address.slice(2) + executorGasLimit.toString(16).padStart(64, '0') + rawData.slice(2) ) hash = util.bufferToHex(util.keccak256(hashInputs)) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig can get a hash`, DharmaUpgradeMultisig, 'getNextHash', 'call', - [rawData, address, executorGasLimit], + [rawData, tester.address, executorGasLimit], true, value => { assert.strictEqual(value, hash) } ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig can get a hash with a specific nonce`, DharmaUpgradeMultisig, 'getHash', 'call', - [rawData, address, executorGasLimit, 0], + [rawData, tester.address, executorGasLimit, 0], true, value => { assert.strictEqual(value, hash) @@ -14324,72 +14325,72 @@ module.exports = {test: async function (testingContext) { ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) + ownerThreeSig.slice(2) - unownedSig = signHashedPrefixedHexString(hash, address) + unownedSig = signHashedPrefixedHexString(hash, tester.address) unownedSigs = unownedSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig cannot call execute from non-executor`, DharmaUpgradeMultisig, 'execute', 'send', - [rawData, addressTwo, executorGasLimit, ownerSigs], + [rawData, tester.addressTwo, executorGasLimit, ownerSigs], false ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig cannot call execute with oddly-sized signatures`, DharmaUpgradeMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigs + '1234'], + [rawData, tester.address, executorGasLimit, ownerSigs + '1234'], false ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig cannot call execute with non-compliant signatures`, DharmaUpgradeMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, bizarreSigs], + [rawData, tester.address, executorGasLimit, bizarreSigs], false ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig cannot call execute without enough signatures`, DharmaUpgradeMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigs.slice(0, -130)], + [rawData, tester.address, executorGasLimit, ownerSigs.slice(0, -130)], false ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig cannot call execute without owner signatures`, DharmaUpgradeMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, unownedSigs], + [rawData, tester.address, executorGasLimit, unownedSigs], false ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig cannot call execute with out-of-order signatures`, DharmaUpgradeMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigsOutOfOrder], + [rawData, tester.address, executorGasLimit, ownerSigsOutOfOrder], false ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig can call execute`, DharmaUpgradeMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigs] + [rawData, tester.address, executorGasLimit, ownerSigs] ) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig nonce is incremented`, DharmaUpgradeMultisig, 'getNonce', @@ -14401,7 +14402,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig can get the initial nonce`, DharmaKeyRegistryMultisig, 'getNonce', @@ -14413,7 +14414,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig can get the owners`, DharmaKeyRegistryMultisig, 'getOwners', @@ -14427,7 +14428,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig can get an owner`, DharmaKeyRegistryMultisig, 'isOwner', @@ -14439,19 +14440,19 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig returns false for a non-owner`, DharmaKeyRegistryMultisig, 'isOwner', 'call', - [address], + [tester.address], true, value => { assert.ok(!value) } ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig can get the threshold`, DharmaKeyRegistryMultisig, 'getThreshold', @@ -14463,7 +14464,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig can get the destination`, DharmaKeyRegistryMultisig, 'getDestination', @@ -14479,31 +14480,31 @@ module.exports = {test: async function (testingContext) { hashInputs = ( DharmaKeyRegistryMultisig.options.address + '0'.padStart(64, '0') + - address.slice(2) + + tester.address.slice(2) + executorGasLimit.toString(16).padStart(64, '0') + rawData.slice(2) ) hash = util.bufferToHex(util.keccak256(hashInputs)) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig can get a hash`, DharmaKeyRegistryMultisig, 'getNextHash', 'call', - [rawData, address, executorGasLimit], + [rawData, tester.address, executorGasLimit], true, value => { assert.strictEqual(value, hash) } ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig can get a hash with a specific nonce`, DharmaKeyRegistryMultisig, 'getHash', 'call', - [rawData, address, executorGasLimit, 0], + [rawData, tester.address, executorGasLimit, 0], true, value => { assert.strictEqual(value, hash) @@ -14515,72 +14516,72 @@ module.exports = {test: async function (testingContext) { ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) + ownerThreeSig.slice(2) - unownedSig = signHashedPrefixedHexString(hash, address) + unownedSig = signHashedPrefixedHexString(hash, tester.address) unownedSigs = unownedSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig cannot call execute from non-executor`, DharmaKeyRegistryMultisig, 'execute', 'send', - [rawData, addressTwo, executorGasLimit, ownerSigs], + [rawData, tester.addressTwo, executorGasLimit, ownerSigs], false ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig cannot call execute with oddly-sized signatures`, DharmaKeyRegistryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigs + '1234'], + [rawData, tester.address, executorGasLimit, ownerSigs + '1234'], false ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig cannot call execute with non-compliant signatures`, DharmaKeyRegistryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, bizarreSigs], + [rawData, tester.address, executorGasLimit, bizarreSigs], false ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig cannot call execute without enough signatures`, DharmaKeyRegistryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigs.slice(0, -130)], + [rawData, tester.address, executorGasLimit, ownerSigs.slice(0, -130)], false ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig cannot call execute without owner signatures`, DharmaKeyRegistryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, unownedSigs], + [rawData, tester.address, executorGasLimit, unownedSigs], false ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig cannot call execute with out-of-order signatures`, DharmaKeyRegistryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigsOutOfOrder], + [rawData, tester.address, executorGasLimit, ownerSigsOutOfOrder], false ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig can call execute`, DharmaKeyRegistryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigs] + [rawData, tester.address, executorGasLimit, ownerSigs] ) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig nonce is incremented`, DharmaKeyRegistryMultisig, 'getNonce', @@ -14592,7 +14593,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig can get the initial nonce`, DharmaAccountRecoveryMultisig, 'getNonce', @@ -14604,7 +14605,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig can get the owners`, DharmaAccountRecoveryMultisig, 'getOwners', @@ -14618,7 +14619,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig can get an owner`, DharmaAccountRecoveryMultisig, 'isOwner', @@ -14630,19 +14631,19 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig returns false for a non-owner`, DharmaAccountRecoveryMultisig, 'isOwner', 'call', - [address], + [tester.address], true, value => { assert.ok(!value) } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig can get the threshold`, DharmaAccountRecoveryMultisig, 'getThreshold', @@ -14654,7 +14655,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig can get the destination`, DharmaAccountRecoveryMultisig, 'getDestination', @@ -14670,31 +14671,31 @@ module.exports = {test: async function (testingContext) { hashInputs = ( DharmaAccountRecoveryMultisig.options.address + '0'.padStart(64, '0') + - address.slice(2) + + tester.address.slice(2) + executorGasLimit.toString(16).padStart(64, '0') + rawData.slice(2) ) hash = util.bufferToHex(util.keccak256(hashInputs)) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig can get a hash`, DharmaAccountRecoveryMultisig, 'getNextHash', 'call', - [rawData, address, executorGasLimit], + [rawData, tester.address, executorGasLimit], true, value => { assert.strictEqual(value, hash) } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig can get a hash with a specific nonce`, DharmaAccountRecoveryMultisig, 'getHash', 'call', - [rawData, address, executorGasLimit, 0], + [rawData, tester.address, executorGasLimit, 0], true, value => { assert.strictEqual(value, hash) @@ -14714,72 +14715,72 @@ module.exports = {test: async function (testingContext) { ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) + ownerThreeSig.slice(2) - unownedSig = signHashedPrefixedHexString(hash, address) + unownedSig = signHashedPrefixedHexString(hash, tester.address) unownedSigs = unownedSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig cannot call execute from non-executor`, DharmaAccountRecoveryMultisig, 'execute', 'send', - [rawData, addressTwo, executorGasLimit, ownerSigs], + [rawData, tester.addressTwo, executorGasLimit, ownerSigs], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig cannot call execute with oddly-sized signatures`, DharmaAccountRecoveryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigs + '1234'], + [rawData, tester.address, executorGasLimit, ownerSigs + '1234'], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig cannot call execute with non-compliant signatures`, DharmaAccountRecoveryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, bizarreSigs], + [rawData, tester.address, executorGasLimit, bizarreSigs], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig cannot call execute without enough signatures`, DharmaAccountRecoveryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerOneSig], + [rawData, tester.address, executorGasLimit, ownerOneSig], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig cannot call execute without owner signatures`, DharmaAccountRecoveryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, unownedSigs], + [rawData, tester.address, executorGasLimit, unownedSigs], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig cannot call execute with out-of-order signatures`, DharmaAccountRecoveryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigsOutOfOrder], + [rawData, tester.address, executorGasLimit, ownerSigsOutOfOrder], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig can call execute`, DharmaAccountRecoveryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigs] + [rawData, tester.address, executorGasLimit, ownerSigs] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig nonce is incremented`, DharmaAccountRecoveryMultisig, 'getNonce', @@ -14791,7 +14792,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig can get the owners`, DharmaAccountRecoveryOperatorMultisig, 'getOwners', @@ -14805,7 +14806,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig can get an owner`, DharmaAccountRecoveryOperatorMultisig, 'isOwner', @@ -14817,19 +14818,19 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig returns false for a non-owner`, DharmaAccountRecoveryOperatorMultisig, 'isOwner', 'call', - [address], + [tester.address], true, value => { assert.ok(!value) } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig can get the threshold`, DharmaAccountRecoveryOperatorMultisig, 'getThreshold', @@ -14841,7 +14842,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig can get the destination`, DharmaAccountRecoveryOperatorMultisig, 'getDestination', @@ -14857,19 +14858,19 @@ module.exports = {test: async function (testingContext) { hashInputs = ( DharmaAccountRecoveryOperatorMultisig.options.address + '0'.padStart(64, '0') + - address.slice(2) + + tester.address.slice(2) + executorGasLimit.toString(16).padStart(64, '0') + rawData.slice(2) ) hash = util.bufferToHex(util.keccak256(hashInputs)) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig can get a hash`, DharmaAccountRecoveryOperatorMultisig, 'getHash', 'call', - [rawData, address, executorGasLimit, constants.NULL_BYTES_32], + [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32], true, values => { assert.strictEqual(values.hash, hash) @@ -14888,88 +14889,88 @@ module.exports = {test: async function (testingContext) { ownerSigs = ownerOneSig + ownerTwoSig.slice(2) ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) - unownedSig = signHashedPrefixedHexString(hash, address) + unownedSig = signHashedPrefixedHexString(hash, tester.address) unownedSigs = unownedSig + ownerTwoSig.slice(2) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig cannot call execute from non-executor`, DharmaAccountRecoveryOperatorMultisig, 'execute', 'send', - [rawData, addressTwo, executorGasLimit, constants.NULL_BYTES_32, ownerSigs], + [rawData, tester.addressTwo, executorGasLimit, constants.NULL_BYTES_32, ownerSigs], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig cannot call execute with oddly-sized signatures`, DharmaAccountRecoveryOperatorMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, constants.NULL_BYTES_32, ownerSigs + '1234'], + [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32, ownerSigs + '1234'], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig cannot call execute with non-compliant signatures`, DharmaAccountRecoveryOperatorMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, constants.NULL_BYTES_32, bizarreSigs], + [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32, bizarreSigs], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig cannot call execute without enough signatures`, DharmaAccountRecoveryOperatorMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, constants.NULL_BYTES_32, ownerOneSig], + [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32, ownerOneSig], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig cannot call execute without owner signatures`, DharmaAccountRecoveryOperatorMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, constants.NULL_BYTES_32, unownedSigs], + [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32, unownedSigs], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig cannot call execute with out-of-order signatures`, DharmaAccountRecoveryOperatorMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, constants.NULL_BYTES_32, ownerSigsOutOfOrder], + [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32, ownerSigsOutOfOrder], false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig can call execute`, DharmaAccountRecoveryOperatorMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, constants.NULL_BYTES_32, ownerSigs] + [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32, ownerSigs] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryOperatorMultisig cannot replay a call to execute`, DharmaAccountRecoveryOperatorMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, constants.NULL_BYTES_32, ownerSigs], + [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32, ownerSigs], false ) - const DharmaEscapeHatchRegistry = await runTest( + const DharmaEscapeHatchRegistry = await tester.runTest( `DharmaEscapeHatchRegistry contract deployment`, DharmaEscapeHatchRegistryDeployer, '', 'deploy' ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry confirms that an escape hatch does not exist until set`, DharmaEscapeHatchRegistry, 'getEscapeHatch', @@ -14982,7 +14983,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry can set the null address as an escape hatch account`, DharmaEscapeHatchRegistry, 'setEscapeHatch', @@ -14991,15 +14992,15 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry can set an escape hatch account`, DharmaEscapeHatchRegistry, 'setEscapeHatch', 'send', - [addressTwo] + [tester.addressTwo] ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry can get an escape hatch account once set`, DharmaEscapeHatchRegistry, 'getEscapeHatch', @@ -15008,13 +15009,13 @@ module.exports = {test: async function (testingContext) { true, value => { assert.ok(value.exists) - assert.strictEqual(value.escapeHatch, addressTwo) + assert.strictEqual(value.escapeHatch, tester.addressTwo) } ) fallbackEscapeHatch = await web3.eth.call({ to: DharmaEscapeHatchRegistry.options.address, - from: address, + from: tester.address, data: "0x" }) @@ -15023,25 +15024,25 @@ module.exports = {test: async function (testingContext) { ) assert.strictEqual( web3.eth.abi.decodeParameter('address', fallbackEscapeHatch), - addressTwo + tester.addressTwo ) passed++ - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry can get an escape hatch for a specific smart wallet`, DharmaEscapeHatchRegistry, 'getEscapeHatchForSmartWallet', 'call', - [address], + [tester.address], true, value => { assert.ok(value.exists) - assert.strictEqual(value.escapeHatch, addressTwo) + assert.strictEqual(value.escapeHatch, tester.addressTwo) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry cannot get an escape hatch the null address`, DharmaEscapeHatchRegistry, 'getEscapeHatchForSmartWallet', @@ -15050,13 +15051,13 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry can remove an escape hatch account`, DharmaEscapeHatchRegistry, 'removeEscapeHatch' ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry confirms that an escape hatch is successfully removed`, DharmaEscapeHatchRegistry, 'getEscapeHatch', @@ -15071,7 +15072,7 @@ module.exports = {test: async function (testingContext) { fallbackEscapeHatch = await web3.eth.call({ to: DharmaEscapeHatchRegistry.options.address, - from: address, + from: tester.address, data: "0x" }) @@ -15084,26 +15085,26 @@ module.exports = {test: async function (testingContext) { ) passed++ - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry will not fire an event when removing an unset escape hatch account`, DharmaEscapeHatchRegistry, 'removeEscapeHatch' ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry confirms that escape hatch functionality is not initially disabled`, DharmaEscapeHatchRegistry, 'hasDisabledEscapeHatchForSmartWallet', 'call', - [address], + [tester.address], true, value => { assert.ok(!value) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry cannot get disabled status for null address`, DharmaEscapeHatchRegistry, 'hasDisabledEscapeHatchForSmartWallet', @@ -15112,7 +15113,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry can reset an escape hatch account`, DharmaEscapeHatchRegistry, 'setEscapeHatch', @@ -15120,7 +15121,7 @@ module.exports = {test: async function (testingContext) { [ownerOne] ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry can get an escape hatch account once reset`, DharmaEscapeHatchRegistry, 'getEscapeHatch', @@ -15133,7 +15134,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry setting an existing escape hatch account is a no-op`, DharmaEscapeHatchRegistry, 'setEscapeHatch', @@ -15141,26 +15142,26 @@ module.exports = {test: async function (testingContext) { [ownerOne] ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry can disable the escape hatch mechanism`, DharmaEscapeHatchRegistry, 'permanentlyDisableEscapeHatch' ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry confirms that escape hatch functionality is disabled`, DharmaEscapeHatchRegistry, 'hasDisabledEscapeHatchForSmartWallet', 'call', - [address], + [tester.address], true, value => { assert.ok(value) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry confirms that an escape hatch is successfully removed when disabling`, DharmaEscapeHatchRegistry, 'getEscapeHatch', @@ -15175,7 +15176,7 @@ module.exports = {test: async function (testingContext) { fallbackEscapeHatch = await web3.eth.call({ to: DharmaEscapeHatchRegistry.options.address, - from: address, + from: tester.address, data: "0x" }) @@ -15188,21 +15189,21 @@ module.exports = {test: async function (testingContext) { ) passed++ - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry confirms escape hatch is removed after disabling for for a specific smart wallet`, DharmaEscapeHatchRegistry, 'getEscapeHatchForSmartWallet', 'call', - [address], + [tester.address], true, value => { assert.ok(!value.exists) assert.strictEqual(value.escapeHatch, constants.NULL_ADDRESS) }, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry cannot set an escape hatch account once disabled`, DharmaEscapeHatchRegistry, 'setEscapeHatch', @@ -15211,7 +15212,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry cannot remove an escape hatch account once disabled`, DharmaEscapeHatchRegistry, 'removeEscapeHatch', @@ -15220,7 +15221,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaEscapeHatchRegistry cannot re-disable an escape hatch account once disabled`, DharmaEscapeHatchRegistry, 'permanentlyDisableEscapeHatch', @@ -15229,7 +15230,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 owner can start ownership transfer to multisig`, DharmaAccountRecoveryManagerV2, 'transferOwnership', @@ -15238,12 +15239,12 @@ module.exports = {test: async function (testingContext) { ) rawData = DharmaAccountRecoveryManagerV2.methods.acceptOwnership().encodeABI() - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig can get a hash`, DharmaAccountRecoveryMultisig, 'getNextHash', 'call', - [rawData, address, executorGasLimit], + [rawData, tester.address, executorGasLimit], true, value => { hash = value @@ -15256,15 +15257,15 @@ module.exports = {test: async function (testingContext) { ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig can call execute to accept ownership`, DharmaAccountRecoveryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigs] + [rawData, tester.address, executorGasLimit, ownerSigs] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 owner is now set to multisig`, DharmaAccountRecoveryManagerV2, 'owner', @@ -15279,13 +15280,13 @@ module.exports = {test: async function (testingContext) { // TODO: test account recovery using the multisig? // transfer ownership back - rawData = DharmaAccountRecoveryManagerV2.methods.transferOwnership(address).encodeABI() - await runTest( + rawData = DharmaAccountRecoveryManagerV2.methods.transferOwnership(tester.address).encodeABI() + await tester.runTest( `DharmaAccountRecoveryMultisig can get a hash`, DharmaAccountRecoveryMultisig, 'getNextHash', 'call', - [rawData, address, executorGasLimit], + [rawData, tester.address, executorGasLimit], true, value => { hash = value @@ -15297,21 +15298,21 @@ module.exports = {test: async function (testingContext) { ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - await runTest( + await tester.runTest( `DharmaAccountRecoveryMultisig can call execute to transfer ownership back`, DharmaAccountRecoveryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigs] + [rawData, tester.address, executorGasLimit, ownerSigs] ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 EOA can accept ownership transfer from multisig`, DharmaAccountRecoveryManagerV2, 'acceptOwnership' ) - await runTest( + await tester.runTest( `DharmaAccountRecoveryManagerV2 owner is now set to EOA`, DharmaAccountRecoveryManagerV2, 'owner', @@ -15319,11 +15320,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - await runTest( + await tester.runTest( `DharmaKeyRegistryV2 owner can start ownership transfer to multisig`, DharmaKeyRegistryV2, 'transferOwnership', @@ -15332,12 +15333,12 @@ module.exports = {test: async function (testingContext) { ) rawData = DharmaKeyRegistryV2.methods.acceptOwnership().encodeABI() - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig can get a hash`, DharmaKeyRegistryMultisig, 'getNextHash', 'call', - [rawData, address, executorGasLimit], + [rawData, tester.address, executorGasLimit], true, value => { hash = value @@ -15350,15 +15351,15 @@ module.exports = {test: async function (testingContext) { ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig can call execute to accept ownership`, DharmaKeyRegistryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigs] + [rawData, tester.address, executorGasLimit, ownerSigs] ) - await runTest( + await tester.runTest( `DharmaKeyRegistryV2 owner is now set to multisig`, DharmaKeyRegistryV2, 'owner', @@ -15373,13 +15374,13 @@ module.exports = {test: async function (testingContext) { // TODO: test setting a new key using the multisig? // transfer ownership back - rawData = DharmaKeyRegistryV2.methods.transferOwnership(address).encodeABI() - await runTest( + rawData = DharmaKeyRegistryV2.methods.transferOwnership(tester.address).encodeABI() + await tester.runTest( `DharmaKeyRegistryMultisig can get a hash`, DharmaKeyRegistryMultisig, 'getNextHash', 'call', - [rawData, address, executorGasLimit], + [rawData, tester.address, executorGasLimit], true, value => { hash = value @@ -15391,21 +15392,21 @@ module.exports = {test: async function (testingContext) { ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - await runTest( + await tester.runTest( `DharmaKeyRegistryMultisig can call execute to transfer ownership back`, DharmaKeyRegistryMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigs] + [rawData, tester.address, executorGasLimit, ownerSigs] ) - await runTest( + await tester.runTest( `DharmaKeyRegistryV2 EOA can accept ownership transfer from multisig`, DharmaKeyRegistryV2, 'acceptOwnership' ) - await runTest( + await tester.runTest( `DharmaKeyRegistryV2 owner is now set to EOA`, DharmaKeyRegistryV2, 'owner', @@ -15413,11 +15414,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager owner is initially set to an EOA`, DharmaUpgradeBeaconControllerManager, 'owner', @@ -15425,11 +15426,11 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager owner can start ownership transfer to multisig`, DharmaUpgradeBeaconControllerManager, 'transferOwnership', @@ -15438,12 +15439,12 @@ module.exports = {test: async function (testingContext) { ) rawData = DharmaUpgradeBeaconControllerManager.methods.acceptOwnership().encodeABI() - await runTest( + await tester.runTest( `DharmaUpgradeMultisig can get a hash`, DharmaUpgradeMultisig, 'getNextHash', 'call', - [rawData, address, executorGasLimit], + [rawData, tester.address, executorGasLimit], true, value => { hash = value @@ -15456,15 +15457,15 @@ module.exports = {test: async function (testingContext) { ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig can call execute to accept ownership`, DharmaUpgradeMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigs] + [rawData, tester.address, executorGasLimit, ownerSigs] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager owner is now set to multisig`, DharmaUpgradeBeaconControllerManager, 'owner', @@ -15479,13 +15480,13 @@ module.exports = {test: async function (testingContext) { // TODO: test an upgrade, rollback, etc with the multisig? // transfer ownership back - rawData = DharmaUpgradeBeaconControllerManager.methods.transferOwnership(address).encodeABI() - await runTest( + rawData = DharmaUpgradeBeaconControllerManager.methods.transferOwnership(tester.address).encodeABI() + await tester.runTest( `DharmaUpgradeMultisig can get a hash`, DharmaUpgradeMultisig, 'getNextHash', 'call', - [rawData, address, executorGasLimit], + [rawData, tester.address, executorGasLimit], true, value => { hash = value @@ -15497,21 +15498,21 @@ module.exports = {test: async function (testingContext) { ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - await runTest( + await tester.runTest( `DharmaUpgradeMultisig can call execute to transfer ownership back`, DharmaUpgradeMultisig, 'execute', 'send', - [rawData, address, executorGasLimit, ownerSigs] + [rawData, tester.address, executorGasLimit, ownerSigs] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager EOA can accept ownership transfer from multisig`, DharmaUpgradeBeaconControllerManager, 'acceptOwnership' ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager owner is now set to EOA`, DharmaUpgradeBeaconControllerManager, 'owner', @@ -15519,12 +15520,12 @@ module.exports = {test: async function (testingContext) { [], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, tester.address) } ) // Transfer smart wallet controller ownership to coverage manager - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController can transfer ownership to manager`, DharmaUpgradeBeaconController, 'transferOwnership', @@ -15532,7 +15533,7 @@ module.exports = {test: async function (testingContext) { [DharmaUpgradeBeaconControllerManagerCoverage.options.address] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when it doesn't own keyring controller`, DharmaUpgradeBeaconControllerManagerCoverage, 'activateAdharmaContingency', @@ -15541,7 +15542,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaKeyRingUpgradeBeaconController can transfer ownership to manager`, DharmaKeyRingUpgradeBeaconController, 'transferOwnership', @@ -15549,13 +15550,13 @@ module.exports = {test: async function (testingContext) { [DharmaUpgradeBeaconControllerManagerCoverage.options.address] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can activate Adharma Contingency`, DharmaUpgradeBeaconControllerManagerCoverage, 'activateAdharmaContingency' ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can get contingency status when activated`, DharmaUpgradeBeaconControllerManagerCoverage, 'contingencyStatus', @@ -15569,7 +15570,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager owner can re-arm an active Adharma Contingency`, DharmaUpgradeBeaconControllerManagerCoverage, 'armAdharmaContingency', @@ -15577,7 +15578,7 @@ module.exports = {test: async function (testingContext) { [true] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when already active`, DharmaUpgradeBeaconControllerManagerCoverage, 'activateAdharmaContingency', @@ -15586,7 +15587,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager now gets a prior implementation count`, DharmaUpgradeBeaconControllerManagerCoverage, 'getTotalPriorImplementations', @@ -15601,7 +15602,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can get the initial prior implementation`, DharmaUpgradeBeaconControllerManagerCoverage, 'getPriorImplementation', @@ -15621,19 +15622,19 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot call "exitAdharmaContingency" before 48 hours has elapsed`, DharmaUpgradeBeaconControllerManagerCoverage, 'exitAdharmaContingency', 'send', [ - address, - address + tester.address, + tester.address ], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can rollback to initial prior implementation`, DharmaUpgradeBeaconControllerManagerCoverage, 'rollback', @@ -15645,7 +15646,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager contingency status is exited after rollback`, DharmaUpgradeBeaconControllerManagerCoverage, 'contingencyStatus', @@ -15659,16 +15660,16 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot rollback to implementation with no index`, DharmaUpgradeBeaconControllerManagerCoverage, 'rollback', 'send', - [address, address, 100], + [tester.address, tester.address, 100], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager owner can re-arm an Adharma Contingency`, DharmaUpgradeBeaconControllerManagerCoverage, 'armAdharmaContingency', @@ -15676,7 +15677,7 @@ module.exports = {test: async function (testingContext) { [true] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager contingency status shows armed`, DharmaUpgradeBeaconControllerManagerCoverage, 'contingencyStatus', @@ -15690,7 +15691,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can rollback to initial prior implementation`, DharmaUpgradeBeaconControllerManagerCoverage, 'rollback', @@ -15702,7 +15703,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager contingency status shows no longer armed`, DharmaUpgradeBeaconControllerManagerCoverage, 'contingencyStatus', @@ -15716,7 +15717,7 @@ module.exports = {test: async function (testingContext) { } ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can block rollback to prior implementation`, DharmaUpgradeBeaconControllerManagerCoverage, 'blockRollback', @@ -15728,7 +15729,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot block a blocked rollback`, DharmaUpgradeBeaconControllerManagerCoverage, 'blockRollback', @@ -15741,7 +15742,7 @@ module.exports = {test: async function (testingContext) { false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot rollback to a blocked rollback`, DharmaUpgradeBeaconControllerManagerCoverage, 'rollback', @@ -15757,7 +15758,7 @@ module.exports = {test: async function (testingContext) { // advance time by 90 days await advanceTime((60 * 60 * 24 * 90) + 5) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager deadman switch can arm an Adharma Contingency`, DharmaUpgradeBeaconControllerManagerCoverage, 'armAdharmaContingency', @@ -15765,10 +15766,10 @@ module.exports = {test: async function (testingContext) { [true], true, receipt => {}, - originalAddress + tester.originalAddress ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager deadman switch can activate an Adharma Contingency`, DharmaUpgradeBeaconControllerManagerCoverage, 'activateAdharmaContingency', @@ -15776,37 +15777,37 @@ module.exports = {test: async function (testingContext) { [], true, receipt => {}, - originalAddress + tester.originalAddress ) // advance time by 2 days await advanceTime((60 * 60 * 24 * 2) + 5) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot call exitAdharmaContingency with null implementation`, DharmaUpgradeBeaconControllerManagerCoverage, 'exitAdharmaContingency', 'send', [ constants.NULL_ADDRESS, - address + tester.address ], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot call exitAdharmaContingency with non-contract implementation`, DharmaUpgradeBeaconControllerManagerCoverage, 'exitAdharmaContingency', 'send', [ - address, - address + tester.address, + tester.address ], false ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can call exitAdharmaContingency`, DharmaUpgradeBeaconControllerManagerCoverage, 'exitAdharmaContingency', @@ -15817,7 +15818,7 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can have an EOA accept controller ownership`, DharmaUpgradeBeaconControllerManagerCoverage, 'agreeToAcceptControllerOwnership', @@ -15828,14 +15829,14 @@ module.exports = {test: async function (testingContext) { ] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can initiate timelock for transferring controller ownership`, DharmaUpgradeBeaconControllerManagerCoverage, 'initiateTransferControllerOwnership', 'send', [ DharmaUpgradeBeaconController.options.address, - address, + tester.address, 0 ] ) @@ -15843,18 +15844,18 @@ module.exports = {test: async function (testingContext) { // advance time by 4 weeks await advanceTime((60 * 60 * 24 * 7 * 4) + 5) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconControllerManager can transfer controller ownership`, DharmaUpgradeBeaconControllerManagerCoverage, 'transferControllerOwnership', 'send', [ DharmaUpgradeBeaconController.options.address, - address + tester.address ] ) - await runTest( + await tester.runTest( `DharmaUpgradeBeaconController can get new owner`, DharmaUpgradeBeaconController, 'isOwner', @@ -15871,7 +15872,7 @@ module.exports = {test: async function (testingContext) { `with ${failed} failure${failed === 1 ? '' : 's'}.` ) - await longer() + await longer(); if (failed > 0) { process.exit(1) diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index f2b9d84..9720854 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -31,7 +31,7 @@ class Tester { '0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed' ); - let addressTwo = await this.setupNewDefaultAddress( + this.addressTwo = await this.setupNewDefaultAddress( '0xf00df00df00df00df00df00df00df00df00df00df00df00df00df00df00df00d' ); @@ -834,8 +834,14 @@ function newContractAndSwapMetadataHash(artifact) { return contract; } +// used to wait for more confirmations +function longer() { + return new Promise(resolve => {setTimeout(() => {resolve()}, 500)}) +} + module.exports = { Tester, swapMetadataHash, newContractAndSwapMetadataHash, + longer, }; From f0a3d90bdfbb86078ed19f1b27427f650b053798 Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Thu, 6 Feb 2020 18:52:27 -0800 Subject: [PATCH 15/47] fix revert reason helper metadata --- scripts/test/constants.js | 3 +++ scripts/test/deploy.js | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/scripts/test/constants.js b/scripts/test/constants.js index d1949c6..7bf8075 100644 --- a/scripts/test/constants.js +++ b/scripts/test/constants.js @@ -330,6 +330,9 @@ module.exports = Object.freeze({ '20204b657952696e6755706772616465426561636f6e50726f78795631202020' ] ), + REVERT_REASON_HELPER_METADATA: [ + "373389197482e319656922b5cf379766d403a45bdb1776717726e0d125834166" + ], KEY_RING_FACTORY_V2_ADDRESS: ( '0x2484000059004afB720000dc738434fA6200F49D' ), diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index 2a26c62..70da750 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -871,14 +871,24 @@ async function test(testingContext) { ImmutableCreate2Factory ); - + // RevertReasonHelper + const revertReasonHelperRuntimeCode = swapMetadataHash( + SmartWalletRevertReasonHelperV1Artifact.deployedBytecode, + constants.REVERT_REASON_HELPER_METADATA + ); + + const revertReasonHelperCreationCode = swapMetadataHash( + SmartWalletRevertReasonHelperV1Artifact.bytecode, + constants.REVERT_REASON_HELPER_METADATA + ); + await tester.checkAndDeploy( "RevertReasonHelper", constants.REVERT_REASON_HELPER_ADDRESS, constants.NULL_BYTES_32, - SmartWalletRevertReasonHelperV1Artifact.deployedBytecode, - SmartWalletRevertReasonHelperV1Artifact.bytecode, + revertReasonHelperRuntimeCode, + revertReasonHelperCreationCode, MockCodeCheck, ImmutableCreate2Factory ); @@ -1923,7 +1933,7 @@ async function test(testingContext) { ) if (tester.failed > 0) { - // process.exit(1) + process.exit(1) } // exit. From c48870fb2d36aada9c9745ce645bc03252f0ea8b Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Thu, 6 Feb 2020 19:16:26 -0800 Subject: [PATCH 16/47] remove all helpers from test.js --- scripts/test/deploy.js | 2 +- scripts/test/test.js | 1069 ++++++++++------------------------- scripts/test/testHelpers.js | 5 +- 3 files changed, 311 insertions(+), 765 deletions(-) diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index 70da750..741a013 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -871,7 +871,7 @@ async function test(testingContext) { ImmutableCreate2Factory ); - + // RevertReasonHelper const revertReasonHelperRuntimeCode = swapMetadataHash( SmartWalletRevertReasonHelperV1Artifact.deployedBytecode, diff --git a/scripts/test/test.js b/scripts/test/test.js index a63b44f..b0e9357 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -55,12 +55,7 @@ const ComptrollerArtifact = require('../../build/contracts/ComptrollerInterface. const contractNames = Object.assign({}, constants.CONTRACT_NAMES) -module.exports = {test: async function (testingContext) { - let passed = 0 - let failed = 0 - let gasUsage = {} - let counts = {} - +async function test(testingContext) { const DharmaUpgradeBeaconController = new web3.eth.Contract( DharmaUpgradeBeaconControllerArtifact.abi, constants.UPGRADE_BEACON_CONTROLLER_ADDRESS @@ -381,461 +376,8 @@ module.exports = {test: async function (testingContext) { const tester = new Tester(testingContext); await tester.init(); - // get available addresses and assign them to various roles - const addresses = await web3.eth.getAccounts() - if (addresses.length < 1) { - console.log('cannot find enough addresses to run tests!') - process.exit(1) - } - - let latestBlock = await web3.eth.getBlock('latest') - - const originalAddress = addresses[0] - - let address = await setupNewDefaultAddress( - '0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed' - ) - - let addressTwo = await setupNewDefaultAddress( - '0xf00df00df00df00df00df00df00df00df00df00df00df00df00df00df00df00d' - ) - - let initialControllerOwner = await setupNewDefaultAddress( - '0x58e0348ce225c18ece7f2d6a069afa340365019481903b221481706d291a66bf' - ) - - const ownerOne = await setupNewDefaultAddress( - constants.MOCK_OWNER_PRIVATE_KEYS[0] - ) - const ownerTwo = await setupNewDefaultAddress( - constants.MOCK_OWNER_PRIVATE_KEYS[1] - ) - const ownerThree = await setupNewDefaultAddress( - constants.MOCK_OWNER_PRIVATE_KEYS[2] - ) - const ownerFour = await setupNewDefaultAddress( - constants.MOCK_OWNER_PRIVATE_KEYS[3] - ) - const ownerFive = await setupNewDefaultAddress( - constants.MOCK_OWNER_PRIVATE_KEYS[4] - ) - - const gasLimit = latestBlock.gasLimit - console.log('running tests...') - // ************************** helper functions **************************** // - async function send( - title, - instance, - method, - args, - from, - value, - gas, - gasPrice, - shouldSucceed, - assertionCallback - ) { - const receipt = await instance.methods[method](...args).send({ - from: from, - value: value, - gas: gas, - gasPrice: gasPrice - }).on('confirmation', (confirmationNumber, r) => { - confirmations[r.transactionHash] = confirmationNumber - }).catch(error => { - if (shouldSucceed) { - console.error(error) - } - return {status: false} - }) - - if (receipt.status !== shouldSucceed) { - return false - } else if (!shouldSucceed) { - return true - } - - let assertionsPassed - try { - assertionCallback(receipt) - assertionsPassed = true - } catch(error) { - assertionsPassed = false - console.log(error); - } - - return assertionsPassed - } - - async function call( - title, - instance, - method, - args, - from, - value, - gas, - gasPrice, - shouldSucceed, - assertionCallback - ) { - let succeeded = true - returnValues = await instance.methods[method](...args).call({ - from: from, - value: value, - gas: gas, - gasPrice: gasPrice - }).catch(error => { - if (shouldSucceed) { - console.error(error) - } - succeeded = false - }) - - if (succeeded !== shouldSucceed) { - return false - } else if (!shouldSucceed) { - return true - } - - let assertionsPassed - try { - assertionCallback(returnValues) - assertionsPassed = true - } catch(error) { - assertionsPassed = false - console.log(error); - } - - return assertionsPassed - } - - async function deploy( - title, - instance, - args, - from, - value, - gas, - gasPrice, - shouldSucceed, - assertionCallback - ) { - let deployData = instance.deploy({arguments: args}).encodeABI() - let deployGas = await web3.eth.estimateGas({ - from: from, - data: deployData - }).catch(error => { - if (shouldSucceed) { - console.error(error) - } - return gasLimit - }) - - if (deployGas > gasLimit) { - console.error(` ✘ ${title}: deployment costs exceed block gas limit!`) - process.exit(1) - } - - if (typeof(gas) === 'undefined') { - gas = deployGas - } - - if (deployGas > gas) { - console.error(` ✘ ${title}: deployment costs exceed supplied gas.`) - process.exit(1) - } - - let signed - let deployHash - let receipt - const contract = await instance.deploy({arguments: args}).send({ - from: from, - gas: gas, - gasPrice: gasPrice - }).on('transactionHash', hash => { - deployHash = hash - }).on('receipt', r => { - receipt = r - }).on('confirmation', (confirmationNumber, r) => { - confirmations[r.transactionHash] = confirmationNumber - }).catch(error => { - if (shouldSucceed) { - console.error(error) - } - - receipt = {status: false} - }) - - if (receipt.status !== shouldSucceed) { - if (contract) { - return [false, contract, gas] - } - return [false, instance, gas] - } else if (!shouldSucceed) { - if (contract) { - return [true, contract, gas] - } - return [true, instance, gas] - } - - assert.ok(receipt.status) - - let assertionsPassed - try { - assertionCallback(receipt) - assertionsPassed = true - } catch(error) { - assertionsPassed = false - } - - if (contract) { - return [assertionsPassed, contract, gas] - } - return [assertionsPassed, instance, gas] - } - - async function runTest( - title, - instance, - method, - callOrSend, - args, - shouldSucceed, - assertionCallback, - from, - value, - gas - ) { - if (typeof(callOrSend) === 'undefined') { - callOrSend = 'send' - } - if (typeof(args) === 'undefined') { - args = [] - } - if (typeof(shouldSucceed) === 'undefined') { - shouldSucceed = true - } - if (typeof(assertionCallback) === 'undefined') { - assertionCallback = (value) => {} - } - if (typeof(from) === 'undefined') { - from = tester.address - } - if (typeof(value) === 'undefined') { - value = 0 - } - if (typeof(gas) === 'undefined' && callOrSend !== 'deploy') { - gas = 6009006 - if (testingContext === 'coverage') { - gas = gasLimit - 1 - } - } - let ok = false - let contract - let deployGas - if (callOrSend === 'send') { - ok = await send( - title, - instance, - method, - args, - from, - value, - gas, - 1, - shouldSucceed, - assertionCallback - ) - } else if (callOrSend === 'call') { - ok = await call( - title, - instance, - method, - args, - from, - value, - gas, - 1, - shouldSucceed, - assertionCallback - ) - } else if (callOrSend === 'deploy') { - const fields = await deploy( - title, - instance, - args, - from, - value, - gas, - 1, - shouldSucceed, - assertionCallback - ) - ok = fields[0] - contract = fields[1] - deployGas = fields[2] - } else { - console.error('must use call, send, or deploy!') - process.exit(1) - } - - if (ok) { - console.log( - ` ✓ ${ - callOrSend === 'deploy' ? 'successful ' : '' - }${title}${ - callOrSend === 'deploy' ? ` (${deployGas} gas)` : '' - }` - ) - passed++ - } else { - console.log( - ` ✘ ${ - callOrSend === 'deploy' ? 'failed ' : '' - }${title}${ - callOrSend === 'deploy' ? ` (${deployGas} gas)` : '' - }` - ) - failed++ - } - - if (contract) { - return contract - } - } - - async function setupNewDefaultAddress(newPrivateKey) { - const pubKey = await web3.eth.accounts.privateKeyToAccount(newPrivateKey) - await web3.eth.accounts.wallet.add(pubKey) - - await web3.eth.sendTransaction({ - from: tester.originalAddress, - to: pubKey.address, - value: 2 * 10 ** 18, - gas: '0x5208', - gasPrice: '0x4A817C800' - }) - - return pubKey.address - } - - // async function raiseGasLimit(necessaryGas) { - // iterations = 9999 - // if (necessaryGas > 8000000) { - // console.error('the gas needed is too high!') - // process.exit(1) - // } else if (typeof necessaryGas === 'undefined') { - // iterations = 20 - // necessaryGas = 8000000 - // } - // - // // bring up gas limit if necessary by doing additional transactions - // var block = await web3.eth.getBlock("latest") - // while (iterations > 0 && block.gasLimit < necessaryGas) { - // await web3.eth.sendTransaction({ - // from: tester.originalAddress, - // to: tester.originalAddress, - // value: '0x01', - // gas: '0x5208', - // gasPrice: '0x4A817C800' - // }) - // var block = await web3.eth.getBlock("latest") - // iterations-- - // } - // - // console.log("raising gasLimit, currently at " + block.gasLimit) - // return block.gasLimit - // } - - // async function getDeployGas(dataPayload) { - // await web3.eth.estimateGas({ - // from: tester.address, - // data: dataPayload - // }).catch(async error => { - // if ( - // error.message === ( - // 'Returned error: gas required exceeds allowance or always failing ' + - // 'transaction' - // ) - // ) { - // await raiseGasLimit() - // await getDeployGas(dataPayload) - // } - // }) - // - // deployGas = await web3.eth.estimateGas({ - // from: tester.address, - // data: dataPayload - // }) - // - // return deployGas - // } - - function signHashedPrefixedHexString(hashedHexString, account) { - const hashedPrefixedMessage = web3.utils.keccak256( - // prefix => "\x19Ethereum Signed Message:\n32" - "0x19457468657265756d205369676e6564204d6573736167653a0a3332" + - hashedHexString.slice(2), - {encoding: "hex"} - ) - - const sig = util.ecsign( - util.toBuffer(hashedPrefixedMessage), - util.toBuffer(web3.eth.accounts.wallet[account].privateKey) - ) - - return ( - util.bufferToHex(sig.r) + - util.bufferToHex(sig.s).slice(2) + - web3.utils.toHex(sig.v).slice(2) - ) - } - - function signHashedPrefixedHashedHexString(hexString, account) { - const hashedPrefixedHashedMessage = web3.utils.keccak256( - // prefix => "\x19Ethereum Signed Message:\n32" - "0x19457468657265756d205369676e6564204d6573736167653a0a3332" + - web3.utils.keccak256(hexString, {encoding: "hex"}).slice(2), - {encoding: "hex"} - ) - - const sig = util.ecsign( - util.toBuffer(hashedPrefixedHashedMessage), - util.toBuffer(web3.eth.accounts.wallet[account].privateKey) - ) - - return ( - util.bufferToHex(sig.r) + - util.bufferToHex(sig.s).slice(2) + - web3.utils.toHex(sig.v).slice(2) - ) - } - - async function advanceTime(time) { - await web3.currentProvider.send( - { - jsonrpc: '2.0', - method: 'evm_increaseTime', - params: [time], - id: new Date().getTime() - }, - (err, result) => { - if (err) { - console.error(err) - } else { - console.log(' ✓ advanced time by', time, 'seconds') - } - } - ) - } - - // *************************** deploy contracts *************************** // - let deployGas - let selfAddress - await tester.runTest( `DharmaUpgradeBeaconController can transfer owner`, DharmaUpgradeBeaconController, @@ -906,9 +448,9 @@ module.exports = {test: async function (testingContext) { ).slice(2) ) - const newKeySignature = signHashedPrefixedHashedHexString(message, tester.address) + const newKeySignature = tester.signHashedPrefixedHashedHexString(message, tester.address) - const badNewKeySignature = signHashedPrefixedHashedHexString('0x12', tester.address) + const badNewKeySignature = tester.signHashedPrefixedHashedHexString('0x12', tester.address) await tester.runTest( 'Dharma Key Registry V1 cannot set a new global key unless called by owner', @@ -1050,7 +592,7 @@ module.exports = {test: async function (testingContext) { ).slice(2) ) - const v2KeySignature = signHashedPrefixedHashedHexString(messageV2, tester.address) + const v2KeySignature = tester.signHashedPrefixedHashedHexString(messageV2, tester.address) await tester.runTest( 'Dharma Key Registry V2 cannot set a previously used global key', @@ -1409,8 +951,8 @@ module.exports = {test: async function (testingContext) { if (!currentSaiCode) { console.log( - `completed ${passed + failed} test${passed + failed === 1 ? '' : 's'} ` + - `with ${failed} failure${failed === 1 ? '' : 's'}.` + `completed ${tester.passed + tester.failed} test${tester.passed + tester.failed === 1 ? '' : 's'} ` + + `with ${tester.failed} failure${tester.failed === 1 ? '' : 's'}.` ) console.log( @@ -1418,7 +960,7 @@ module.exports = {test: async function (testingContext) { 'run against a fork of mainnet using `yarn forkStart` and `yarn test`.' ) - if (failed > 0) { + if (tester.failed > 0) { process.exit(1) } @@ -1506,7 +1048,7 @@ module.exports = {test: async function (testingContext) { from: tester.address, to: constants.ETH_WHALE_ADDRESS, value: web3.utils.toWei('.2', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : gasLimit - 1, + gas: (testingContext !== 'coverage') ? '0x5208' : tester.gasLimit - 1, gasPrice: 1 }) console.log(' ✓ Eth Whale can receive eth if needed') @@ -1517,7 +1059,7 @@ module.exports = {test: async function (testingContext) { from: tester.address, to: constants.SAI_WHALE_ADDRESS, value: web3.utils.toWei('.1', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : gasLimit - 1, + gas: (testingContext !== 'coverage') ? '0x5208' : tester.gasLimit - 1, gasPrice: 1 }) console.log(' ✓ Sai Whale can receive eth if needed') @@ -1528,7 +1070,7 @@ module.exports = {test: async function (testingContext) { from: tester.address, to: constants.USDC_WHALE_ADDRESS, value: web3.utils.toWei('.1', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : gasLimit - 1, + gas: (testingContext !== 'coverage') ? '0x5208' : tester.gasLimit - 1, gasPrice: 1 }) console.log(' ✓ USDC Whale can receive eth if needed') @@ -1538,7 +1080,7 @@ module.exports = {test: async function (testingContext) { from: constants.ETH_WHALE_ADDRESS, to: targetWalletAddress, value: web3.utils.toWei('.1', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : gasLimit - 1, + gas: (testingContext !== 'coverage') ? '0x5208' : tester.gasLimit - 1, gasPrice: 1 }) console.log(' ✓ Eth Whale can deposit eth into the yet-to-be-deployed smart wallet') @@ -1710,7 +1252,7 @@ module.exports = {test: async function (testingContext) { from: constants.ETH_WHALE_ADDRESS, to: targetWalletAddress, value: web3.utils.toWei('100', 'ether'), - gas: (testingContext !== 'coverage') ? '0xffff' : gasLimit - 1, + gas: (testingContext !== 'coverage') ? '0xffff' : tester.gasLimit - 1, gasPrice: 1 }).catch(error => { console.log(' ✓ Eth Whale can no longer deposit eth into the deployed smart wallet') @@ -2094,7 +1636,7 @@ module.exports = {test: async function (testingContext) { } ) - let usdcWithdrawalSignature = signHashedPrefixedHexString( + let usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) @@ -2152,7 +1694,7 @@ module.exports = {test: async function (testingContext) { address.slice(2) // recipient ) - const saiWithdrawalSignature = signHashedPrefixedHashedHexString( + const saiWithdrawalSignature = tester.signHashedPrefixedHashedHexString( withdrawalMessage, address ) @@ -2263,7 +1805,7 @@ module.exports = {test: async function (testingContext) { } ) - let saiWithdrawalSignature = signHashedPrefixedHexString( + let saiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) @@ -2869,12 +2411,12 @@ module.exports = {test: async function (testingContext) { } ) - let executeActionSignature = signHashedPrefixedHexString( + let executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - let executeActionUserSignature = signHashedPrefixedHexString( + let executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -2910,12 +2452,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -2978,12 +2520,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -3133,12 +2675,12 @@ module.exports = {test: async function (testingContext) { } ) - let setUserSigningKeyUserSignature = signHashedPrefixedHexString( + let setUserSigningKeyUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) - let setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( + let setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) @@ -3206,7 +2748,7 @@ module.exports = {test: async function (testingContext) { } ) - let cancelUserSignature = signHashedPrefixedHexString( + let cancelUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -3298,12 +2840,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - let usdcUserWithdrawalSignature = signHashedPrefixedHexString( + let usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -3345,12 +2887,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -3392,12 +2934,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -3439,12 +2981,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -3522,7 +3064,7 @@ module.exports = {test: async function (testingContext) { address.slice(2) // recipient ) - const saiWithdrawalSignature = signHashedPrefixedHashedHexString( + const saiWithdrawalSignature = tester.signHashedPrefixedHashedHexString( withdrawalMessage, address ) @@ -3545,12 +3087,12 @@ module.exports = {test: async function (testingContext) { } ) - saiWithdrawalSignature = signHashedPrefixedHexString( + saiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - let saiUserWithdrawalSignature = signHashedPrefixedHexString( + let saiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -3589,12 +3131,12 @@ module.exports = {test: async function (testingContext) { } ) - saiWithdrawalSignature = signHashedPrefixedHexString( + saiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - saiUserWithdrawalSignature = signHashedPrefixedHexString( + saiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -3633,12 +3175,12 @@ module.exports = {test: async function (testingContext) { } ) - saiWithdrawalSignature = signHashedPrefixedHexString( + saiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - saiUserWithdrawalSignature = signHashedPrefixedHexString( + saiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -3709,12 +3251,12 @@ module.exports = {test: async function (testingContext) { } ) - saiWithdrawalSignature = signHashedPrefixedHexString( + saiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - saiUserWithdrawalSignature = signHashedPrefixedHexString( + saiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -3795,12 +3337,12 @@ module.exports = {test: async function (testingContext) { } ) - let ethWithdrawalSignature = signHashedPrefixedHexString( + let ethWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - let ethUserWithdrawalSignature = signHashedPrefixedHexString( + let ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -3841,12 +3383,12 @@ module.exports = {test: async function (testingContext) { } ) - ethWithdrawalSignature = signHashedPrefixedHexString( + ethWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - ethUserWithdrawalSignature = signHashedPrefixedHexString( + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -3887,12 +3429,12 @@ module.exports = {test: async function (testingContext) { } ) - ethWithdrawalSignature = signHashedPrefixedHexString( + ethWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - ethUserWithdrawalSignature = signHashedPrefixedHexString( + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -3973,12 +3515,12 @@ module.exports = {test: async function (testingContext) { } ) - ethWithdrawalSignature = signHashedPrefixedHexString( + ethWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - ethUserWithdrawalSignature = signHashedPrefixedHexString( + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -4096,7 +3638,7 @@ module.exports = {test: async function (testingContext) { } ) - let cancelSignature = signHashedPrefixedHexString(customActionId, tester.addressTwo) + let cancelSignature = tester.signHashedPrefixedHexString(customActionId, tester.addressTwo) await tester.runTest( 'V5 UserSmartWallet can cancel using a signature', @@ -4183,12 +3725,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -4280,12 +3822,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -4564,12 +4106,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -4648,12 +4190,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -4696,12 +4238,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -4742,12 +4284,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -4790,12 +4332,12 @@ module.exports = {test: async function (testingContext) { } ) - ethWithdrawalSignature = signHashedPrefixedHexString( + ethWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - ethUserWithdrawalSignature = signHashedPrefixedHexString( + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -4877,12 +4419,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -4918,12 +4460,12 @@ module.exports = {test: async function (testingContext) { } ) - saiWithdrawalSignature = signHashedPrefixedHexString( + saiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - saiUserWithdrawalSignature = signHashedPrefixedHexString( + saiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -4965,12 +4507,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -5016,12 +4558,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -5066,12 +4608,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -5140,12 +4682,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -5185,12 +4727,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -5231,12 +4773,12 @@ module.exports = {test: async function (testingContext) { } ) - saiWithdrawalSignature = signHashedPrefixedHexString( + saiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - saiUserWithdrawalSignature = signHashedPrefixedHexString( + saiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -5292,7 +4834,7 @@ module.exports = {test: async function (testingContext) { ) // advance time by 3 days - await advanceTime((60 * 60 * 24 * 3) + 5) + await tester.advanceTime((60 * 60 * 24 * 3) + 5) // recover account await tester.runTest( @@ -5478,7 +5020,7 @@ module.exports = {test: async function (testingContext) { } ) - setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( + setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) @@ -5617,7 +5159,7 @@ module.exports = {test: async function (testingContext) { from: tester.address, to: constants.DAI_WHALE_ADDRESS, value: web3.utils.toWei('1', 'ether'), - gas: (testingContext !== 'coverage') ? '0xffff' : gasLimit - 1, + gas: (testingContext !== 'coverage') ? '0xffff' : tester.gasLimit - 1, gasPrice: 1 }) @@ -5689,12 +5231,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -5812,12 +5354,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -5853,12 +5395,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -5921,12 +5463,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -6018,12 +5560,12 @@ module.exports = {test: async function (testingContext) { } ) - setUserSigningKeyUserSignature = signHashedPrefixedHexString( + setUserSigningKeyUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) - setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( + setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) @@ -6091,12 +5633,12 @@ module.exports = {test: async function (testingContext) { } ) - setUserSigningKeyUserSignature = signHashedPrefixedHexString( + setUserSigningKeyUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) - setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( + setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) @@ -6164,7 +5706,7 @@ module.exports = {test: async function (testingContext) { } ) - cancelUserSignature = signHashedPrefixedHexString( + cancelUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -6256,12 +5798,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -6303,12 +5845,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -6350,12 +5892,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -6397,12 +5939,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -6480,7 +6022,7 @@ module.exports = {test: async function (testingContext) { address.slice(2) // recipient ) - const saiWithdrawalSignature = signHashedPrefixedHashedHexString( + const saiWithdrawalSignature = tester.signHashedPrefixedHashedHexString( withdrawalMessage, address ) @@ -6503,12 +6045,12 @@ module.exports = {test: async function (testingContext) { } ) - let daiWithdrawalSignature = signHashedPrefixedHexString( + let daiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - let daiUserWithdrawalSignature = signHashedPrefixedHexString( + let daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -6547,12 +6089,12 @@ module.exports = {test: async function (testingContext) { } ) - daiWithdrawalSignature = signHashedPrefixedHexString( + daiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - daiUserWithdrawalSignature = signHashedPrefixedHexString( + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -6591,12 +6133,12 @@ module.exports = {test: async function (testingContext) { } ) - daiWithdrawalSignature = signHashedPrefixedHexString( + daiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - daiUserWithdrawalSignature = signHashedPrefixedHexString( + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -6667,12 +6209,12 @@ module.exports = {test: async function (testingContext) { } ) - daiWithdrawalSignature = signHashedPrefixedHexString( + daiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - daiUserWithdrawalSignature = signHashedPrefixedHexString( + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -6753,12 +6295,12 @@ module.exports = {test: async function (testingContext) { } ) - ethWithdrawalSignature = signHashedPrefixedHexString( + ethWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - ethUserWithdrawalSignature = signHashedPrefixedHexString( + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -6799,12 +6341,12 @@ module.exports = {test: async function (testingContext) { } ) - ethWithdrawalSignature = signHashedPrefixedHexString( + ethWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - ethUserWithdrawalSignature = signHashedPrefixedHexString( + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -6845,12 +6387,12 @@ module.exports = {test: async function (testingContext) { } ) - ethWithdrawalSignature = signHashedPrefixedHexString( + ethWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - ethUserWithdrawalSignature = signHashedPrefixedHexString( + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -6931,12 +6473,12 @@ module.exports = {test: async function (testingContext) { } ) - ethWithdrawalSignature = signHashedPrefixedHexString( + ethWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - ethUserWithdrawalSignature = signHashedPrefixedHexString( + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -7054,7 +6596,7 @@ module.exports = {test: async function (testingContext) { } ) - cancelSignature = signHashedPrefixedHexString(customActionId, tester.addressTwo) + cancelSignature = tester.signHashedPrefixedHexString(customActionId, tester.addressTwo) await tester.runTest( 'V6 UserSmartWallet can cancel using a signature', @@ -7141,12 +6683,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -7238,12 +6780,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -7484,12 +7026,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -7568,12 +7110,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -7616,12 +7158,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -7662,12 +7204,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -7710,12 +7252,12 @@ module.exports = {test: async function (testingContext) { } ) - ethWithdrawalSignature = signHashedPrefixedHexString( + ethWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - ethUserWithdrawalSignature = signHashedPrefixedHexString( + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -7796,12 +7338,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -7837,12 +7379,12 @@ module.exports = {test: async function (testingContext) { } ) - daiWithdrawalSignature = signHashedPrefixedHexString( + daiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - daiUserWithdrawalSignature = signHashedPrefixedHexString( + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -7884,12 +7426,12 @@ module.exports = {test: async function (testingContext) { } ) - daiWithdrawalSignature = signHashedPrefixedHexString( + daiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - daiUserWithdrawalSignature = signHashedPrefixedHexString( + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -7931,12 +7473,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -7981,12 +7523,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -8031,12 +7573,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -8105,12 +7647,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -8151,12 +7693,12 @@ module.exports = {test: async function (testingContext) { } ) - let escapeHatchSignature = signHashedPrefixedHexString( + let escapeHatchSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - let escapeHatchUserSignature = signHashedPrefixedHexString( + let escapeHatchUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -8338,7 +7880,7 @@ module.exports = {test: async function (testingContext) { } ) - setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( + setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) @@ -8477,7 +8019,7 @@ module.exports = {test: async function (testingContext) { from: tester.address, to: constants.DAI_WHALE_ADDRESS, value: web3.utils.toWei('1', 'ether'), - gas: (testingContext !== 'coverage') ? '0xffff' : gasLimit - 1, + gas: (testingContext !== 'coverage') ? '0xffff' : tester.gasLimit - 1, gasPrice: 1 }) @@ -8549,12 +8091,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -8627,12 +8169,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -8668,12 +8210,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -8720,12 +8262,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -8785,12 +8327,12 @@ module.exports = {test: async function (testingContext) { } ) - setUserSigningKeyUserSignature = signHashedPrefixedHexString( + setUserSigningKeyUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) - setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( + setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) @@ -8858,12 +8400,12 @@ module.exports = {test: async function (testingContext) { } ) - setUserSigningKeyUserSignature = signHashedPrefixedHexString( + setUserSigningKeyUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) - setUserSigningKeyDharmaSignature = signHashedPrefixedHexString( + setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) @@ -8931,7 +8473,7 @@ module.exports = {test: async function (testingContext) { } ) - cancelUserSignature = signHashedPrefixedHexString( + cancelUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -9023,12 +8565,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -9070,12 +8612,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -9117,12 +8659,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -9164,12 +8706,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -9247,7 +8789,7 @@ module.exports = {test: async function (testingContext) { address.slice(2) // recipient ) - const saiWithdrawalSignature = signHashedPrefixedHashedHexString( + const saiWithdrawalSignature = tester.signHashedPrefixedHashedHexString( withdrawalMessage, address ) @@ -9270,12 +8812,12 @@ module.exports = {test: async function (testingContext) { } ) - daiWithdrawalSignature = signHashedPrefixedHexString( + daiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - daiUserWithdrawalSignature = signHashedPrefixedHexString( + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -9314,12 +8856,12 @@ module.exports = {test: async function (testingContext) { } ) - daiWithdrawalSignature = signHashedPrefixedHexString( + daiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - daiUserWithdrawalSignature = signHashedPrefixedHexString( + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -9358,12 +8900,12 @@ module.exports = {test: async function (testingContext) { } ) - daiWithdrawalSignature = signHashedPrefixedHexString( + daiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - daiUserWithdrawalSignature = signHashedPrefixedHexString( + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -9434,12 +8976,12 @@ module.exports = {test: async function (testingContext) { } ) - daiWithdrawalSignature = signHashedPrefixedHexString( + daiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - daiUserWithdrawalSignature = signHashedPrefixedHexString( + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -9520,12 +9062,12 @@ module.exports = {test: async function (testingContext) { } ) - ethWithdrawalSignature = signHashedPrefixedHexString( + ethWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - ethUserWithdrawalSignature = signHashedPrefixedHexString( + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -9566,12 +9108,12 @@ module.exports = {test: async function (testingContext) { } ) - ethWithdrawalSignature = signHashedPrefixedHexString( + ethWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - ethUserWithdrawalSignature = signHashedPrefixedHexString( + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -9612,12 +9154,12 @@ module.exports = {test: async function (testingContext) { } ) - ethWithdrawalSignature = signHashedPrefixedHexString( + ethWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - ethUserWithdrawalSignature = signHashedPrefixedHexString( + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -9698,12 +9240,12 @@ module.exports = {test: async function (testingContext) { } ) - ethWithdrawalSignature = signHashedPrefixedHexString( + ethWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - ethUserWithdrawalSignature = signHashedPrefixedHexString( + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -9821,7 +9363,7 @@ module.exports = {test: async function (testingContext) { } ) - cancelSignature = signHashedPrefixedHexString(customActionId, tester.addressTwo) + cancelSignature = tester.signHashedPrefixedHexString(customActionId, tester.addressTwo) await tester.runTest( 'V7 UserSmartWallet can cancel using a signature', @@ -9908,12 +9450,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -10005,12 +9547,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -10220,12 +9762,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -10304,12 +9846,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -10352,12 +9894,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -10398,12 +9940,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -10446,12 +9988,12 @@ module.exports = {test: async function (testingContext) { } ) - ethWithdrawalSignature = signHashedPrefixedHexString( + ethWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - ethUserWithdrawalSignature = signHashedPrefixedHexString( + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -10532,12 +10074,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -10573,12 +10115,12 @@ module.exports = {test: async function (testingContext) { } ) - daiWithdrawalSignature = signHashedPrefixedHexString( + daiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - daiUserWithdrawalSignature = signHashedPrefixedHexString( + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -10620,12 +10162,12 @@ module.exports = {test: async function (testingContext) { } ) - daiWithdrawalSignature = signHashedPrefixedHexString( + daiWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - daiUserWithdrawalSignature = signHashedPrefixedHexString( + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -10667,12 +10209,12 @@ module.exports = {test: async function (testingContext) { } ) - usdcWithdrawalSignature = signHashedPrefixedHexString( + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - usdcUserWithdrawalSignature = signHashedPrefixedHexString( + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -10717,12 +10259,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -10767,12 +10309,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -10841,12 +10383,12 @@ module.exports = {test: async function (testingContext) { } ) - executeActionSignature = signHashedPrefixedHexString( + executeActionSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - executeActionUserSignature = signHashedPrefixedHexString( + executeActionUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -10890,12 +10432,12 @@ module.exports = {test: async function (testingContext) { } ) - escapeHatchSignature = signHashedPrefixedHexString( + escapeHatchSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - escapeHatchUserSignature = signHashedPrefixedHexString( + escapeHatchUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -10935,12 +10477,12 @@ module.exports = {test: async function (testingContext) { } ) - escapeHatchSignature = signHashedPrefixedHexString( + escapeHatchSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - escapeHatchUserSignature = signHashedPrefixedHexString( + escapeHatchUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -11031,12 +10573,12 @@ module.exports = {test: async function (testingContext) { } ) - escapeHatchSignature = signHashedPrefixedHexString( + escapeHatchSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - escapeHatchUserSignature = signHashedPrefixedHexString( + escapeHatchUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -11087,12 +10629,12 @@ module.exports = {test: async function (testingContext) { } ) - escapeHatchSignature = signHashedPrefixedHexString( + escapeHatchSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - escapeHatchUserSignature = signHashedPrefixedHexString( + escapeHatchUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -11131,12 +10673,12 @@ module.exports = {test: async function (testingContext) { } ) - escapeHatchSignature = signHashedPrefixedHexString( + escapeHatchSignature = tester.signHashedPrefixedHexString( customActionId, tester.address ) - escapeHatchUserSignature = signHashedPrefixedHexString( + escapeHatchUserSignature = tester.signHashedPrefixedHexString( customActionId, tester.addressTwo ) @@ -11276,7 +10818,7 @@ module.exports = {test: async function (testingContext) { ) // advance time by 3 days - await advanceTime((60 * 60 * 24 * 3) + 5) + await tester.advanceTime((60 * 60 * 24 * 3) + 5) // recover account await tester.runTest( @@ -11543,7 +11085,7 @@ module.exports = {test: async function (testingContext) { false ) - const takeAdminActionSignature = signHashedPrefixedHexString( + const takeAdminActionSignature = tester.signHashedPrefixedHexString( adminActionID, tester.address ) @@ -11895,9 +11437,9 @@ module.exports = {test: async function (testingContext) { ).slice(2) ) - const newKeySignatureCoverage = signHashedPrefixedHashedHexString(messageCoverage, tester.addressTwo) + const newKeySignatureCoverage = tester.signHashedPrefixedHashedHexString(messageCoverage, tester.addressTwo) - const badNewKeySignatureCoverage = signHashedPrefixedHashedHexString('0x12', tester.addressTwo) + const badNewKeySignatureCoverage = tester.signHashedPrefixedHashedHexString('0x12', tester.addressTwo) await tester.runTest( 'Dharma Key Registry V2 cannot set a new global key unless called by owner', @@ -12138,7 +11680,7 @@ module.exports = {test: async function (testingContext) { ).slice(2) ) - const v2KeySignatureCoverage = signHashedPrefixedHashedHexString(messageV2Coverage, tester.address) + const v2KeySignatureCoverage = tester.signHashedPrefixedHashedHexString(messageV2Coverage, tester.address) await tester.runTest( 'Dharma Key Registry V2 cannot set a previously used global key', @@ -12535,7 +12077,7 @@ module.exports = {test: async function (testingContext) { ) // advance time by 3 days - await advanceTime((60 * 60 * 24 * 3) + 5) + await tester.advanceTime((60 * 60 * 24 * 3) + 5) await tester.runTest( `DharmaAccountRecoveryManagerV2 can call recover after timelock completion`, @@ -12775,7 +12317,7 @@ module.exports = {test: async function (testingContext) { ) // advance time by 2 weeks - await advanceTime((60 * 60 * 24 * 7 * 2) + 5) + await tester.advanceTime((60 * 60 * 24 * 7 * 2) + 5) await tester.runTest( `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery after timelock expiration`, @@ -13184,7 +12726,7 @@ module.exports = {test: async function (testingContext) { ) // advance time by 2 weeks - await advanceTime((60 * 60 * 24 * 7 * 2) + 5) + await tester.advanceTime((60 * 60 * 24 * 7 * 2) + 5) await tester.runTest( `DharmaAccountRecoveryManagerV2 can call modifyTimelockInterval`, @@ -13325,7 +12867,7 @@ module.exports = {test: async function (testingContext) { ) // advance time by 7 days - await advanceTime((60 * 60 * 24 * 7) + 5) + await tester.advanceTime((60 * 60 * 24 * 7) + 5) await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot upgrade an unowned controller`, @@ -13407,7 +12949,7 @@ module.exports = {test: async function (testingContext) { ) // advance time by 4 weeks - await advanceTime((60 * 60 * 24 * 7 * 4) + 5) + await tester.advanceTime((60 * 60 * 24 * 7 * 4) + 5) await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot transfer unowned controller ownership`, @@ -13581,7 +13123,7 @@ module.exports = {test: async function (testingContext) { ) // advance time by 2 days - await advanceTime((60 * 60 * 24 * 2) + 5) + await tester.advanceTime((60 * 60 * 24 * 2) + 5) await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot exit Contingency to null address`, @@ -13850,7 +13392,7 @@ module.exports = {test: async function (testingContext) { ) // advance time by 4 weeks - await advanceTime((60 * 60 * 24 * 7 * 4) + 5) + await tester.advanceTime((60 * 60 * 24 * 7 * 4) + 5) await tester.runTest( `DharmaUpgradeBeaconControllerManager can call modifyTimelockInterval`, @@ -14174,7 +13716,7 @@ module.exports = {test: async function (testingContext) { DharmaUpgradeMultisigDeployer, '', 'deploy', - [[ownerOne, ownerTwo, ownerThree, ownerFour, ownerFive]] + [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] ) const DharmaAccountRecoveryMultisig = await tester.runTest( @@ -14182,7 +13724,7 @@ module.exports = {test: async function (testingContext) { DharmaAccountRecoveryMultisigDeployer, '', 'deploy', - [[ownerOne, ownerTwo, ownerThree, ownerFour]] + [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour]] ) const DharmaAccountRecoveryOperatorMultisig = await tester.runTest( @@ -14190,7 +13732,7 @@ module.exports = {test: async function (testingContext) { DharmaAccountRecoveryOperatorMultisigDeployer, '', 'deploy', - [[ownerOne, ownerTwo, ownerThree, ownerFour]] + [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour]] ) const DharmaKeyRegistryMultisig = await tester.runTest( @@ -14198,7 +13740,7 @@ module.exports = {test: async function (testingContext) { DharmaKeyRegistryMultisigDeployer, '', 'deploy', - [[ownerOne, ownerTwo, ownerThree, ownerFour, ownerFive]] + [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] ) rawData = '0x' @@ -14232,7 +13774,7 @@ module.exports = {test: async function (testingContext) { true, value => { assert.deepEqual( - value, [ownerOne, ownerTwo, ownerThree, ownerFour, ownerFive] + value, [tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive] ) } ) @@ -14242,7 +13784,7 @@ module.exports = {test: async function (testingContext) { DharmaUpgradeMultisig, 'isOwner', 'call', - [ownerOne], + [tester.ownerOne], true, value => { assert.ok(value) @@ -14320,12 +13862,12 @@ module.exports = {test: async function (testingContext) { } ) - ownerOneSig = signHashedPrefixedHexString(hash, ownerOne) - ownerTwoSig = signHashedPrefixedHexString(hash, ownerTwo) - ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) + ownerThreeSig.slice(2) - unownedSig = signHashedPrefixedHexString(hash, tester.address) + unownedSig = tester.signHashedPrefixedHexString(hash, tester.address) unownedSigs = unownedSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) await tester.runTest( @@ -14423,7 +13965,7 @@ module.exports = {test: async function (testingContext) { true, value => { assert.deepEqual( - value, [ownerOne, ownerTwo, ownerThree, ownerFour, ownerFive] + value, [tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive] ) } ) @@ -14433,7 +13975,7 @@ module.exports = {test: async function (testingContext) { DharmaKeyRegistryMultisig, 'isOwner', 'call', - [ownerOne], + [tester.ownerOne], true, value => { assert.ok(value) @@ -14511,12 +14053,12 @@ module.exports = {test: async function (testingContext) { } ) - ownerOneSig = signHashedPrefixedHexString(hash, ownerOne) - ownerTwoSig = signHashedPrefixedHexString(hash, ownerTwo) - ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) + ownerThreeSig.slice(2) - unownedSig = signHashedPrefixedHexString(hash, tester.address) + unownedSig = tester.signHashedPrefixedHexString(hash, tester.address) unownedSigs = unownedSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) await tester.runTest( @@ -14614,7 +14156,7 @@ module.exports = {test: async function (testingContext) { true, value => { assert.deepEqual( - value, [ownerOne, ownerTwo, ownerThree, ownerFour] + value, [tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour] ) } ) @@ -14624,7 +14166,7 @@ module.exports = {test: async function (testingContext) { DharmaAccountRecoveryMultisig, 'isOwner', 'call', - [ownerOne], + [tester.ownerOne], true, value => { assert.ok(value) @@ -14702,20 +14244,20 @@ module.exports = {test: async function (testingContext) { } ) - ownerOneSig = signHashedPrefixedHexString(hash, ownerOne) - ownerTwoSig = signHashedPrefixedHexString(hash, ownerTwo) - ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) /* ownerSigs = ownerOneSig + ownerTwoSig.slice(2) ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) - unownedSig = signHashedPrefixedHexString(hash, address) + unownedSig = tester.signHashedPrefixedHexString(hash, address) unownedSigs = unownedSig + ownerTwoSig.slice(2) */ ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) + ownerThreeSig.slice(2) - unownedSig = signHashedPrefixedHexString(hash, tester.address) + unownedSig = tester.signHashedPrefixedHexString(hash, tester.address) unownedSigs = unownedSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) await tester.runTest( @@ -14801,7 +14343,7 @@ module.exports = {test: async function (testingContext) { true, value => { assert.deepEqual( - value, [ownerOne, ownerTwo, ownerThree, ownerFour] + value, [tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour] ) } ) @@ -14811,7 +14353,7 @@ module.exports = {test: async function (testingContext) { DharmaAccountRecoveryOperatorMultisig, 'isOwner', 'call', - [ownerOne], + [tester.ownerOne], true, value => { assert.ok(value) @@ -14877,19 +14419,19 @@ module.exports = {test: async function (testingContext) { } ) - ownerOneSig = signHashedPrefixedHexString(hash, ownerOne) - ownerTwoSig = signHashedPrefixedHexString(hash, ownerTwo) + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) /* ownerSigs = ownerOneSig + ownerTwoSig.slice(2) ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) - unownedSig = signHashedPrefixedHexString(hash, address) + unownedSig = tester.signHashedPrefixedHexString(hash, address) unownedSigs = unownedSig + ownerTwoSig.slice(2) */ ownerSigs = ownerOneSig + ownerTwoSig.slice(2) ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) - unownedSig = signHashedPrefixedHexString(hash, tester.address) + unownedSig = tester.signHashedPrefixedHexString(hash, tester.address) unownedSigs = unownedSig + ownerTwoSig.slice(2) await tester.runTest( @@ -15026,7 +14568,7 @@ module.exports = {test: async function (testingContext) { web3.eth.abi.decodeParameter('address', fallbackEscapeHatch), tester.addressTwo ) - passed++ + tester.passed++ await tester.runTest( `DharmaEscapeHatchRegistry can get an escape hatch for a specific smart wallet`, @@ -15083,7 +14625,7 @@ module.exports = {test: async function (testingContext) { web3.eth.abi.decodeParameter('address', fallbackEscapeHatch), constants.NULL_ADDRESS ) - passed++ + tester.passed++ await tester.runTest( `DharmaEscapeHatchRegistry will not fire an event when removing an unset escape hatch account`, @@ -15118,7 +14660,7 @@ module.exports = {test: async function (testingContext) { DharmaEscapeHatchRegistry, 'setEscapeHatch', 'send', - [ownerOne] + [tester.ownerOne] ) await tester.runTest( @@ -15130,7 +14672,7 @@ module.exports = {test: async function (testingContext) { true, value => { assert.ok(value.exists) - assert.strictEqual(value.escapeHatch, ownerOne) + assert.strictEqual(value.escapeHatch, tester.ownerOne) } ) @@ -15139,7 +14681,7 @@ module.exports = {test: async function (testingContext) { DharmaEscapeHatchRegistry, 'setEscapeHatch', 'send', - [ownerOne] + [tester.ownerOne] ) await tester.runTest( @@ -15187,7 +14729,7 @@ module.exports = {test: async function (testingContext) { web3.eth.abi.decodeParameter('address', fallbackEscapeHatch), constants.NULL_ADDRESS ) - passed++ + tester.passed++ await tester.runTest( `DharmaEscapeHatchRegistry confirms escape hatch is removed after disabling for for a specific smart wallet`, @@ -15208,7 +14750,7 @@ module.exports = {test: async function (testingContext) { DharmaEscapeHatchRegistry, 'setEscapeHatch', 'send', - [ownerTwo], + [tester.ownerTwo], false ) @@ -15252,9 +14794,9 @@ module.exports = {test: async function (testingContext) { ) // accept ownership - ownerOneSig = signHashedPrefixedHexString(hash, ownerOne) - ownerTwoSig = signHashedPrefixedHexString(hash, ownerTwo) - ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) await tester.runTest( @@ -15293,9 +14835,9 @@ module.exports = {test: async function (testingContext) { } ) - ownerOneSig = signHashedPrefixedHexString(hash, ownerOne) - ownerTwoSig = signHashedPrefixedHexString(hash, ownerTwo) - ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) await tester.runTest( @@ -15346,9 +14888,9 @@ module.exports = {test: async function (testingContext) { ) // accept ownership - ownerOneSig = signHashedPrefixedHexString(hash, ownerOne) - ownerTwoSig = signHashedPrefixedHexString(hash, ownerTwo) - ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) await tester.runTest( @@ -15387,9 +14929,9 @@ module.exports = {test: async function (testingContext) { } ) - ownerOneSig = signHashedPrefixedHexString(hash, ownerOne) - ownerTwoSig = signHashedPrefixedHexString(hash, ownerTwo) - ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) await tester.runTest( @@ -15452,9 +14994,9 @@ module.exports = {test: async function (testingContext) { ) // accept ownership - ownerOneSig = signHashedPrefixedHexString(hash, ownerOne) - ownerTwoSig = signHashedPrefixedHexString(hash, ownerTwo) - ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) await tester.runTest( @@ -15493,9 +15035,9 @@ module.exports = {test: async function (testingContext) { } ) - ownerOneSig = signHashedPrefixedHexString(hash, ownerOne) - ownerTwoSig = signHashedPrefixedHexString(hash, ownerTwo) - ownerThreeSig = signHashedPrefixedHexString(hash, ownerThree) + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) await tester.runTest( @@ -15756,7 +15298,7 @@ module.exports = {test: async function (testingContext) { ) // advance time by 90 days - await advanceTime((60 * 60 * 24 * 90) + 5) + await tester.advanceTime((60 * 60 * 24 * 90) + 5) await tester.runTest( `DharmaUpgradeBeaconControllerManager deadman switch can arm an Adharma Contingency`, @@ -15781,7 +15323,7 @@ module.exports = {test: async function (testingContext) { ) // advance time by 2 days - await advanceTime((60 * 60 * 24 * 2) + 5) + await tester.advanceTime((60 * 60 * 24 * 2) + 5) await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot call exitAdharmaContingency with null implementation`, @@ -15842,7 +15384,7 @@ module.exports = {test: async function (testingContext) { ) // advance time by 4 weeks - await advanceTime((60 * 60 * 24 * 7 * 4) + 5) + await tester.advanceTime((60 * 60 * 24 * 7 * 4) + 5) await tester.runTest( `DharmaUpgradeBeaconControllerManager can transfer controller ownership`, @@ -15868,17 +15410,20 @@ module.exports = {test: async function (testingContext) { ) console.log( - `completed ${passed + failed} test${passed + failed === 1 ? '' : 's'} ` + - `with ${failed} failure${failed === 1 ? '' : 's'}.` + `completed ${tester.passed + tester.failed} test${tester.passed + tester.failed === 1 ? '' : 's'} ` + + `with ${tester.failed} failure${tester.failed === 1 ? '' : 's'}.` ) await longer(); - if (failed > 0) { + if (tester.failed > 0) { process.exit(1) } // exit. return 0 -}} +} +module.exports = { + test, +}; diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index 9720854..db464a6 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -1,6 +1,7 @@ const { web3 } = require("./web3"); const constants = require("./constants"); const assert = require("assert"); +const util = require('ethereumjs-util'); const SCALING_FACTOR = web3.utils.toBN("1000000000000000000"); const ZERO = web3.utils.toBN("0"); @@ -86,8 +87,8 @@ class Tester { let block = await web3.eth.getBlock("latest"); while (iterations > 0 && block.gasLimit < necessaryGas) { await web3.eth.sendTransaction({ - from: originalAddress, - to: originalAddress, + from: this.originalAddress, + to: this.originalAddress, value: "0x01", gas: "0x5208", gasPrice: "0x4A817C800" From 5626874a6eb81fff483a33221232375568bbbf43 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Fri, 7 Feb 2020 09:44:20 -0500 Subject: [PATCH 17/47] move account recovery tests to new file --- .../testAccountRecoveryManager.js | 885 +++++++++++++++++ scripts/test/test.js | 893 +----------------- 2 files changed, 896 insertions(+), 882 deletions(-) create mode 100644 scripts/test/contracts/account-recovery/testAccountRecoveryManager.js diff --git a/scripts/test/contracts/account-recovery/testAccountRecoveryManager.js b/scripts/test/contracts/account-recovery/testAccountRecoveryManager.js new file mode 100644 index 0000000..cdf6aa9 --- /dev/null +++ b/scripts/test/contracts/account-recovery/testAccountRecoveryManager.js @@ -0,0 +1,885 @@ +const constants = require("../../constants"); +const assert = require("assert"); + +async function testAccountRecoveryManager(tester, contract, smartWalletAddress) { + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot transfer ownership from a non-owner`, + contract, + 'transferOwnership', + 'send', + [tester.addressTwo], + false, + receipt => {}, + tester.originalAddress + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot initiate recovery with null smart wallet`, + contract, + 'initiateAccountRecovery', + 'send', + [constants.NULL_ADDRESS, tester.addressTwo, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot initiate recovery with null new key`, + contract, + 'initiateAccountRecovery', + 'send', + [tester.address, constants.NULL_ADDRESS, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can initiate recovery timelock`, + contract, + 'initiateAccountRecovery', + 'send', + [constants.UPGRADE_BEACON_ADDRESS, tester.addressTwo, 0] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can initiate another recovery timelock`, + contract, + 'initiateAccountRecovery', + 'send', + [smartWalletAddress, tester.addressTwo, 0] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can initiate a third recovery timelock`, + contract, + 'initiateAccountRecovery', + 'send', + [tester.address, tester.addressTwo, 0] + ) + + await tester.runTest( + 'smart wallet account recovery cannot be cancelled with no smart wallet', + contract, + 'cancelAccountRecovery', + 'send', + [ + constants.NULL_ADDRESS, + tester.addressTwo + ], + false + ) + + await tester.runTest( + 'smart wallet account recovery cannot be cancelled with no user signing key', + contract, + 'cancelAccountRecovery', + 'send', + [ + tester.address, + constants.NULL_ADDRESS + ], + false + ) + + await tester.runTest( + 'smart wallet account recovery can be cancelled', + contract, + 'cancelAccountRecovery', + 'send', + [ + tester.address, + tester.addressTwo + ], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ) + + await tester.runTest( + 'smart wallet account recovery cannot be cancelled if it is already cancelled', + contract, + 'cancelAccountRecovery', + 'send', + [ + tester.address, + tester.addressTwo + ], + false + ) + + await tester.runTest( + 'smart wallet account recovery cannot be cancelled if no timelock exists', + contract, + 'cancelAccountRecovery', + 'send', + [ + tester.addressTwo, + tester.addressTwo + ], + false + ) + + + await tester.runTest( + 'smart wallet account recovery can be reinitiated', + contract, + 'initiateAccountRecovery', + 'send', + [ + tester.address, + tester.addressTwo, + 1 // extraTime in seconds - add one to ensure that timelock is extended + ], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot initiate recovery disablement with null smart wallet`, + contract, + 'initiateAccountRecoveryDisablement', + 'send', + [constants.NULL_ADDRESS, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can initiate recovery disablement timelock`, + contract, + 'initiateAccountRecoveryDisablement', + 'send', + [tester.address, 0] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call recover with null new key`, + contract, + 'recover', + 'send', + [constants.NULL_ADDRESS, tester.addressTwo], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call recover with null new key`, + contract, + 'recover', + 'send', + [tester.address, constants.NULL_ADDRESS], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call recover prior to timelock completion`, + contract, + 'recover', + 'send', + [constants.UPGRADE_BEACON_ADDRESS, tester.addressTwo], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery prior to timelock completion`, + contract, + 'disableAccountRecovery', + 'send', + [tester.address], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check if account recovery is disabled`, + contract, + 'accountRecoveryDisabled', + 'call', + [tester.address], + true, + value => { + assert.ok(!value) + } + ) + + // advance time by 3 days + await tester.advanceTime((60 * 60 * 24 * 3) + 5) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call recover after timelock completion`, + contract, + 'recover', + 'send', + [constants.UPGRADE_BEACON_ADDRESS, tester.addressTwo] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot recover an unowned smart wallet`, + contract, + 'recover', + 'send', + [smartWalletAddress, tester.addressTwo], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot recover an EOA`, + contract, + 'recover', + 'send', + [tester.address, tester.addressTwo], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery with null smart wallet`, + contract, + 'disableAccountRecovery', + 'send', + [constants.NULL_ADDRESS], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call disableAccountRecovery after timelock completion`, + contract, + 'disableAccountRecovery', + 'send', + [tester.address] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check if account recovery is disabled`, + contract, + 'accountRecoveryDisabled', + 'call', + [tester.address], + true, + value => { + assert.ok(value) + } + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot recover an account that has disabled recovery`, + contract, + 'recover', + 'send', + [tester.address, tester.addressTwo], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval with no selector`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0x00000000', 0, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval to modify interval over 8 weeks`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0xe950c085', 5443200, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0xe950c085', 10000, 0] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock on another function`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0xaaaaaaaa', 10000, 0] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval with no selector`, + contract, + 'modifyTimelockInterval', + 'send', + ['0x00000000', 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval before timelock completion`, + contract, + 'modifyTimelockInterval', + 'send', + ['0xe950c085', 1000], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration with no selector`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0x00000000', 0, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to with expiration over one month`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0xe950c085', 5443200, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to modify expiration under one minute`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0xd7ce3c6f', 30, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to modify expiration under one hour`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0xd7ce3c6f', 3000, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0xd7ce3c6f', 30000, 0], + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock on another function`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0xaaaaaaaa', 300000, 0] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration with no selector`, + contract, + 'modifyTimelockExpiration', + 'send', + ['0x00000000', 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration before timelock completion`, + contract, + 'modifyTimelockExpiration', + 'send', + ['0xd7ce3c6f', 300], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can initiate recovery disablement timelock`, + contract, + 'initiateAccountRecoveryDisablement', + 'send', + [tester.addressTwo, 0] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot cancel disablement with null address`, + contract, + 'cancelAccountRecoveryDisablement', + 'send', + [constants.NULL_ADDRESS], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can cancel recovery disablement timelock`, + contract, + 'cancelAccountRecoveryDisablement', + 'send', + [tester.addressTwo] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can re-initiate recovery disablement timelock`, + contract, + 'initiateAccountRecoveryDisablement', + 'send', + [tester.addressTwo, 1] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot shorten a timelock`, + contract, + 'initiateAccountRecoveryDisablement', + 'send', + [tester.addressTwo, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot initiate recovery with massive extraTime`, + contract, + 'initiateAccountRecovery', + 'send', + [tester.address, tester.addressTwo, constants.FULL_APPROVAL], + false + ) + + // advance time by 2 weeks + await tester.advanceTime((60 * 60 * 24 * 7 * 2) + 5) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery after timelock expiration`, + contract, + 'disableAccountRecovery', + 'send', + [tester.addressTwo], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot set a role to the null tester.address`, + contract, + 'setRole', + 'send', + [0, constants.NULL_ADDRESS], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can set a role`, + contract, + 'setRole', + 'send', + [0, tester.address] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can set a role that is already set`, + contract, + 'setRole', + 'send', + [0, tester.address] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check if the caller has a role`, + contract, + 'isRole', + 'call', + [0], + true, + value => { + assert.ok(value) + } + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check for an operator role`, + contract, + 'getOperator', + 'call', + [], + true, + value => { + assert.strictEqual(value, tester.address) + } + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check for a recoverer role`, + contract, + 'getRecoverer', + 'call', + [], + true, + value => { + assert.strictEqual(value, constants.NULL_ADDRESS) + } + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check for a canceller role`, + contract, + 'getCanceller', + 'call', + [], + true, + value => { + assert.strictEqual(value, constants.NULL_ADDRESS) + } + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check for a disabler role`, + contract, + 'getDisabler', + 'call', + [], + true, + value => { + assert.strictEqual(value, constants.NULL_ADDRESS) + } + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check for a pauser role`, + contract, + 'getPauser', + 'call', + [], + true, + value => { + assert.strictEqual(value, constants.NULL_ADDRESS) + } + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can remove a role`, + contract, + 'removeRole', + 'send', + [0] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check if the caller has a role`, + contract, + 'isRole', + 'call', + [0], + true, + value => { + assert.ok(!value) + } + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check if a role is paused`, + contract, + 'isPaused', + 'call', + [0], + true, + value => { + assert.ok(!value) + } + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot pause a role if not owner or pauser`, + contract, + 'pause', + 'send', + [0], + false, + receipt => {}, + tester.addressTwo + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can set a role`, + contract, + 'setRole', + 'send', + [4, tester.addressTwo] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot unpause an unpaused role`, + contract, + 'unpause', + 'send', + [0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can pause an unpaused role`, + contract, + 'pause', + 'send', + [0], + true, + receipt => {}, + tester.addressTwo + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot pause a paused role`, + contract, + 'pause', + 'send', + [0], + false, + receipt => {}, + tester.addressTwo + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can pause the pauser role`, + contract, + 'pause', + 'send', + [4] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 pauser cannot call a paused role`, + contract, + 'pause', + 'send', + [4], + false, + receipt => {}, + tester.addressTwo + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check if a role is paused`, + contract, + 'isPaused', + 'call', + [0], + true, + value => { + assert.ok(value) + } + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can unpause a paused role`, + contract, + 'unpause', + 'send', + [0] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can get an empty timelock`, + contract, + 'getTimelock', + 'call', + ['0x01020304', '0x'], + true, + value => { + assert.ok(!value.exists) + assert.ok(!value.completed) + assert.ok(!value.expired) + assert.strictEqual(value.completionTime, '0') + assert.strictEqual(value.expirationTime, '0') + } + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can get an empty default timelock interval`, + contract, + 'getDefaultTimelockInterval', + 'call', + ['0x01020304'], + true, + value => { + assert.strictEqual(value, '0') + } + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can get an empty default timelock expiration`, + contract, + 'getDefaultTimelockExpiration', + 'call', + ['0x01020304'], + true, + value => { + assert.strictEqual(value, '0') + } + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval with no selector`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0x00000000', 0, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval to modify interval over 8 weeks`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0xe950c085', 5443200, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot create timelock with excessive duration`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0xe950c085', constants.FULL_APPROVAL, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0xe950c085', 10000, 5] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot shorten existing initiateModifyTimelockInterval timelock`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0xe950c085', 10000, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to change a duration`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0xe950c085', 10001, 5] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock on another function`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0xaaaaaaaa', 10000, 0] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval with no selector`, + contract, + 'modifyTimelockInterval', + 'send', + ['0x00000000', 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval before timelock completion`, + contract, + 'modifyTimelockInterval', + 'send', + ['0xe950c085', 1000], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration with no selector`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0x00000000', 0, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to with expiration over one month`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0xe950c085', 5443200, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to modify expiration under one minute`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0xd7ce3c6f', 30, 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0xd7ce3c6f', 300000, 0], + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock on another function`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0xe950c085', 30, 0] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration with no selector`, + contract, + 'modifyTimelockExpiration', + 'send', + ['0x00000000', 0], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration before timelock completion`, + contract, + 'modifyTimelockExpiration', + 'send', + ['0xd7ce3c6f', 300], + false + ) + + // advance time by 2 weeks + await tester.advanceTime((60 * 60 * 24 * 7 * 2) + 5) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call modifyTimelockInterval`, + contract, + 'modifyTimelockInterval', + 'send', + ['0xaaaaaaaa', 10000] + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call modifyTimelockExpiration`, + contract, + 'modifyTimelockExpiration', + 'send', + ['0xd7ce3c6f', 300000], + ) + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration if expiration is too short`, + contract, + 'modifyTimelockExpiration', + 'send', + ['0xe950c085', 30], + false + ) +} + +module.exports = { + testAccountRecoveryManager +}; \ No newline at end of file diff --git a/scripts/test/test.js b/scripts/test/test.js index b0e9357..c457733 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -4,6 +4,7 @@ var util = require('ethereumjs-util') const constants = require('./constants.js') const { web3 } = require("./web3"); const { Tester, longer } = require("./testHelpers"); +const { testAccountRecoveryManager } = require("./contracts/account-recovery/testAccountRecoveryManager"); const AdharmaSmartWalletImplementationArtifact = require('../../build/contracts/AdharmaSmartWalletImplementation.json') const AdharmaKeyRingImplementationArtifact = require('../../build/contracts/AdharmaKeyRingImplementation.json') @@ -10854,13 +10855,6 @@ async function test(testingContext) { 'deploy' ) - const DharmaAccountRecoveryManagerV2Coverage = await tester.runTest( - `DharmaAccountRecoveryManagerV2 contract deployment`, - DharmaAccountRecoveryManagerV2Deployer, - '', - 'deploy' - ) - const DharmaKeyRegistryV2Coverage = await tester.runTest( `DharmaKeyRegistryV2 contract deployment`, DharmaKeyRegistryV2Deployer, @@ -11875,883 +11869,18 @@ async function test(testingContext) { 'renounceOwnership' ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot transfer ownership from a non-owner`, - DharmaAccountRecoveryManagerV2Coverage, - 'transferOwnership', - 'send', - [tester.addressTwo], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot initiate recovery with null smart wallet`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateAccountRecovery', - 'send', - [constants.NULL_ADDRESS, tester.addressTwo, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot initiate recovery with null new key`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateAccountRecovery', - 'send', - [tester.address, constants.NULL_ADDRESS, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can initiate recovery timelock`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateAccountRecovery', - 'send', - [constants.UPGRADE_BEACON_ADDRESS, tester.addressTwo, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can initiate another recovery timelock`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateAccountRecovery', - 'send', - [UserSmartWalletV6.options.address, tester.addressTwo, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can initiate a third recovery timelock`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateAccountRecovery', - 'send', - [tester.address, tester.addressTwo, 0] - ) - - await tester.runTest( - 'smart wallet account recovery cannot be cancelled with no smart wallet', - DharmaAccountRecoveryManagerV2Coverage, - 'cancelAccountRecovery', - 'send', - [ - constants.NULL_ADDRESS, - tester.addressTwo - ], - false - ) - - await tester.runTest( - 'smart wallet account recovery cannot be cancelled with no user signing key', - DharmaAccountRecoveryManagerV2Coverage, - 'cancelAccountRecovery', - 'send', - [ - tester.address, - constants.NULL_ADDRESS - ], - false - ) - - await tester.runTest( - 'smart wallet account recovery can be cancelled', - DharmaAccountRecoveryManagerV2Coverage, - 'cancelAccountRecovery', - 'send', - [ - tester.address, - tester.addressTwo - ], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - 'smart wallet account recovery cannot be cancelled if it is already cancelled', - DharmaAccountRecoveryManagerV2Coverage, - 'cancelAccountRecovery', - 'send', - [ - tester.address, - tester.addressTwo - ], - false - ) - - await tester.runTest( - 'smart wallet account recovery cannot be cancelled if no timelock exists', - DharmaAccountRecoveryManagerV2Coverage, - 'cancelAccountRecovery', - 'send', - [ - tester.addressTwo, - tester.addressTwo - ], - false - ) - - - await tester.runTest( - 'smart wallet account recovery can be reinitiated', - DharmaAccountRecoveryManagerV2Coverage, - 'initiateAccountRecovery', - 'send', - [ - tester.address, - tester.addressTwo, - 1 // extraTime in seconds - add one to ensure that timelock is extended - ], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot initiate recovery disablement with null smart wallet`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateAccountRecoveryDisablement', - 'send', - [constants.NULL_ADDRESS, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can initiate recovery disablement timelock`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateAccountRecoveryDisablement', - 'send', - [tester.address, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call recover with null new key`, - DharmaAccountRecoveryManagerV2Coverage, - 'recover', - 'send', - [constants.NULL_ADDRESS, tester.addressTwo], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call recover with null new key`, - DharmaAccountRecoveryManagerV2Coverage, - 'recover', - 'send', - [tester.address, constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call recover prior to timelock completion`, - DharmaAccountRecoveryManagerV2Coverage, - 'recover', - 'send', - [constants.UPGRADE_BEACON_ADDRESS, tester.addressTwo], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery prior to timelock completion`, - DharmaAccountRecoveryManagerV2Coverage, - 'disableAccountRecovery', - 'send', - [tester.address], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check if account recovery is disabled`, - DharmaAccountRecoveryManagerV2Coverage, - 'accountRecoveryDisabled', - 'call', - [tester.address], - true, - value => { - assert.ok(!value) - } - ) - - // advance time by 3 days - await tester.advanceTime((60 * 60 * 24 * 3) + 5) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call recover after timelock completion`, - DharmaAccountRecoveryManagerV2Coverage, - 'recover', - 'send', - [constants.UPGRADE_BEACON_ADDRESS, tester.addressTwo] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot recover an unowned smart wallet`, - DharmaAccountRecoveryManagerV2Coverage, - 'recover', - 'send', - [UserSmartWalletV6.options.address, tester.addressTwo], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot recover an EOA`, - DharmaAccountRecoveryManagerV2Coverage, - 'recover', - 'send', - [tester.address, tester.addressTwo], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery with null smart wallet`, - DharmaAccountRecoveryManagerV2Coverage, - 'disableAccountRecovery', - 'send', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call disableAccountRecovery after timelock completion`, - DharmaAccountRecoveryManagerV2Coverage, - 'disableAccountRecovery', - 'send', - [tester.address] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check if account recovery is disabled`, - DharmaAccountRecoveryManagerV2Coverage, - 'accountRecoveryDisabled', - 'call', - [tester.address], - true, - value => { - assert.ok(value) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot recover an account that has disabled recovery`, - DharmaAccountRecoveryManagerV2Coverage, - 'recover', - 'send', - [tester.address, tester.addressTwo], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval with no selector`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockInterval', - 'send', - ['0x00000000', 0, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval to modify interval over 8 weeks`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 5443200, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 10000, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock on another function`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockInterval', - 'send', - ['0xaaaaaaaa', 10000, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval with no selector`, - DharmaAccountRecoveryManagerV2Coverage, - 'modifyTimelockInterval', - 'send', - ['0x00000000', 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval before timelock completion`, - DharmaAccountRecoveryManagerV2Coverage, - 'modifyTimelockInterval', - 'send', - ['0xe950c085', 1000], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration with no selector`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0x00000000', 0, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to with expiration over one month`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0xe950c085', 5443200, 0], - false + const DharmaAccountRecoveryManagerV2Coverage = await tester.runTest( + `DharmaAccountRecoveryManagerV2 contract deployment`, + DharmaAccountRecoveryManagerV2Deployer, + '', + 'deploy' ) - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to modify expiration under one minute`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 30, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to modify expiration under one hour`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 3000, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 30000, 0], - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock on another function`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0xaaaaaaaa', 300000, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration with no selector`, - DharmaAccountRecoveryManagerV2Coverage, - 'modifyTimelockExpiration', - 'send', - ['0x00000000', 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration before timelock completion`, - DharmaAccountRecoveryManagerV2Coverage, - 'modifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 300], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can initiate recovery disablement timelock`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateAccountRecoveryDisablement', - 'send', - [tester.addressTwo, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot cancel disablement with null address`, - DharmaAccountRecoveryManagerV2Coverage, - 'cancelAccountRecoveryDisablement', - 'send', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can cancel recovery disablement timelock`, - DharmaAccountRecoveryManagerV2Coverage, - 'cancelAccountRecoveryDisablement', - 'send', - [tester.addressTwo] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can re-initiate recovery disablement timelock`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateAccountRecoveryDisablement', - 'send', - [tester.addressTwo, 1] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot shorten a timelock`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateAccountRecoveryDisablement', - 'send', - [tester.addressTwo, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot initiate recovery with massive extraTime`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateAccountRecovery', - 'send', - [tester.address, tester.addressTwo, constants.FULL_APPROVAL], - false - ) - - // advance time by 2 weeks - await tester.advanceTime((60 * 60 * 24 * 7 * 2) + 5) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery after timelock expiration`, - DharmaAccountRecoveryManagerV2Coverage, - 'disableAccountRecovery', - 'send', - [tester.addressTwo], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot set a role to the null tester.address`, - DharmaAccountRecoveryManagerV2Coverage, - 'setRole', - 'send', - [0, constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can set a role`, - DharmaAccountRecoveryManagerV2Coverage, - 'setRole', - 'send', - [0, tester.address] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can set a role that is already set`, - DharmaAccountRecoveryManagerV2Coverage, - 'setRole', - 'send', - [0, tester.address] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check if the caller has a role`, - DharmaAccountRecoveryManagerV2Coverage, - 'isRole', - 'call', - [0], - true, - value => { - assert.ok(value) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check for an operator role`, - DharmaAccountRecoveryManagerV2Coverage, - 'getOperator', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check for a recoverer role`, - DharmaAccountRecoveryManagerV2Coverage, - 'getRecoverer', - 'call', - [], - true, - value => { - assert.strictEqual(value, constants.NULL_ADDRESS) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check for a canceller role`, - DharmaAccountRecoveryManagerV2Coverage, - 'getCanceller', - 'call', - [], - true, - value => { - assert.strictEqual(value, constants.NULL_ADDRESS) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check for a disabler role`, - DharmaAccountRecoveryManagerV2Coverage, - 'getDisabler', - 'call', - [], - true, - value => { - assert.strictEqual(value, constants.NULL_ADDRESS) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check for a pauser role`, - DharmaAccountRecoveryManagerV2Coverage, - 'getPauser', - 'call', - [], - true, - value => { - assert.strictEqual(value, constants.NULL_ADDRESS) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can remove a role`, - DharmaAccountRecoveryManagerV2Coverage, - 'removeRole', - 'send', - [0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check if the caller has a role`, - DharmaAccountRecoveryManagerV2Coverage, - 'isRole', - 'call', - [0], - true, - value => { - assert.ok(!value) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check if a role is paused`, - DharmaAccountRecoveryManagerV2Coverage, - 'isPaused', - 'call', - [0], - true, - value => { - assert.ok(!value) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot pause a role if not owner or pauser`, - DharmaAccountRecoveryManagerV2Coverage, - 'pause', - 'send', - [0], - false, - receipt => {}, - tester.addressTwo - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can set a role`, - DharmaAccountRecoveryManagerV2Coverage, - 'setRole', - 'send', - [4, tester.addressTwo] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot unpause an unpaused role`, - DharmaAccountRecoveryManagerV2Coverage, - 'unpause', - 'send', - [0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can pause an unpaused role`, - DharmaAccountRecoveryManagerV2Coverage, - 'pause', - 'send', - [0], - true, - receipt => {}, - tester.addressTwo - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot pause a paused role`, - DharmaAccountRecoveryManagerV2Coverage, - 'pause', - 'send', - [0], - false, - receipt => {}, - tester.addressTwo - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can pause the pauser role`, - DharmaAccountRecoveryManagerV2Coverage, - 'pause', - 'send', - [4] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 pauser cannot call a paused role`, - DharmaAccountRecoveryManagerV2Coverage, - 'pause', - 'send', - [4], - false, - receipt => {}, - tester.addressTwo - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check if a role is paused`, - DharmaAccountRecoveryManagerV2Coverage, - 'isPaused', - 'call', - [0], - true, - value => { - assert.ok(value) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can unpause a paused role`, - DharmaAccountRecoveryManagerV2Coverage, - 'unpause', - 'send', - [0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can get an empty timelock`, - DharmaAccountRecoveryManagerV2Coverage, - 'getTimelock', - 'call', - ['0x01020304', '0x'], - true, - value => { - assert.ok(!value.exists) - assert.ok(!value.completed) - assert.ok(!value.expired) - assert.strictEqual(value.completionTime, '0') - assert.strictEqual(value.expirationTime, '0') - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can get an empty default timelock interval`, - DharmaAccountRecoveryManagerV2Coverage, - 'getDefaultTimelockInterval', - 'call', - ['0x01020304'], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can get an empty default timelock expiration`, - DharmaAccountRecoveryManagerV2Coverage, - 'getDefaultTimelockExpiration', - 'call', - ['0x01020304'], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval with no selector`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockInterval', - 'send', - ['0x00000000', 0, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval to modify interval over 8 weeks`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 5443200, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot create timelock with excessive duration`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', constants.FULL_APPROVAL, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 10000, 5] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot shorten existing initiateModifyTimelockInterval timelock`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 10000, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to change a duration`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 10001, 5] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock on another function`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockInterval', - 'send', - ['0xaaaaaaaa', 10000, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval with no selector`, - DharmaAccountRecoveryManagerV2Coverage, - 'modifyTimelockInterval', - 'send', - ['0x00000000', 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval before timelock completion`, - DharmaAccountRecoveryManagerV2Coverage, - 'modifyTimelockInterval', - 'send', - ['0xe950c085', 1000], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration with no selector`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0x00000000', 0, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to with expiration over one month`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0xe950c085', 5443200, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to modify expiration under one minute`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 30, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 300000, 0], - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock on another function`, - DharmaAccountRecoveryManagerV2Coverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0xe950c085', 30, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration with no selector`, - DharmaAccountRecoveryManagerV2Coverage, - 'modifyTimelockExpiration', - 'send', - ['0x00000000', 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration before timelock completion`, - DharmaAccountRecoveryManagerV2Coverage, - 'modifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 300], - false - ) - - // advance time by 2 weeks - await tester.advanceTime((60 * 60 * 24 * 7 * 2) + 5) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call modifyTimelockInterval`, - DharmaAccountRecoveryManagerV2Coverage, - 'modifyTimelockInterval', - 'send', - ['0xaaaaaaaa', 10000] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call modifyTimelockExpiration`, - DharmaAccountRecoveryManagerV2Coverage, - 'modifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 300000], - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration if expiration is too short`, - DharmaAccountRecoveryManagerV2Coverage, - 'modifyTimelockExpiration', - 'send', - ['0xe950c085', 30], - false - ) + await testAccountRecoveryManager( + tester, + DharmaAccountRecoveryManagerV2Coverage, + UserSmartWalletV6.options.address + ); await tester.runTest( `DharmaUpgradeBeaconControllerManager cannot transfer ownership from a non-owner`, From 1c33d794629bb0ff923b3330f04bf9fdd406d011 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Fri, 7 Feb 2020 10:35:32 -0500 Subject: [PATCH 18/47] move beacon controller tests to new file --- .../testUpgradeBeaconController.js | 199 ++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 scripts/test/contracts/upgradeability/testUpgradeBeaconController.js diff --git a/scripts/test/contracts/upgradeability/testUpgradeBeaconController.js b/scripts/test/contracts/upgradeability/testUpgradeBeaconController.js new file mode 100644 index 0000000..9ec201c --- /dev/null +++ b/scripts/test/contracts/upgradeability/testUpgradeBeaconController.js @@ -0,0 +1,199 @@ +const constants = require("../../constants"); +const assert = require("assert"); + +async function testUpgradeBeaconController( + tester, + contract, + smartWalletControllerContract, + keyRingControllerContract, + envoyContract, + smartWalletUpgradeBeaconAddress, + keyRingUpgradeBeaconAddress, + badBeaconAddress +) { + + await tester.runTest( + `DharmaUpgradeBeaconController initially gets zero for lastImplementation`, + contract, + 'getCodeHashAtLastUpgrade', + 'call', + [tester.address], + true, + value => { + assert.strictEqual(value, constants.NULL_BYTES_32) + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconController cannot call upgrade from non-owner account`, + contract, + 'upgrade', + 'send', + [smartWalletUpgradeBeaconAddress, smartWalletControllerContract.options.address], + false, + receipt => {}, + tester.addressTwo + ) + + await tester.runTest( + `DharmaUpgradeBeaconController can set implementation on upgrade beacon contract`, + smartWalletControllerContract, + 'upgrade', + 'send', + [smartWalletUpgradeBeaconAddress, smartWalletControllerContract.options.address] + ) + + await tester.runTest( + `DharmaKeyRingUpgradeBeaconController can set implementation on key ring upgrade beacon contract`, + keyRingControllerContract, + 'upgrade', + 'send', + [keyRingUpgradeBeaconAddress, smartWalletControllerContract.options.address] + ) + + await tester.runTest( + `DharmaUpgradeBeaconEnvoy throws when given invalid beacon`, + envoyContract, + 'getImplementation', + 'call', + [envoyContract.options.address], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconEnvoy throws when given non-contract beacon`, + envoyContract, + 'getImplementation', + 'call', + [tester.address], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconEnvoy can get the implementation of a valid beacon`, + envoyContract, + 'getImplementation', + 'call', + [keyRingUpgradeBeaconAddress], + true, + value => { + assert.strictEqual(value, smartWalletControllerContract.options.address) + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconController cannot set null implementation on an upgrade beacon contract`, + contract, + 'upgrade', + 'send', + [smartWalletUpgradeBeaconAddress, constants.NULL_ADDRESS], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconController cannot set non-contract implementation`, + contract, + 'upgrade', + 'send', + [smartWalletUpgradeBeaconAddress, tester.address], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconController cannot set null address beacon`, + contract, + 'upgrade', + 'send', + [constants.NULL_ADDRESS, smartWalletControllerContract.options.address], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconController cannot set non-contract address beacon`, + contract, + 'upgrade', + 'send', + [tester.address, smartWalletControllerContract.options.address], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconController cannot set unowned bad beacon`, + contract, + 'upgrade', + 'send', + [badBeaconAddress, smartWalletControllerContract.options.address], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconController cannot set unowned beacon (Note that it still logs an event!)`, + contract, + 'upgrade', + 'send', + [smartWalletUpgradeBeaconAddress, smartWalletControllerContract.options.address] + ) + + await tester.runTest( + `DharmaUpgradeBeaconController can get implementation of a beacon`, + contract, + 'getImplementation', + 'call', + [smartWalletUpgradeBeaconAddress], + true, + value => { + assert.strictEqual(value, smartWalletControllerContract.options.address) + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconController can get owner`, + contract, + 'owner', + 'call', + [], + true, + value => { + assert.strictEqual(value, tester.address) + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconController can call isOwner and value is ok`, + contract, + 'isOwner', + 'call', + [], + true, + value => { + assert.ok(value) + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconController cannot transfer ownership to null address`, + contract, + 'transferOwnership', + 'send', + [constants.NULL_ADDRESS], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconController can transfer ownership`, + contract, + 'transferOwnership', + 'send', + [tester.address] + ) + + await tester.runTest( + `DharmaUpgradeBeaconController can renounce ownership`, + contract, + 'renounceOwnership' + ) +} + +module.exports = { + testUpgradeBeaconController +}; \ No newline at end of file From 671ca4a324ace5e365e9e60e9c97fab3e4757157 Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Fri, 7 Feb 2020 07:35:48 -0800 Subject: [PATCH 19/47] refactor indestructible registry --- .../testIndestructibleRegistry.js | 241 ++++++++++++++ scripts/test/deploy.js | 296 +++--------------- 2 files changed, 281 insertions(+), 256 deletions(-) create mode 100644 scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js diff --git a/scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js b/scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js new file mode 100644 index 0000000..e98603e --- /dev/null +++ b/scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js @@ -0,0 +1,241 @@ +const constants = require("../../constants"); +const { newContractAndSwapMetadataHash } = require("../../testHelpers"); + +const IndestructibleRegistryArtifact = require('../../../../build/contracts/IndestructibleRegistry.json'); + +async function testIndestructibleRegistry(tester, contracts) { + const { + DharmaSmartWalletImplementationV0, + DharmaSmartWalletImplementationV1, + DharmaSmartWalletImplementationV2, + DharmaSmartWalletImplementationV5, + DharmaSmartWalletImplementationV6, + DharmaSmartWalletImplementationV7, + DharmaKeyRingImplementationV1, + } = contracts; + + const IndestructibleRegistryDeployer = newContractAndSwapMetadataHash( + IndestructibleRegistryArtifact + ); + + const IndestructibleRegistry = await tester.runTest( + `IndestructibleRegistry contract deployment`, + IndestructibleRegistryDeployer, + '', + 'deploy' + ) + + await tester.runTest( + 'IndestructibleRegistry can register itself as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [IndestructibleRegistry.options.address] + ) + + await tester.runTest( + 'IndestructibleRegistry can register the upgrade beacon as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.UPGRADE_BEACON_ADDRESS] + ) + + await tester.runTest( + 'IndestructibleRegistry can register the upgrade beacon controller as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.UPGRADE_BEACON_CONTROLLER_ADDRESS] + ) + + await tester.runTest( + 'IndestructibleRegistry can register the key ring upgrade beacon as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.KEY_RING_UPGRADE_BEACON_ADDRESS] + ) + + await tester.runTest( + 'IndestructibleRegistry can register the key ring upgrade beacon controller as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS] + ) + + await tester.runTest( + 'IndestructibleRegistry can register the upgrade beacon envoy as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.UPGRADE_BEACON_ENVOY_ADDRESS] + ) + + await tester.runTest( + 'IndestructibleRegistry can register the account recovery manager as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS] + ) + + await tester.runTest( + 'IndestructibleRegistry can register DharmaKeyRegistryV1 as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.KEY_REGISTRY_ADDRESS] + ) + + await tester.runTest( + 'IndestructibleRegistry can register DharmaKeyRegistryV2 as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.KEY_REGISTRY_V2_ADDRESS] + ) + + await tester.runTest( + 'IndestructibleRegistry can register DharmaEscapeHatchRegistry as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.ESCAPE_HATCH_REGISTRY_ADDRESS] + ) + + await tester.runTest( + 'WARNING: IndestructibleRegistry CANNOT register the smart wallet factory as indestructible (even though it is in fact NOT destructible)', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.FACTORY_ADDRESS], + false + ) + + await tester.runTest( + 'IndestructibleRegistry can register the Adharma smart wallet implementation as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS] + ) + + await tester.runTest( + 'IndestructibleRegistry can register the Adharma key ring implementation as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS] + ) + + await tester.runTest( + 'IndestructibleRegistry can register V0 implementation as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [DharmaSmartWalletImplementationV0.options.address] + ) + + /* + await runTest( + 'IndestructibleRegistry can register V0 key ring implementation as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [DharmaKeyRingImplementationV0.options.address] + ) + */ + + await tester.runTest( + 'IndestructibleRegistry can register V1 implementation as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [DharmaSmartWalletImplementationV1.options.address] + ) + + if (tester.testingContext !== 'coverage') { + await tester.runTest( + 'IndestructibleRegistry can register V2 implementation as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [DharmaSmartWalletImplementationV2.options.address] + ) + + /* + await runTest( + 'IndestructibleRegistry can register V3 implementation as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [DharmaSmartWalletImplementationV3.options.address] + ) + + await runTest( + 'IndestructibleRegistry can register V4 implementation as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [DharmaSmartWalletImplementationV4.options.address] + ) + */ + + await tester.runTest( + 'IndestructibleRegistry can register V5 implementation as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [DharmaSmartWalletImplementationV5.options.address] + ) + + await tester.runTest( + 'IndestructibleRegistry can register V6 implementation as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [DharmaSmartWalletImplementationV6.options.address] + ) + + await tester.runTest( + 'IndestructibleRegistry can register V7 implementation as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [DharmaSmartWalletImplementationV7.options.address] + ) + + await tester.runTest( + 'IndestructibleRegistry can register V1 key ring implementation as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [DharmaKeyRingImplementationV1.options.address] + ) + } + + /* + await runTest( + 'IndestructibleRegistry can register V2 key ring implementation as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [DharmaKeyRingImplementationV2.options.address] + ) + */ + + await tester.runTest( + 'IndestructibleRegistry can register the upgrade beacon controller manager as indestructible', + IndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS] + ) +} + +module.exports = { + testIndestructibleRegistry, +} + diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index 741a013..abaf13c 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -4,6 +4,7 @@ var util = require('ethereumjs-util') const constants = require('./constants.js') const { web3 } = require("./web3"); const { Tester, swapMetadataHash, newContractAndSwapMetadataHash } = require("./testHelpers"); +const { testIndestructibleRegistry } = require("./contracts/indestructible-registry/testIndestructibleRegistry"); let DharmaUpgradeBeaconArtifact; let DharmaUpgradeBeaconControllerArtifact; @@ -207,10 +208,6 @@ async function test(testingContext) { constants.REVERT_REASON_HELPER_ADDRESS ) - const IndestructibleRegistryDeployer = newContractAndSwapMetadataHash( - IndestructibleRegistryArtifact - ); - const CodeHashCacheDeployer = newContractAndSwapMetadataHash( CodeHashCacheArtifact ); @@ -333,7 +330,6 @@ async function test(testingContext) { DharmaKeyRingFactoryV2Artifact.bytecode ) - const AdharmaSmartWalletImplementationDeployer = newContractAndSwapMetadataHash( AdharmaSmartWalletImplementationArtifact ); @@ -500,7 +496,6 @@ async function test(testingContext) { const tester = new Tester(testingContext); await tester.init(); - console.log('funding initial create2 contract deployer address...') await web3.eth.sendTransaction({ from: tester.originalAddress, @@ -1516,261 +1511,54 @@ async function test(testingContext) { false ) - const IndestructibleRegistry = await tester.runTest( - `IndestructibleRegistry contract deployment`, - IndestructibleRegistryDeployer, - '', - 'deploy' - ) - - await tester.runTest( - 'IndestructibleRegistry can register itself as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [IndestructibleRegistry.options.address] - ) - - await tester.runTest( - 'IndestructibleRegistry can register the upgrade beacon as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.UPGRADE_BEACON_ADDRESS] - ) - - await tester.runTest( - 'IndestructibleRegistry can register the upgrade beacon controller as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.UPGRADE_BEACON_CONTROLLER_ADDRESS] - ) - - await tester.runTest( - 'IndestructibleRegistry can register the key ring upgrade beacon as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.KEY_RING_UPGRADE_BEACON_ADDRESS] - ) - - await tester.runTest( - 'IndestructibleRegistry can register the key ring upgrade beacon controller as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS] - ) - - await tester.runTest( - 'IndestructibleRegistry can register the upgrade beacon envoy as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.UPGRADE_BEACON_ENVOY_ADDRESS] - ) - - await tester.runTest( - 'IndestructibleRegistry can register the account recovery manager as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS] - ) - - await tester.runTest( - 'IndestructibleRegistry can register DharmaKeyRegistryV1 as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.KEY_REGISTRY_ADDRESS] - ) - - await tester.runTest( - 'IndestructibleRegistry can register DharmaKeyRegistryV2 as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.KEY_REGISTRY_V2_ADDRESS] - ) - - await tester.runTest( - 'IndestructibleRegistry can register DharmaEscapeHatchRegistry as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.ESCAPE_HATCH_REGISTRY_ADDRESS] - ) - - await tester.runTest( - 'WARNING: IndestructibleRegistry CANNOT register the smart wallet factory as indestructible (even though it is in fact NOT destructible)', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.FACTORY_ADDRESS], - false - ) - - await tester.runTest( - 'IndestructibleRegistry can register the Adharma smart wallet implementation as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS] - ) - - await tester.runTest( - 'IndestructibleRegistry can register the Adharma key ring implementation as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS] - ) - - await tester.runTest( - 'IndestructibleRegistry can register V0 implementation as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [DharmaSmartWalletImplementationV0.options.address] - ) - - /* - await runTest( - 'IndestructibleRegistry can register V0 key ring implementation as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [DharmaKeyRingImplementationV0.options.address] - ) - */ - await tester.runTest( - 'IndestructibleRegistry can register V1 implementation as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [DharmaSmartWalletImplementationV1.options.address] - ) - - if (testingContext !== 'coverage') { - await tester.runTest( - 'IndestructibleRegistry can register V2 implementation as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [DharmaSmartWalletImplementationV2.options.address] - ) - - /* - await runTest( - 'IndestructibleRegistry can register V3 implementation as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [DharmaSmartWalletImplementationV3.options.address] - ) - - await runTest( - 'IndestructibleRegistry can register V4 implementation as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [DharmaSmartWalletImplementationV4.options.address] - ) - */ - - await tester.runTest( - 'IndestructibleRegistry can register V5 implementation as indestructible', - IndestructibleRegistry, + '"actual" IndestructibleRegistry can register the upgrade beacon as indestructible', + ActualIndestructibleRegistry, 'registerAsIndestructible', 'send', - [DharmaSmartWalletImplementationV5.options.address] - ) - - await tester.runTest( - 'IndestructibleRegistry can register V6 implementation as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [DharmaSmartWalletImplementationV6.options.address] - ) + [constants.UPGRADE_BEACON_ADDRESS] + ) - await tester.runTest( - 'IndestructibleRegistry can register V7 implementation as indestructible', - IndestructibleRegistry, + await tester.runTest( + '"actual" IndestructibleRegistry can register the upgrade beacon controller as indestructible', + ActualIndestructibleRegistry, 'registerAsIndestructible', 'send', - [DharmaSmartWalletImplementationV7.options.address] - ) + [constants.UPGRADE_BEACON_CONTROLLER_ADDRESS] + ) - await tester.runTest( - 'IndestructibleRegistry can register V1 key ring implementation as indestructible', - IndestructibleRegistry, + await tester.runTest( + '"actual" IndestructibleRegistry can register the key ring upgrade beacon as indestructible', + ActualIndestructibleRegistry, 'registerAsIndestructible', 'send', - [DharmaKeyRingImplementationV1.options.address] - ) - } - - /* - await runTest( - 'IndestructibleRegistry can register V2 key ring implementation as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [DharmaKeyRingImplementationV2.options.address] + [constants.KEY_RING_UPGRADE_BEACON_ADDRESS] ) - */ - - await tester.runTest( - '"actual" IndestructibleRegistry can register the upgrade beacon as indestructible', - ActualIndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.UPGRADE_BEACON_ADDRESS] - ) await tester.runTest( - '"actual" IndestructibleRegistry can register the upgrade beacon controller as indestructible', - ActualIndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.UPGRADE_BEACON_CONTROLLER_ADDRESS] + '"actual" IndestructibleRegistry can register the key ring upgrade beacon controller as indestructible', + ActualIndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS] ) await tester.runTest( - '"actual" IndestructibleRegistry can register the key ring upgrade beacon as indestructible', - ActualIndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.KEY_RING_UPGRADE_BEACON_ADDRESS] - ) - - await tester.runTest( - '"actual" IndestructibleRegistry can register the key ring upgrade beacon controller as indestructible', - ActualIndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS] + '"actual" IndestructibleRegistry can register the Adharma smart wallet implementation as indestructible', + ActualIndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS] ) await tester.runTest( - '"actual" IndestructibleRegistry can register the Adharma smart wallet implementation as indestructible', - ActualIndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS] + '"actual" IndestructibleRegistry can register the Adharma key ring implementation as indestructible', + ActualIndestructibleRegistry, + 'registerAsIndestructible', + 'send', + [constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS] ) - await tester.runTest( - '"actual" IndestructibleRegistry can register the Adharma key ring implementation as indestructible', - ActualIndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS] - ) const CodeHashCache = await tester.runTest( `CodeHashCache contract deployment`, @@ -1779,14 +1567,6 @@ async function test(testingContext) { 'deploy' ) - await tester.runTest( - 'IndestructibleRegistry can register codehashcache as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [CodeHashCache.options.address] - ) - await tester.runTest( 'CodeHashCache can register the runtime code hash of the smart wallet factory', CodeHashCache, @@ -1817,13 +1597,17 @@ async function test(testingContext) { ); - await tester.runTest( - 'IndestructibleRegistry can register the upgrade beacon controller manager as indestructible', - IndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS] - ) + const testIndestructibleRegistryContracts = { + DharmaSmartWalletImplementationV0, + DharmaSmartWalletImplementationV1, + DharmaSmartWalletImplementationV2, + DharmaSmartWalletImplementationV5, + DharmaSmartWalletImplementationV6, + DharmaSmartWalletImplementationV7, + DharmaKeyRingImplementationV1, + }; + + await testIndestructibleRegistry(tester, testIndestructibleRegistryContracts); await tester.runTest( `DharmaUpgradeMultisig contract deployment fails if threshold is not met`, From 3789c007697aae111755082dc21ed76bcc116086 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Fri, 7 Feb 2020 10:36:47 -0500 Subject: [PATCH 20/47] use beacon controller test file --- scripts/test/test.js | 207 ++++--------------------------------------- 1 file changed, 19 insertions(+), 188 deletions(-) diff --git a/scripts/test/test.js b/scripts/test/test.js index c457733..9a17a13 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -5,6 +5,7 @@ const constants = require('./constants.js') const { web3 } = require("./web3"); const { Tester, longer } = require("./testHelpers"); const { testAccountRecoveryManager } = require("./contracts/account-recovery/testAccountRecoveryManager"); +const { testUpgradeBeaconController } = require("./contracts/upgradeability/testUpgradeBeaconController"); const AdharmaSmartWalletImplementationArtifact = require('../../build/contracts/AdharmaSmartWalletImplementation.json') const AdharmaKeyRingImplementationArtifact = require('../../build/contracts/AdharmaKeyRingImplementation.json') @@ -10855,13 +10856,6 @@ async function test(testingContext) { 'deploy' ) - const DharmaKeyRegistryV2Coverage = await tester.runTest( - `DharmaKeyRegistryV2 contract deployment`, - DharmaKeyRegistryV2Deployer, - '', - 'deploy' - ) - const DharmaUpgradeBeaconCoverage = await tester.runTest( `DharmaUpgradeBeacon (smart wallet) contract deployment`, DharmaUpgradeBeaconDeployer, @@ -10883,6 +10877,24 @@ async function test(testingContext) { 'deploy' ) + await testUpgradeBeaconController( + tester, + DharmaUpgradeBeaconControllerCoverage, // controller manager + DharmaUpgradeBeaconController, // smart wallet controller contract + DharmaKeyRingUpgradeBeaconController, // key ring controller contract + DharmaUpgradeBeaconEnvoy, // envoy contract + DharmaUpgradeBeaconCoverage.options.address, // owned smart wallet beacon + DharmaKeyRingUpgradeBeaconCoverage.options.address, // owned key ring beacon + BadBeaconTwo.options.address // "bad" beacon + ); + + const DharmaKeyRegistryV2Coverage = await tester.runTest( + `DharmaKeyRegistryV2 contract deployment`, + DharmaKeyRegistryV2Deployer, + '', + 'deploy' + ) + const AdharmaSmartWalletImplementation = await tester.runTest( `AdharmaSmartWalletImplementation contract deployment`, AdharmaSmartWalletImplementationDeployer, @@ -11688,187 +11700,6 @@ async function test(testingContext) { false ) - await tester.runTest( - `DharmaUpgradeBeaconController initially gets zero for lastImplementation`, - DharmaUpgradeBeaconControllerCoverage, - 'getCodeHashAtLastUpgrade', - 'call', - [tester.address], - true, - value => { - assert.strictEqual(value, constants.NULL_BYTES_32) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot call upgrade from non-owner account`, - DharmaUpgradeBeaconControllerCoverage, - 'upgrade', - 'send', - [DharmaUpgradeBeaconCoverage.options.address, DharmaUpgradeBeaconController.options.address], - false, - receipt => {}, - tester.addressTwo - ) - - await tester.runTest( - `DharmaUpgradeBeaconController can set implementation on upgrade beacon contract`, - DharmaUpgradeBeaconController, - 'upgrade', - 'send', - [DharmaUpgradeBeaconCoverage.options.address, DharmaUpgradeBeaconController.options.address] - ) - - await tester.runTest( - `DharmaKeyRingUpgradeBeaconController can set implementation on key ring upgrade beacon contract`, - DharmaKeyRingUpgradeBeaconController, - 'upgrade', - 'send', - [DharmaKeyRingUpgradeBeaconCoverage.options.address, DharmaUpgradeBeaconController.options.address] - ) - - await tester.runTest( - `DharmaUpgradeBeaconEnvoy throws when given invalid beacon`, - DharmaUpgradeBeaconEnvoy, - 'getImplementation', - 'call', - [DharmaUpgradeBeaconEnvoy.options.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconEnvoy throws when given non-contract beacon`, - DharmaUpgradeBeaconEnvoy, - 'getImplementation', - 'call', - [tester.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconEnvoy can get the implementation of a valid beacon`, - DharmaUpgradeBeaconEnvoy, - 'getImplementation', - 'call', - [DharmaKeyRingUpgradeBeaconCoverage.options.address], - true, - value => { - assert.strictEqual(value, DharmaUpgradeBeaconController.options.address) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot set null implementation on an upgrade beacon contract`, - DharmaUpgradeBeaconControllerCoverage, - 'upgrade', - 'send', - [DharmaUpgradeBeaconCoverage.options.address, constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot set non-contract implementation`, - DharmaUpgradeBeaconControllerCoverage, - 'upgrade', - 'send', - [DharmaUpgradeBeaconCoverage.options.address, tester.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot set null address beacon`, - DharmaUpgradeBeaconControllerCoverage, - 'upgrade', - 'send', - [constants.NULL_ADDRESS, DharmaUpgradeBeaconControllerCoverage.options.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot set non-contract address beacon`, - DharmaUpgradeBeaconControllerCoverage, - 'upgrade', - 'send', - [tester.address, DharmaUpgradeBeaconControllerCoverage.options.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot set unowned bad beacon`, - DharmaUpgradeBeaconControllerCoverage, - 'upgrade', - 'send', - [BadBeaconTwo.options.address, DharmaUpgradeBeaconControllerCoverage.options.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot set unowned beacon (Note that it still logs an event!)`, - DharmaUpgradeBeaconControllerCoverage, - 'upgrade', - 'send', - [DharmaUpgradeBeaconCoverage.options.address, DharmaUpgradeBeaconControllerCoverage.options.address] - ) - - await tester.runTest( - `DharmaUpgradeBeaconController can get implementation of a beacon`, - DharmaUpgradeBeaconControllerCoverage, - 'getImplementation', - 'call', - [DharmaUpgradeBeaconCoverage.options.address], - true, - value => { - assert.strictEqual(value, DharmaUpgradeBeaconController.options.address) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconController can get owner`, - DharmaUpgradeBeaconControllerCoverage, - 'owner', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconController can call isOwner and value is ok`, - DharmaUpgradeBeaconControllerCoverage, - 'isOwner', - 'call', - [], - true, - value => { - assert.ok(value) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot transfer ownership to null address`, - DharmaUpgradeBeaconControllerCoverage, - 'transferOwnership', - 'send', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconController can transfer ownership`, - DharmaUpgradeBeaconControllerCoverage, - 'transferOwnership', - 'send', - [tester.address] - ) - - await tester.runTest( - `DharmaUpgradeBeaconController can renounce ownership`, - DharmaUpgradeBeaconControllerCoverage, - 'renounceOwnership' - ) - const DharmaAccountRecoveryManagerV2Coverage = await tester.runTest( `DharmaAccountRecoveryManagerV2 contract deployment`, DharmaAccountRecoveryManagerV2Deployer, From 271d8f20a8359a2e573cc45a6db502434191d1df Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Fri, 7 Feb 2020 11:01:10 -0500 Subject: [PATCH 21/47] move beacon controller manager tests to new file --- .../testUpgradeBeaconController.js | 1 - .../testUpgradeBeaconControllerManager.js | 1031 +++++++++++++++++ scripts/test/test.js | 1012 +--------------- 3 files changed, 1041 insertions(+), 1003 deletions(-) create mode 100644 scripts/test/contracts/upgradeability/testUpgradeBeaconControllerManager.js diff --git a/scripts/test/contracts/upgradeability/testUpgradeBeaconController.js b/scripts/test/contracts/upgradeability/testUpgradeBeaconController.js index 9ec201c..f04437d 100644 --- a/scripts/test/contracts/upgradeability/testUpgradeBeaconController.js +++ b/scripts/test/contracts/upgradeability/testUpgradeBeaconController.js @@ -11,7 +11,6 @@ async function testUpgradeBeaconController( keyRingUpgradeBeaconAddress, badBeaconAddress ) { - await tester.runTest( `DharmaUpgradeBeaconController initially gets zero for lastImplementation`, contract, diff --git a/scripts/test/contracts/upgradeability/testUpgradeBeaconControllerManager.js b/scripts/test/contracts/upgradeability/testUpgradeBeaconControllerManager.js new file mode 100644 index 0000000..94ca0f4 --- /dev/null +++ b/scripts/test/contracts/upgradeability/testUpgradeBeaconControllerManager.js @@ -0,0 +1,1031 @@ +const constants = require("../../constants"); +const assert = require("assert"); + +async function testUpgradeBeaconControllerManagerPartOne( + tester, + contract +) { + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot transfer ownership from a non-owner`, + contract, + 'transferOwnership', + 'send', + [tester.addressTwo], + false, + receipt => {}, + tester.originalAddress + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with null controller`, + contract, + 'initiateUpgrade', + 'send', + [constants.NULL_ADDRESS, tester.address, tester.addressTwo, 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with null beacon`, + contract, + 'initiateUpgrade', + 'send', + [tester.address, constants.NULL_ADDRESS, tester.addressTwo, 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with null implementation`, + contract, + 'initiateUpgrade', + 'send', + [tester.address, tester.addressTwo, constants.NULL_ADDRESS, 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with non-contract implementation`, + contract, + 'initiateUpgrade', + 'send', + [tester.address, tester.addressTwo, tester.address, 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with massive extraTime`, + contract, + 'initiateUpgrade', + 'send', + [tester.address, tester.addressTwo, contract.options.address, constants.FULL_APPROVAL], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can initiate upgrade timelock`, + contract, + 'initiateUpgrade', + 'send', + [tester.address, tester.addressTwo, contract.options.address, 0] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can get an empty timelock`, + contract, + 'getTimelock', + 'call', + ['0x01020304', '0x'], + true, + value => { + assert.ok(!value.exists) + assert.ok(!value.completed) + assert.ok(!value.expired) + assert.strictEqual(value.completionTime, '0') + assert.strictEqual(value.expirationTime, '0') + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can get an empty default timelock interval`, + contract, + 'getDefaultTimelockInterval', + 'call', + ['0x01020304'], + true, + value => { + assert.strictEqual(value, '0') + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can get an empty default timelock expiration`, + contract, + 'getDefaultTimelockExpiration', + 'call', + ['0x01020304'], + true, + value => { + assert.strictEqual(value, '0') + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot upgrade before timelock is complete`, + contract, + 'upgrade', + 'send', + [tester.address, tester.addressTwo, contract.options.address], + false + ) + + // advance time by 7 days + await tester.advanceTime((60 * 60 * 24 * 7) + 5) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot upgrade an unowned controller`, + contract, + 'upgrade', + 'send', + [tester.address, tester.addressTwo, contract.options.address], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot transfer controller ownership before accepting ownership`, + contract, + 'transferControllerOwnership', + 'send', + [tester.address, tester.address], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot agree to accept ownership of null controller`, + contract, + 'agreeToAcceptControllerOwnership', + 'send', + [constants.NULL_ADDRESS, true], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can agree to accept ownership`, + contract, + 'agreeToAcceptControllerOwnership', + 'send', + [tester.address, true] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate controller ownership transfer with null controller`, + contract, + 'initiateTransferControllerOwnership', + 'send', + [constants.NULL_ADDRESS, tester.addressTwo, 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate controller ownership transfer with null new owner`, + contract, + 'initiateTransferControllerOwnership', + 'send', + [tester.address, constants.NULL_ADDRESS, 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate controller ownership transfer if new owner has not accepted`, + contract, + 'initiateTransferControllerOwnership', + 'send', + [tester.address, tester.addressTwo, 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can initiate controller ownership transfer if new owner has accepted`, + contract, + 'initiateTransferControllerOwnership', + 'send', + [tester.address, tester.address, 0] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot transfer controller ownership prior to timelock completion`, + contract, + 'transferControllerOwnership', + 'send', + [tester.address, tester.address], + false + ) + + // advance time by 4 weeks + await tester.advanceTime((60 * 60 * 24 * 7 * 4) + 5) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot transfer unowned controller ownership`, + contract, + 'transferControllerOwnership', + 'send', + [tester.address, tester.address], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot heartbeat from non-heartbeater`, + contract, + 'heartbeat', + 'send', + [], + false, + receipt => {}, + tester.originalAddress + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can heartbeat`, + contract, + 'heartbeat' + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot set new heartbeater to null address`, + contract, + 'newHeartbeater', + 'send', + [constants.NULL_ADDRESS], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner can set new heartbeater`, + contract, + 'newHeartbeater', + 'send', + [tester.address] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot arm Adharma Contingency from non-owner when not expired`, + contract, + 'armAdharmaContingency', + 'send', + [true], + false, + receipt => {}, + tester.originalAddress + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when not armed`, + contract, + 'activateAdharmaContingency', + 'send', + [], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner can arm an Adharma Contingency`, + contract, + 'armAdharmaContingency', + 'send', + [true] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner can disarm Adharma Contingency`, + contract, + 'armAdharmaContingency', + 'send', + [false] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner can re-arm Adharma Contingency`, + contract, + 'armAdharmaContingency', + 'send', + [true] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency from non-owner when not expired`, + contract, + 'activateAdharmaContingency', + 'send', + [], + false, + receipt => {}, + tester.originalAddress + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when it doesn't own controllers`, + contract, + 'activateAdharmaContingency', + 'send', + [], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot roll back prior to first upgrade`, + contract, + 'rollback', + 'send', + [tester.address, tester.address, 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot exit Adharma Contingency when not active`, + contract, + 'exitAdharmaContingency', + 'send', + [tester.address, tester.address], + false + ) + + /* + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can activate Adharma Contingency`, + contract, + 'activateAdharmaContingency', + 'send', + [] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner cannot arm Adharma Contingency while active`, + contract, + 'armAdharmaContingency', + 'send', + [true] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot activate Contingency when activated`, + contract, + 'activateAdharmaContingency', + 'send', + [], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner can disarm Adharma Contingency`, + contract, + 'armAdharmaContingency', + 'send', + [false] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot exit Contingency before 48 hours`, + contract, + 'exitAdharmaContingency', + 'send', + [ + DharmaSmartWalletImplementationV6.options.address, + DharmaKeyRingImplementationV1.options.address + ], + false + ) + + // advance time by 2 days + await tester.advanceTime((60 * 60 * 24 * 2) + 5) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot exit Contingency to null address`, + contract, + 'exitAdharmaContingency', + 'send', + [constants.NULL_ADDRESS, DharmaKeyRingImplementationV1.options.address], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot exit Contingency to non-contract address`, + contract, + 'exitAdharmaContingency', + 'send', + [address, address], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can exit Contingency after 48 hours`, + contract, + 'exitAdharmaContingency', + 'send', + [ + DharmaSmartWalletImplementationV6.options.address, + DharmaKeyRingImplementationV1.options.address + ] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner can arm Adharma Contingency again`, + contract, + 'armAdharmaContingency', + 'send', + [true] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can activate fake Adharma Contingency again`, + contract, + 'activateAdharmaContingency', + 'send', + [] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can roll back from fake Adharma Contingency`, + contract, + 'rollback', + 'send', + [constants.UPGRADE_BEACON_CONTROLLER_ADDRESS, constants.UPGRADE_BEACON_ADDRESS, 0] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can "roll forward" after roll back`, + contract, + 'rollback', + 'send', + [constants.UPGRADE_BEACON_ADDRESS, constants.UPGRADE_BEACON_ADDRESS] + ) + */ + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can get heartbeat status`, + contract, + 'heartbeatStatus', + 'call', + [], + true, + value => { + assert.ok(!value.expired) + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager get contingency status when armed but not activated`, + contract, + 'contingencyStatus', + 'call', + [], + true, + value => { + assert.ok(value.armed) + assert.ok(!value.activated) + assert.strictEqual(value.activationTime, '0') + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager gets 0 for non-existent total implementations`, + contract, + 'getTotalPriorImplementations', + 'call', + [tester.address, tester.address], + true, + value => { + assert.strictEqual(value, '0') + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot get a prior implementation with no index`, + contract, + 'getPriorImplementation', + 'call', + [tester.address, tester.address, 100], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot rollback to implementation with no index`, + contract, + 'rollback', + 'send', + [tester.address, tester.address, 100], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot block rollback to implementation with no index`, + contract, + 'blockRollback', + 'send', + [tester.address, tester.address, 100], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockInterval with no selector`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0x00000000', 0, 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockInterval to modify interval over 8 weeks`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0xe950c085', 5443200, 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot create timelock with excessive duration`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0xe950c085', constants.FULL_APPROVAL, 0], + false // TODO: move this outside of Controller manager + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockInterval to set a timelock`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0xe950c085', 10000, 5] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot shorten existing initiateModifyTimelockInterval timelock`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0xe950c085', 10000, 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockInterval to change a duration`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0xe950c085', 10001, 5] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockInterval to set a timelock on another function`, + contract, + 'initiateModifyTimelockInterval', + 'send', + ['0xaaaaaaaa', 10000, 0] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockInterval with no selector`, + contract, + 'modifyTimelockInterval', + 'send', + ['0x00000000', 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockInterval before timelock completion`, + contract, + 'modifyTimelockInterval', + 'send', + ['0xe950c085', 1000], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockExpiration with no selector`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0x00000000', 0, 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockExpiration to with expiration over one month`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0xe950c085', 5443200, 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockExpiration to modify expiration under one minute`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0xd7ce3c6f', 30, 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockExpiration to set a timelock`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0xd7ce3c6f', 300000, 0], + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockExpiration to set a timelock on another function`, + contract, + 'initiateModifyTimelockExpiration', + 'send', + ['0xe950c085', 30, 0] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockExpiration with no selector`, + contract, + 'modifyTimelockExpiration', + 'send', + ['0x00000000', 0], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockExpiration before timelock completion`, + contract, + 'modifyTimelockExpiration', + 'send', + ['0xd7ce3c6f', 300], + false + ) + + // advance time by 4 weeks + await tester.advanceTime((60 * 60 * 24 * 7 * 4) + 5) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call modifyTimelockInterval`, + contract, + 'modifyTimelockInterval', + 'send', + ['0xaaaaaaaa', 10000] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call modifyTimelockExpiration`, + contract, + 'modifyTimelockExpiration', + 'send', + ['0xd7ce3c6f', 300000], + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockExpiration if expiration is too short`, + contract, + 'modifyTimelockExpiration', + 'send', + ['0xe950c085', 30], + false + ) +} + +async function testUpgradeBeaconControllerManagerPartTwo( + tester, + contract, + upgradeBeaconControllerContract, + keyRingUpgradeBeaconControllerContract, + upgradeBeaconAddress, + adharmaSmartWalletImplementationAddress, + smartWalletImplementationAddress, + keyRingImplementationAddress +) { + // Transfer smart wallet controller ownership to coverage manager + await tester.runTest( + `DharmaUpgradeBeaconController can transfer ownership to manager`, + upgradeBeaconControllerContract, + 'transferOwnership', + 'send', + [contract.options.address] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when it doesn't own keyring controller`, + contract, + 'activateAdharmaContingency', + 'send', + [], + false + ) + + await tester.runTest( + `DharmaKeyRingUpgradeBeaconController can transfer ownership to manager`, + keyRingUpgradeBeaconControllerContract, + 'transferOwnership', + 'send', + [contract.options.address] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can activate Adharma Contingency`, + contract, + 'activateAdharmaContingency' + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can get contingency status when activated`, + contract, + 'contingencyStatus', + 'call', + [], + true, + value => { + assert.ok(!value.armed) + assert.ok(value.activated) + //assert.strictEqual(value.activationTime, '?') + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner can re-arm an active Adharma Contingency`, + contract, + 'armAdharmaContingency', + 'send', + [true] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when already active`, + contract, + 'activateAdharmaContingency', + 'send', + [], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager now gets a prior implementation count`, + contract, + 'getTotalPriorImplementations', + 'call', + [ + upgradeBeaconControllerContract.options.address, + upgradeBeaconAddress + ], + true, + value => { + assert.strictEqual(value, '1') + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can get the initial prior implementation`, + contract, + 'getPriorImplementation', + 'call', + [ + upgradeBeaconControllerContract.options.address, + upgradeBeaconAddress, + 0 + ], + true, + value => { + assert.strictEqual( + value.priorImplementation, adharmaSmartWalletImplementationAddress + ) + assert.ok(value.rollbackAllowed) + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call "exitAdharmaContingency" before 48 hours has elapsed`, + contract, + 'exitAdharmaContingency', + 'send', + [ + tester.address, + tester.address + ], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can rollback to initial prior implementation`, + contract, + 'rollback', + 'send', + [ + upgradeBeaconControllerContract.options.address, + upgradeBeaconAddress, + 0 + ] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager contingency status is exited after rollback`, + contract, + 'contingencyStatus', + 'call', + [], + true, + value => { + assert.ok(!value.armed) + assert.ok(!value.activated) + assert.strictEqual(value.activationTime, '0') + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot rollback to implementation with no index`, + contract, + 'rollback', + 'send', + [tester.address, tester.address, 100], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner can re-arm an Adharma Contingency`, + contract, + 'armAdharmaContingency', + 'send', + [true] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager contingency status shows armed`, + contract, + 'contingencyStatus', + 'call', + [], + true, + value => { + assert.ok(value.armed) + assert.ok(!value.activated) + assert.strictEqual(value.activationTime, '0') + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can rollback to initial prior implementation`, + contract, + 'rollback', + 'send', + [ + upgradeBeaconControllerContract.options.address, + upgradeBeaconAddress, + 0 + ] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager contingency status shows no longer armed`, + contract, + 'contingencyStatus', + 'call', + [], + true, + value => { + assert.ok(!value.armed) + assert.ok(!value.activated) + assert.strictEqual(value.activationTime, '0') + } + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can block rollback to prior implementation`, + contract, + 'blockRollback', + 'send', + [ + upgradeBeaconControllerContract.options.address, + upgradeBeaconAddress, + 0 + ] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot block a blocked rollback`, + contract, + 'blockRollback', + 'send', + [ + upgradeBeaconControllerContract.options.address, + upgradeBeaconAddress, + 0 + ], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot rollback to a blocked rollback`, + contract, + 'rollback', + 'send', + [ + upgradeBeaconControllerContract.options.address, + upgradeBeaconAddress, + 0 + ], + false + ) + + // advance time by 90 days + await tester.advanceTime((60 * 60 * 24 * 90) + 5) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager deadman switch can arm an Adharma Contingency`, + contract, + 'armAdharmaContingency', + 'send', + [true], + true, + receipt => {}, + tester.originalAddress + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager deadman switch can activate an Adharma Contingency`, + contract, + 'activateAdharmaContingency', + 'send', + [], + true, + receipt => {}, + tester.originalAddress + ) + + // advance time by 2 days + await tester.advanceTime((60 * 60 * 24 * 2) + 5) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call exitAdharmaContingency with null implementation`, + contract, + 'exitAdharmaContingency', + 'send', + [ + constants.NULL_ADDRESS, + tester.address + ], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call exitAdharmaContingency with non-contract implementation`, + contract, + 'exitAdharmaContingency', + 'send', + [ + tester.address, + tester.address + ], + false + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call exitAdharmaContingency`, + contract, + 'exitAdharmaContingency', + 'send', + [ + smartWalletImplementationAddress, + keyRingImplementationAddress + ] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can have an EOA accept controller ownership`, + contract, + 'agreeToAcceptControllerOwnership', + 'send', + [ + upgradeBeaconControllerContract.options.address, + true + ] + ) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can initiate timelock for transferring controller ownership`, + contract, + 'initiateTransferControllerOwnership', + 'send', + [ + upgradeBeaconControllerContract.options.address, + tester.address, + 0 + ] + ) + + // advance time by 4 weeks + await tester.advanceTime((60 * 60 * 24 * 7 * 4) + 5) + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can transfer controller ownership`, + contract, + 'transferControllerOwnership', + 'send', + [ + upgradeBeaconControllerContract.options.address, + tester.address + ] + ) + + await tester.runTest( + `DharmaUpgradeBeaconController can get new owner`, + upgradeBeaconControllerContract, + 'isOwner', + 'call', + [], + true, + value => { + assert.ok(value) + } + ) +} + +module.exports = { + testUpgradeBeaconControllerManagerPartOne, + testUpgradeBeaconControllerManagerPartTwo +}; \ No newline at end of file diff --git a/scripts/test/test.js b/scripts/test/test.js index 9a17a13..a51b7eb 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -6,6 +6,7 @@ const { web3 } = require("./web3"); const { Tester, longer } = require("./testHelpers"); const { testAccountRecoveryManager } = require("./contracts/account-recovery/testAccountRecoveryManager"); const { testUpgradeBeaconController } = require("./contracts/upgradeability/testUpgradeBeaconController"); +const { testUpgradeBeaconControllerManagerPartOne, testUpgradeBeaconControllerManagerPartTwo } = require("./contracts/upgradeability/testUpgradeBeaconControllerManager"); const AdharmaSmartWalletImplementationArtifact = require('../../build/contracts/AdharmaSmartWalletImplementation.json') const AdharmaKeyRingImplementationArtifact = require('../../build/contracts/AdharmaKeyRingImplementation.json') @@ -11713,670 +11714,9 @@ async function test(testingContext) { UserSmartWalletV6.options.address ); - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot transfer ownership from a non-owner`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'transferOwnership', - 'send', - [tester.addressTwo], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with null controller`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateUpgrade', - 'send', - [constants.NULL_ADDRESS, tester.address, tester.addressTwo, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with null beacon`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateUpgrade', - 'send', - [tester.address, constants.NULL_ADDRESS, tester.addressTwo, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with null implementation`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateUpgrade', - 'send', - [tester.address, tester.addressTwo, constants.NULL_ADDRESS, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with non-contract implementation`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateUpgrade', - 'send', - [tester.address, tester.addressTwo, tester.address, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with massive extraTime`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateUpgrade', - 'send', - [tester.address, tester.addressTwo, DharmaUpgradeBeaconControllerManager.options.address, constants.FULL_APPROVAL], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can initiate upgrade timelock`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateUpgrade', - 'send', - [tester.address, tester.addressTwo, DharmaUpgradeBeaconControllerManager.options.address, 0] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can get an empty timelock`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'getTimelock', - 'call', - ['0x01020304', '0x'], - true, - value => { - assert.ok(!value.exists) - assert.ok(!value.completed) - assert.ok(!value.expired) - assert.strictEqual(value.completionTime, '0') - assert.strictEqual(value.expirationTime, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can get an empty default timelock interval`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'getDefaultTimelockInterval', - 'call', - ['0x01020304'], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can get an empty default timelock expiration`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'getDefaultTimelockExpiration', - 'call', - ['0x01020304'], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot upgrade before timelock is complete`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'upgrade', - 'send', - [tester.address, tester.addressTwo, DharmaUpgradeBeaconControllerManager.options.address], - false - ) - - // advance time by 7 days - await tester.advanceTime((60 * 60 * 24 * 7) + 5) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot upgrade an unowned controller`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'upgrade', - 'send', - [tester.address, tester.addressTwo, DharmaUpgradeBeaconControllerManager.options.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot transfer controller ownership before accepting ownership`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'transferControllerOwnership', - 'send', - [tester.address, tester.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot agree to accept ownership of null controller`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'agreeToAcceptControllerOwnership', - 'send', - [constants.NULL_ADDRESS, true], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can agree to accept ownership`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'agreeToAcceptControllerOwnership', - 'send', - [tester.address, true] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate controller ownership transfer with null controller`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateTransferControllerOwnership', - 'send', - [constants.NULL_ADDRESS, tester.addressTwo, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate controller ownership transfer with null new owner`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateTransferControllerOwnership', - 'send', - [tester.address, constants.NULL_ADDRESS, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate controller ownership transfer if new owner has not accepted`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateTransferControllerOwnership', - 'send', - [tester.address, tester.addressTwo, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can initiate controller ownership transfer if new owner has accepted`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateTransferControllerOwnership', - 'send', - [tester.address, tester.address, 0] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot transfer controller ownership prior to timelock completion`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'transferControllerOwnership', - 'send', - [tester.address, tester.address], - false - ) - - // advance time by 4 weeks - await tester.advanceTime((60 * 60 * 24 * 7 * 4) + 5) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot transfer unowned controller ownership`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'transferControllerOwnership', - 'send', - [tester.address, tester.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot heartbeat from non-heartbeater`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'heartbeat', - 'send', - [], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can heartbeat`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'heartbeat' - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot set new heartbeater to null address`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'newHeartbeater', - 'send', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner can set new heartbeater`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'newHeartbeater', - 'send', - [tester.address] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot arm Adharma Contingency from non-owner when not expired`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'armAdharmaContingency', - 'send', - [true], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when not armed`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'activateAdharmaContingency', - 'send', - [], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner can arm an Adharma Contingency`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'armAdharmaContingency', - 'send', - [true] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner can disarm Adharma Contingency`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'armAdharmaContingency', - 'send', - [false] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner can re-arm Adharma Contingency`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'armAdharmaContingency', - 'send', - [true] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency from non-owner when not expired`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'activateAdharmaContingency', - 'send', - [], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when it doesn't own controllers`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'activateAdharmaContingency', - 'send', - [], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot roll back prior to first upgrade`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'rollback', - 'send', - [tester.address, tester.address, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot exit Adharma Contingency when not active`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'exitAdharmaContingency', - 'send', - [tester.address, tester.address], - false - ) - - /* - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can activate Adharma Contingency`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'activateAdharmaContingency', - 'send', - [] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner cannot arm Adharma Contingency while active`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'armAdharmaContingency', - 'send', - [true] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot activate Contingency when activated`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'activateAdharmaContingency', - 'send', - [], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner can disarm Adharma Contingency`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'armAdharmaContingency', - 'send', - [false] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot exit Contingency before 48 hours`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'exitAdharmaContingency', - 'send', - [ - DharmaSmartWalletImplementationV6.options.address, - DharmaKeyRingImplementationV1.options.address - ], - false - ) - - // advance time by 2 days - await tester.advanceTime((60 * 60 * 24 * 2) + 5) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot exit Contingency to null address`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'exitAdharmaContingency', - 'send', - [constants.NULL_ADDRESS, DharmaKeyRingImplementationV1.options.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot exit Contingency to non-contract address`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'exitAdharmaContingency', - 'send', - [address, address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can exit Contingency after 48 hours`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'exitAdharmaContingency', - 'send', - [ - DharmaSmartWalletImplementationV6.options.address, - DharmaKeyRingImplementationV1.options.address - ] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner can arm Adharma Contingency again`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'armAdharmaContingency', - 'send', - [true] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can activate fake Adharma Contingency again`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'activateAdharmaContingency', - 'send', - [] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can roll back from fake Adharma Contingency`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'rollback', - 'send', - [constants.UPGRADE_BEACON_CONTROLLER_ADDRESS, constants.UPGRADE_BEACON_ADDRESS, 0] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can "roll forward" after roll back`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'rollback', - 'send', - [constants.UPGRADE_BEACON_ADDRESS, constants.UPGRADE_BEACON_ADDRESS] - ) - */ - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can get heartbeat status`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'heartbeatStatus', - 'call', - [], - true, - value => { - assert.ok(!value.expired) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager get contingency status when armed but not activated`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'contingencyStatus', - 'call', - [], - true, - value => { - assert.ok(value.armed) - assert.ok(!value.activated) - assert.strictEqual(value.activationTime, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager gets 0 for non-existent total implementations`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'getTotalPriorImplementations', - 'call', - [tester.address, tester.address], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot get a prior implementation with no index`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'getPriorImplementation', - 'call', - [tester.address, tester.address, 100], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot rollback to implementation with no index`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'rollback', - 'send', - [tester.address, tester.address, 100], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot block rollback to implementation with no index`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'blockRollback', - 'send', - [tester.address, tester.address, 100], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockInterval with no selector`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateModifyTimelockInterval', - 'send', - ['0x00000000', 0, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockInterval to modify interval over 8 weeks`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 5443200, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot create timelock with excessive duration`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', constants.FULL_APPROVAL, 0], - false // TODO: move this outside of Controller manager - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockInterval to set a timelock`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 10000, 5] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot shorten existing initiateModifyTimelockInterval timelock`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 10000, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockInterval to change a duration`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 10001, 5] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockInterval to set a timelock on another function`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateModifyTimelockInterval', - 'send', - ['0xaaaaaaaa', 10000, 0] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockInterval with no selector`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'modifyTimelockInterval', - 'send', - ['0x00000000', 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockInterval before timelock completion`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'modifyTimelockInterval', - 'send', - ['0xe950c085', 1000], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockExpiration with no selector`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0x00000000', 0, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockExpiration to with expiration over one month`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0xe950c085', 5443200, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockExpiration to modify expiration under one minute`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 30, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockExpiration to set a timelock`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 300000, 0], - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockExpiration to set a timelock on another function`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateModifyTimelockExpiration', - 'send', - ['0xe950c085', 30, 0] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockExpiration with no selector`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'modifyTimelockExpiration', - 'send', - ['0x00000000', 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockExpiration before timelock completion`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'modifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 300], - false - ) - - // advance time by 4 weeks - await tester.advanceTime((60 * 60 * 24 * 7 * 4) + 5) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call modifyTimelockInterval`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'modifyTimelockInterval', - 'send', - ['0xaaaaaaaa', 10000] - ) - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call modifyTimelockExpiration`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'modifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 300000], - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockExpiration if expiration is too short`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'modifyTimelockExpiration', - 'send', - ['0xe950c085', 30], - false + await testUpgradeBeaconControllerManagerPartOne( + tester, DharmaUpgradeBeaconControllerManagerCoverage ) const MockDharmaKeyRingFactory = await tester.runTest( @@ -14026,347 +13366,15 @@ async function test(testingContext) { } ) - // Transfer smart wallet controller ownership to coverage manager - await tester.runTest( - `DharmaUpgradeBeaconController can transfer ownership to manager`, - DharmaUpgradeBeaconController, - 'transferOwnership', - 'send', - [DharmaUpgradeBeaconControllerManagerCoverage.options.address] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when it doesn't own keyring controller`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'activateAdharmaContingency', - 'send', - [], - false - ) - - await tester.runTest( - `DharmaKeyRingUpgradeBeaconController can transfer ownership to manager`, - DharmaKeyRingUpgradeBeaconController, - 'transferOwnership', - 'send', - [DharmaUpgradeBeaconControllerManagerCoverage.options.address] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can activate Adharma Contingency`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'activateAdharmaContingency' - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can get contingency status when activated`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'contingencyStatus', - 'call', - [], - true, - value => { - assert.ok(!value.armed) - assert.ok(value.activated) - //assert.strictEqual(value.activationTime, '?') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner can re-arm an active Adharma Contingency`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'armAdharmaContingency', - 'send', - [true] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when already active`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'activateAdharmaContingency', - 'send', - [], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager now gets a prior implementation count`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'getTotalPriorImplementations', - 'call', - [ - DharmaUpgradeBeaconController.options.address, - DharmaUpgradeBeacon.options.address - ], - true, - value => { - assert.strictEqual(value, '1') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can get the initial prior implementation`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'getPriorImplementation', - 'call', - [ - DharmaUpgradeBeaconController.options.address, - DharmaUpgradeBeacon.options.address, - 0 - ], - true, - value => { - assert.strictEqual( - value.priorImplementation, - AdharmaSmartWalletImplementation.options.address - ) - assert.ok(value.rollbackAllowed) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call "exitAdharmaContingency" before 48 hours has elapsed`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'exitAdharmaContingency', - 'send', - [ - tester.address, - tester.address - ], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can rollback to initial prior implementation`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'rollback', - 'send', - [ - DharmaUpgradeBeaconController.options.address, - DharmaUpgradeBeacon.options.address, - 0 - ] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager contingency status is exited after rollback`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'contingencyStatus', - 'call', - [], - true, - value => { - assert.ok(!value.armed) - assert.ok(!value.activated) - assert.strictEqual(value.activationTime, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot rollback to implementation with no index`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'rollback', - 'send', - [tester.address, tester.address, 100], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner can re-arm an Adharma Contingency`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'armAdharmaContingency', - 'send', - [true] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager contingency status shows armed`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'contingencyStatus', - 'call', - [], - true, - value => { - assert.ok(value.armed) - assert.ok(!value.activated) - assert.strictEqual(value.activationTime, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can rollback to initial prior implementation`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'rollback', - 'send', - [ - DharmaUpgradeBeaconController.options.address, - DharmaUpgradeBeacon.options.address, - 0 - ] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager contingency status shows no longer armed`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'contingencyStatus', - 'call', - [], - true, - value => { - assert.ok(!value.armed) - assert.ok(!value.activated) - assert.strictEqual(value.activationTime, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can block rollback to prior implementation`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'blockRollback', - 'send', - [ - DharmaUpgradeBeaconController.options.address, - DharmaUpgradeBeacon.options.address, - 0 - ] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot block a blocked rollback`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'blockRollback', - 'send', - [ - DharmaUpgradeBeaconController.options.address, - DharmaUpgradeBeacon.options.address, - 0 - ], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot rollback to a blocked rollback`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'rollback', - 'send', - [ - DharmaUpgradeBeaconController.options.address, + await testUpgradeBeaconControllerManagerPartTwo( + tester, + DharmaUpgradeBeaconControllerManagerCoverage, + DharmaUpgradeBeaconController, + DharmaKeyRingUpgradeBeaconController, DharmaUpgradeBeacon.options.address, - 0 - ], - false - ) - - // advance time by 90 days - await tester.advanceTime((60 * 60 * 24 * 90) + 5) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager deadman switch can arm an Adharma Contingency`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'armAdharmaContingency', - 'send', - [true], - true, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager deadman switch can activate an Adharma Contingency`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'activateAdharmaContingency', - 'send', - [], - true, - receipt => {}, - tester.originalAddress - ) - - // advance time by 2 days - await tester.advanceTime((60 * 60 * 24 * 2) + 5) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call exitAdharmaContingency with null implementation`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'exitAdharmaContingency', - 'send', - [ - constants.NULL_ADDRESS, - tester.address - ], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call exitAdharmaContingency with non-contract implementation`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'exitAdharmaContingency', - 'send', - [ - tester.address, - tester.address - ], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call exitAdharmaContingency`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'exitAdharmaContingency', - 'send', - [ - DharmaSmartWalletImplementationV6.options.address, + AdharmaSmartWalletImplementation.options.address, + DharmaSmartWalletImplementationV7.options.address, DharmaKeyRingImplementationV1.options.address - ] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can have an EOA accept controller ownership`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'agreeToAcceptControllerOwnership', - 'send', - [ - DharmaUpgradeBeaconController.options.address, - true - ] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can initiate timelock for transferring controller ownership`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'initiateTransferControllerOwnership', - 'send', - [ - DharmaUpgradeBeaconController.options.address, - tester.address, - 0 - ] - ) - - // advance time by 4 weeks - await tester.advanceTime((60 * 60 * 24 * 7 * 4) + 5) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can transfer controller ownership`, - DharmaUpgradeBeaconControllerManagerCoverage, - 'transferControllerOwnership', - 'send', - [ - DharmaUpgradeBeaconController.options.address, - tester.address - ] - ) - - await tester.runTest( - `DharmaUpgradeBeaconController can get new owner`, - DharmaUpgradeBeaconController, - 'isOwner', - 'call', - [], - true, - value => { - assert.ok(value) - } ) console.log( From 99718526e34156074f8840394940183ffbdf9b0a Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Fri, 7 Feb 2020 08:02:17 -0800 Subject: [PATCH 22/47] refactor multisig deployers --- ...stDharmaAccountRecoveryMultisigDeployer.js | 60 +++++ ...AccountRecoveryOperatorMultisigDeployer.js | 52 +++++ .../testDharmaKeyRegistryMultisigDeployer.js | 60 +++++ .../testDharmaUpgradeMultisigDeployer.js | 60 +++++ scripts/test/deploy.js | 217 +----------------- 5 files changed, 241 insertions(+), 208 deletions(-) create mode 100644 scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryMultisigDeployer.js create mode 100644 scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryOperatorMultisigDeployer.js create mode 100644 scripts/test/contracts/multisig-deployers/testDharmaKeyRegistryMultisigDeployer.js create mode 100644 scripts/test/contracts/multisig-deployers/testDharmaUpgradeMultisigDeployer.js diff --git a/scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryMultisigDeployer.js b/scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryMultisigDeployer.js new file mode 100644 index 0000000..980ac9e --- /dev/null +++ b/scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryMultisigDeployer.js @@ -0,0 +1,60 @@ +async function testDharmaAccountRecoveryMultisigDeployer(tester, contract) { + await tester.runTest( + `DharmaAccountRecoveryMultisig contract deployment fails if threshold is not met`, + contract, + '', + 'deploy', + [[ + '0x0000000000000000000000000000000000000001' + ]], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryMultisig contract deployment fails if sigs are out of order`, + contract, + '', + 'deploy', + [[ + '0x0000000000000000000000000000000000000005', + '0x0000000000000000000000000000000000000002', + '0x0000000000000000000000000000000000000003', + '0x0000000000000000000000000000000000000004', + '0x0000000000000000000000000000000000000001' + ]], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryMultisig contract deployment fails with too many owners`, + contract, + '', + 'deploy', + [[ + '0x0000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000002', + '0x0000000000000000000000000000000000000003', + '0x0000000000000000000000000000000000000004', + '0x0000000000000000000000000000000000000005', + '0x0000000000000000000000000000000000000006', + '0x0000000000000000000000000000000000000007', + '0x0000000000000000000000000000000000000008', + '0x0000000000000000000000000000000000000009', + '0x000000000000000000000000000000000000000a', + '0x000000000000000000000000000000000000000b' + ]], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryMultisig contract deployment`, + contract, + '', + 'deploy', + [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour]] + ) +} + +module.exports = { + testDharmaAccountRecoveryMultisigDeployer, +}; diff --git a/scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryOperatorMultisigDeployer.js b/scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryOperatorMultisigDeployer.js new file mode 100644 index 0000000..e6f0a9c --- /dev/null +++ b/scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryOperatorMultisigDeployer.js @@ -0,0 +1,52 @@ +async function testDharmaAccountRecoveryOperatorMultisigDeployer(tester, contract) { + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig contract deployment fails if threshold is not met`, + contract, + '', + 'deploy', + [[ + '0x0000000000000000000000000000000000000001' + ]], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig contract deployment fails if sigs are out of order`, + contract, + '', + 'deploy', + [[ + '0x0000000000000000000000000000000000000005', + '0x0000000000000000000000000000000000000002', + '0x0000000000000000000000000000000000000003', + '0x0000000000000000000000000000000000000004', + '0x0000000000000000000000000000000000000001' + ]], + false + ) + + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig contract deployment fails with too many owners`, + contract, + '', + 'deploy', + [[ + '0x0000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000002', + '0x0000000000000000000000000000000000000003', + '0x0000000000000000000000000000000000000004', + '0x0000000000000000000000000000000000000005', + '0x0000000000000000000000000000000000000006', + '0x0000000000000000000000000000000000000007', + '0x0000000000000000000000000000000000000008', + '0x0000000000000000000000000000000000000009', + '0x000000000000000000000000000000000000000a', + '0x000000000000000000000000000000000000000b' + ]], + false + ) +} + +module.exports = { + testDharmaAccountRecoveryOperatorMultisigDeployer, +}; diff --git a/scripts/test/contracts/multisig-deployers/testDharmaKeyRegistryMultisigDeployer.js b/scripts/test/contracts/multisig-deployers/testDharmaKeyRegistryMultisigDeployer.js new file mode 100644 index 0000000..1978046 --- /dev/null +++ b/scripts/test/contracts/multisig-deployers/testDharmaKeyRegistryMultisigDeployer.js @@ -0,0 +1,60 @@ +async function testDharmaKeyRegistryMultisigDeployer(tester, contract) { + await tester.runTest( + `DharmaKeyRegistryMultisig contract deployment fails if threshold is not met`, + contract, + '', + 'deploy', + [[ + '0x0000000000000000000000000000000000000001' + ]], + false + ) + + await tester.runTest( + `DharmaKeyRegistryMultisig contract deployment fails if sigs are out of order`, + contract, + '', + 'deploy', + [[ + '0x0000000000000000000000000000000000000005', + '0x0000000000000000000000000000000000000002', + '0x0000000000000000000000000000000000000003', + '0x0000000000000000000000000000000000000004', + '0x0000000000000000000000000000000000000001' + ]], + false + ) + + await tester.runTest( + `DharmaKeyRegistryMultisig contract deployment fails with too many owners`, + contract, + '', + 'deploy', + [[ + '0x0000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000002', + '0x0000000000000000000000000000000000000003', + '0x0000000000000000000000000000000000000004', + '0x0000000000000000000000000000000000000005', + '0x0000000000000000000000000000000000000006', + '0x0000000000000000000000000000000000000007', + '0x0000000000000000000000000000000000000008', + '0x0000000000000000000000000000000000000009', + '0x000000000000000000000000000000000000000a', + '0x000000000000000000000000000000000000000b' + ]], + false + ) + + await tester.runTest( + `DharmaKeyRegistryMultisig contract deployment`, + contract, + '', + 'deploy', + [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] + ) +} + +module.exports = { + testDharmaKeyRegistryMultisigDeployer, +}; diff --git a/scripts/test/contracts/multisig-deployers/testDharmaUpgradeMultisigDeployer.js b/scripts/test/contracts/multisig-deployers/testDharmaUpgradeMultisigDeployer.js new file mode 100644 index 0000000..2562050 --- /dev/null +++ b/scripts/test/contracts/multisig-deployers/testDharmaUpgradeMultisigDeployer.js @@ -0,0 +1,60 @@ +async function testDharmaUpgradeMultisigDeployer(tester, contract) { + await tester.runTest( + `DharmaUpgradeMultisig contract deployment fails if threshold is not met`, + contract, + '', + 'deploy', + [[ + '0x0000000000000000000000000000000000000001' + ]], + false + ) + + await tester.runTest( + `DharmaUpgradeMultisig contract deployment fails if sigs are out of order`, + contract, + '', + 'deploy', + [[ + '0x0000000000000000000000000000000000000005', + '0x0000000000000000000000000000000000000002', + '0x0000000000000000000000000000000000000003', + '0x0000000000000000000000000000000000000004', + '0x0000000000000000000000000000000000000001' + ]], + false + ) + + await tester.runTest( + `DharmaUpgradeMultisig contract deployment fails with too many owners`, + contract, + '', + 'deploy', + [[ + '0x0000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000002', + '0x0000000000000000000000000000000000000003', + '0x0000000000000000000000000000000000000004', + '0x0000000000000000000000000000000000000005', + '0x0000000000000000000000000000000000000006', + '0x0000000000000000000000000000000000000007', + '0x0000000000000000000000000000000000000008', + '0x0000000000000000000000000000000000000009', + '0x000000000000000000000000000000000000000a', + '0x000000000000000000000000000000000000000b' + ]], + false + ) + + await tester.runTest( + `DharmaUpgradeMultisig contract deployment`, + contract, + '', + 'deploy', + [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] + ) +} + +module.exports = { + testDharmaUpgradeMultisigDeployer, +}; diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index abaf13c..b8ec901 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -5,6 +5,10 @@ const constants = require('./constants.js') const { web3 } = require("./web3"); const { Tester, swapMetadataHash, newContractAndSwapMetadataHash } = require("./testHelpers"); const { testIndestructibleRegistry } = require("./contracts/indestructible-registry/testIndestructibleRegistry"); +const { testDharmaUpgradeMultisigDeployer } = require("./contracts/multisig-deployers/testDharmaUpgradeMultisigDeployer"); +const { testDharmaAccountRecoveryMultisigDeployer } = require("./contracts/multisig-deployers/testDharmaAccountRecoveryMultisigDeployer"); +const { testDharmaAccountRecoveryOperatorMultisigDeployer } = require("./contracts/multisig-deployers/testDharmaAccountRecoveryOperatorMultisigDeployer"); +const { testDharmaKeyRegistryMultisigDeployer } = require("./contracts/multisig-deployers/testDharmaKeyRegistryMultisigDeployer"); let DharmaUpgradeBeaconArtifact; let DharmaUpgradeBeaconControllerArtifact; @@ -1345,163 +1349,13 @@ async function test(testingContext) { 'deploy' ) - await tester.runTest( - `DharmaAccountRecoveryMultisig contract deployment fails if threshold is not met`, - DharmaAccountRecoveryMultisigDeployer, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001' - ]], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig contract deployment fails if sigs are out of order`, - DharmaAccountRecoveryMultisigDeployer, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000001' - ]], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig contract deployment fails with too many owners`, - DharmaAccountRecoveryMultisigDeployer, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000006', - '0x0000000000000000000000000000000000000007', - '0x0000000000000000000000000000000000000008', - '0x0000000000000000000000000000000000000009', - '0x000000000000000000000000000000000000000a', - '0x000000000000000000000000000000000000000b' - ]], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig contract deployment fails if threshold is not met`, - DharmaAccountRecoveryOperatorMultisigDeployer, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001' - ]], - false - ) + await testDharmaAccountRecoveryMultisigDeployer(tester, DharmaAccountRecoveryMultisigDeployer); - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig contract deployment fails if sigs are out of order`, - DharmaAccountRecoveryOperatorMultisigDeployer, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000001' - ]], - false - ) + await testDharmaAccountRecoveryOperatorMultisigDeployer(tester, DharmaAccountRecoveryOperatorMultisigDeployer); - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig contract deployment fails with too many owners`, - DharmaAccountRecoveryOperatorMultisigDeployer, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000006', - '0x0000000000000000000000000000000000000007', - '0x0000000000000000000000000000000000000008', - '0x0000000000000000000000000000000000000009', - '0x000000000000000000000000000000000000000a', - '0x000000000000000000000000000000000000000b' - ]], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig contract deployment`, - DharmaAccountRecoveryMultisigDeployer, - '', - 'deploy', - [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour]] - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig contract deployment fails if threshold is not met`, - DharmaKeyRegistryMultisigDeployer, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001' - ]], - false - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig contract deployment fails if sigs are out of order`, - DharmaKeyRegistryMultisigDeployer, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000001' - ]], - false - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig contract deployment fails with too many owners`, - DharmaKeyRegistryMultisigDeployer, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000006', - '0x0000000000000000000000000000000000000007', - '0x0000000000000000000000000000000000000008', - '0x0000000000000000000000000000000000000009', - '0x000000000000000000000000000000000000000a', - '0x000000000000000000000000000000000000000b' - ]], - false - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig contract deployment`, - DharmaKeyRegistryMultisigDeployer, - '', - 'deploy', - [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] - ) + await testDharmaKeyRegistryMultisigDeployer(tester, DharmaKeyRegistryMultisigDeployer); +// await tester.runTest( `DharmaUpgradeBeaconControllerManager contract deployment fails before indestructible registration`, DharmaUpgradeBeaconControllerManagerCoverageDeployer, @@ -1609,60 +1463,7 @@ async function test(testingContext) { await testIndestructibleRegistry(tester, testIndestructibleRegistryContracts); - await tester.runTest( - `DharmaUpgradeMultisig contract deployment fails if threshold is not met`, - DharmaUpgradeMultisigDeployer, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001' - ]], - false - ) - - await tester.runTest( - `DharmaUpgradeMultisig contract deployment fails if sigs are out of order`, - DharmaUpgradeMultisigDeployer, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000001' - ]], - false - ) - - await tester.runTest( - `DharmaUpgradeMultisig contract deployment fails with too many owners`, - DharmaUpgradeMultisigDeployer, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000006', - '0x0000000000000000000000000000000000000007', - '0x0000000000000000000000000000000000000008', - '0x0000000000000000000000000000000000000009', - '0x000000000000000000000000000000000000000a', - '0x000000000000000000000000000000000000000b' - ]], - false - ) - - await tester.runTest( - `DharmaUpgradeMultisig contract deployment`, - DharmaUpgradeMultisigDeployer, - '', - 'deploy', - [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] - ) + await testDharmaUpgradeMultisigDeployer(tester, DharmaUpgradeMultisigDeployer); await tester.runTest( `DharmaUpgradeBeaconControllerManager contract deployment`, From 45613fa2c2609ae56183aa3cf3be093db379e775 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Fri, 7 Feb 2020 11:18:19 -0500 Subject: [PATCH 23/47] move key registry tests to new file --- .../contracts/registries/testKeyRegistryV2.js | 331 ++++++++++++++++++ scripts/test/test.js | 313 +---------------- 2 files changed, 334 insertions(+), 310 deletions(-) create mode 100644 scripts/test/contracts/registries/testKeyRegistryV2.js diff --git a/scripts/test/contracts/registries/testKeyRegistryV2.js b/scripts/test/contracts/registries/testKeyRegistryV2.js new file mode 100644 index 0000000..fab044d --- /dev/null +++ b/scripts/test/contracts/registries/testKeyRegistryV2.js @@ -0,0 +1,331 @@ +const { web3 } = require("../../web3"); +const constants = require("../../constants"); +const assert = require("assert"); + +async function testKeyRegistryV2( + tester, + contract, + unownedKeyRegistryAddress +) { + await tester.runTest( + 'Dharma Key Registry V2 gets the initial global key correctly', + contract, + 'getGlobalKey', + 'call', + [], + true, + value => { + assert.strictEqual(value, tester.address) + } + ) + + await tester.runTest( + 'Dharma Key Registry V2 attempt to get an unset specific key throws', + contract, + 'getSpecificKey', + 'call', + [tester.address], + false + ) + + await tester.runTest( + 'Dharma Key Registry V2 gets the global key when requesting unset key', + contract, + 'getKey', + 'call', + [], + true, + value => { + assert.strictEqual(value, tester.address) + } + ) + + await tester.runTest( + 'Dharma Key Registry V2 cannot set a new empty global key', + contract, + 'setGlobalKey', + 'send', + [ + constants.NULL_ADDRESS, + '0x' + ], + false, + receipt => {}, + tester.originalAddress + ) + + const message = ( + contract.options.address + + tester.addressTwo.slice(2) + + web3.utils.asciiToHex( + "This signature demonstrates that the supplied signing key is valid." + ).slice(2) + ) + + const newKeySignature = tester.signHashedPrefixedHashedHexString( + message, tester.addressTwo + ) + + const badNewKeySignature = tester.signHashedPrefixedHashedHexString( + '0x12', tester.addressTwo + ) + + await tester.runTest( + 'Dharma Key Registry V2 cannot set a new global key unless called by owner', + contract, + 'setGlobalKey', + 'send', + [ + tester.addressTwo, + newKeySignature + ], + false, + receipt => {}, + tester.addressTwo + ) + + await tester.runTest( + 'Dharma Key Registry V2 cannot set an empty global key', + contract, + 'setGlobalKey', + 'send', + [ + constants.NULL_ADDRESS, + newKeySignature + ], + false + ) + + await tester.runTest( + 'Dharma Key Registry V2 cannot set a new global key with a bad signature', + contract, + 'setGlobalKey', + 'send', + [ + tester.addressTwo, + badNewKeySignature + ], + false + ) + + await tester.runTest( + 'Dharma Key Registry V2 can set a new global key correctly', + contract, + 'setGlobalKey', + 'send', + [ + tester.addressTwo, + newKeySignature + ] + ) + + await tester.runTest( + 'Dharma Key Registry V2 gets the new global key correctly', + contract, + 'getGlobalKey', + 'call', + [], + true, + value => { + assert.strictEqual(value, tester.addressTwo) + } + ) + + await tester.runTest( + 'Dharma Key Registry V2 cannot set a new specific key unless called by owner', + contract, + 'setSpecificKey', + 'send', + [ + tester.address, + unownedKeyRegistryAddress + ], + false, + receipt => {}, + tester.originalAddress + ) + + await tester.runTest( + 'Dharma Key Registry V2 gets global key for a user if no specific key set', + contract, + 'getKeyForUser', + 'call', + [tester.address], + true, + value => { + assert.strictEqual(value, tester.addressTwo) + } + ) + + await tester.runTest( + 'Dharma Key Registry V2 can set a new specific key', + contract, + 'setSpecificKey', + 'send', + [ + tester.address, + unownedKeyRegistryAddress + ] + ) + + await tester.runTest( + 'Dharma Key Registry V2 gets specific key for user if one is set', + contract, + 'getKeyForUser', + 'call', + [tester.address], + true, + value => { + assert.strictEqual(value, unownedKeyRegistryAddress) + } + ) + + await tester.runTest( + 'Dharma Key Registry V2 gets the new specific key correctly', + contract, + 'getSpecificKey', + 'call', + [tester.address], + true, + value => { + assert.strictEqual(value, unownedKeyRegistryAddress) + } + ) + + await tester.runTest( + 'Dharma Key Registry V2 gets the specific key when requesting set key', + contract, + 'getKey', + 'call', + [], + true, + value => { + assert.strictEqual(value, unownedKeyRegistryAddress) + } + ) + + await tester.runTest( + 'Dharma Key Registry V2 cannot reuse a specific key', + contract, + 'setSpecificKey', + 'send', + [ + tester.address, + unownedKeyRegistryAddress + ], + false + ) + + await tester.runTest( + 'Dharma Key Registry V2 new owner cannot accept ownership before added', + contract, + 'acceptOwnership', + 'send', + [], + false + ) + + await tester.runTest( + 'Dharma Key Registry V2 cannot prepare to transfer to the null address', + contract, + 'transferOwnership', + 'send', + [ + constants.NULL_ADDRESS + ], + false + ) + + await tester.runTest( + 'Dharma Key Registry V2 can prepare to transfer to a new owner', + contract, + 'transferOwnership', + 'send', + [ + tester.address + ] + ) + + await tester.runTest( + 'Dharma Key Registry V2 can cancel an ownership transfer', + contract, + 'cancelOwnershipTransfer' + ) + + await tester.runTest( + 'Dharma Key Registry V2 new owner cannot accept ownership after cancellation', + contract, + 'acceptOwnership', + 'send', + [], + false + ) + + await tester.runTest( + 'Dharma Key Registry V2 can prepare to transfer to a new owner again', + contract, + 'transferOwnership', + 'send', + [ + tester.address + ] + ) + + await tester.runTest( + 'Dharma Key Registry V2 new owner can accept ownership', + contract, + 'acceptOwnership' + ) + + await tester.runTest( + 'Dharma Key Registry V2 gets the new owner', + contract, + 'owner', + 'call', + [], + true, + value => { + assert.strictEqual(value, tester.address) + } + ) + + await tester.runTest( + 'Dharma Key Registry V2 gets the global key correctly', + contract, + 'getGlobalKey', + 'call', + [], + true, + value => { + assert.strictEqual(value, tester.addressTwo) + } + ) + + const messageV2 = ( + contract.options.address + + tester.address.slice(2) + + web3.utils.asciiToHex( + "This signature demonstrates that the supplied signing key is valid." + ).slice(2) + ) + + const v2KeySignature = tester.signHashedPrefixedHashedHexString( + messageV2, tester.address + ) + + await tester.runTest( + 'Dharma Key Registry V2 cannot set a previously used global key', + contract, + 'setGlobalKey', + 'send', + [ + tester.address, + v2KeySignature + ], + false + ) +} + +module.exports = { + testKeyRegistryV2 +}; \ No newline at end of file diff --git a/scripts/test/test.js b/scripts/test/test.js index a51b7eb..c542867 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -7,6 +7,7 @@ const { Tester, longer } = require("./testHelpers"); const { testAccountRecoveryManager } = require("./contracts/account-recovery/testAccountRecoveryManager"); const { testUpgradeBeaconController } = require("./contracts/upgradeability/testUpgradeBeaconController"); const { testUpgradeBeaconControllerManagerPartOne, testUpgradeBeaconControllerManagerPartTwo } = require("./contracts/upgradeability/testUpgradeBeaconControllerManager"); +const { testKeyRegistryV2 } = require("./contracts/registries/testKeyRegistryV2"); const AdharmaSmartWalletImplementationArtifact = require('../../build/contracts/AdharmaSmartWalletImplementation.json') const AdharmaKeyRingImplementationArtifact = require('../../build/contracts/AdharmaKeyRingImplementation.json') @@ -11389,316 +11390,8 @@ async function test(testingContext) { } */ - await tester.runTest( - 'Dharma Key Registry V2 gets the initial global key correctly', - DharmaKeyRegistryV2Coverage, - 'getGlobalKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 attempt to get an unset specific key throws', - DharmaKeyRegistryV2Coverage, - 'getSpecificKey', - 'call', - [tester.address], - false - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets the global key when requesting unset key', - DharmaKeyRegistryV2Coverage, - 'getKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 cannot set a new empty global key', - DharmaKeyRegistryV2Coverage, - 'setGlobalKey', - 'send', - [ - constants.NULL_ADDRESS, - '0x' - ], - false, - receipt => {}, - tester.originalAddress - ) - - const messageCoverage = ( - DharmaKeyRegistryV2Coverage.options.address + - tester.addressTwo.slice(2) + - web3.utils.asciiToHex( - "This signature demonstrates that the supplied signing key is valid." - ).slice(2) - ) - - const newKeySignatureCoverage = tester.signHashedPrefixedHashedHexString(messageCoverage, tester.addressTwo) - - const badNewKeySignatureCoverage = tester.signHashedPrefixedHashedHexString('0x12', tester.addressTwo) - - await tester.runTest( - 'Dharma Key Registry V2 cannot set a new global key unless called by owner', - DharmaKeyRegistryV2Coverage, - 'setGlobalKey', - 'send', - [ - tester.addressTwo, - newKeySignatureCoverage - ], - false, - receipt => {}, - tester.addressTwo - ) - - await tester.runTest( - 'Dharma Key Registry V2 cannot set an empty global key', - DharmaKeyRegistryV2Coverage, - 'setGlobalKey', - 'send', - [ - constants.NULL_ADDRESS, - newKeySignatureCoverage - ], - false - ) - - await tester.runTest( - 'Dharma Key Registry V2 cannot set a new global key with a bad signature', - DharmaKeyRegistryV2Coverage, - 'setGlobalKey', - 'send', - [ - tester.addressTwo, - badNewKeySignatureCoverage - ], - false - ) - - await tester.runTest( - 'Dharma Key Registry V2 can set a new global key correctly', - DharmaKeyRegistryV2Coverage, - 'setGlobalKey', - 'send', - [ - tester.addressTwo, - newKeySignatureCoverage - ] - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets the new global key correctly', - DharmaKeyRegistryV2Coverage, - 'getGlobalKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.addressTwo) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 cannot set a new specific key unless called by owner', - DharmaKeyRegistryV2Coverage, - 'setSpecificKey', - 'send', - [ - tester.address, - DharmaKeyRegistryV2.options.address - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets global key for a user if no specific key set', - DharmaKeyRegistryV2Coverage, - 'getKeyForUser', - 'call', - [tester.address], - true, - value => { - assert.strictEqual(value, tester.addressTwo) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 can set a new specific key', - DharmaKeyRegistryV2Coverage, - 'setSpecificKey', - 'send', - [ - tester.address, - DharmaKeyRegistryV2.options.address - ] - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets specific key for user if one is set', - DharmaKeyRegistryV2Coverage, - 'getKeyForUser', - 'call', - [tester.address], - true, - value => { - assert.strictEqual(value, DharmaKeyRegistryV2.options.address) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets the new specific key correctly', - DharmaKeyRegistryV2Coverage, - 'getSpecificKey', - 'call', - [tester.address], - true, - value => { - assert.strictEqual(value, DharmaKeyRegistryV2.options.address) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets the specific key when requesting set key', - DharmaKeyRegistryV2Coverage, - 'getKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, DharmaKeyRegistryV2.options.address) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 cannot reuse a specific key', - DharmaKeyRegistryV2Coverage, - 'setSpecificKey', - 'send', - [ - tester.address, - DharmaKeyRegistryV2.options.address - ], - false - ) - - await tester.runTest( - 'Dharma Key Registry V2 new owner cannot accept ownership before added', - DharmaKeyRegistryV2Coverage, - 'acceptOwnership', - 'send', - [], - false - ) - - await tester.runTest( - 'Dharma Key Registry V2 cannot prepare to transfer to the null address', - DharmaKeyRegistryV2Coverage, - 'transferOwnership', - 'send', - [ - constants.NULL_ADDRESS - ], - false - ) - - await tester.runTest( - 'Dharma Key Registry V2 can prepare to transfer to a new owner', - DharmaKeyRegistryV2Coverage, - 'transferOwnership', - 'send', - [ - tester.address - ] - ) - - await tester.runTest( - 'Dharma Key Registry V2 can cancel an ownership transfer', - DharmaKeyRegistryV2Coverage, - 'cancelOwnershipTransfer' - ) - - await tester.runTest( - 'Dharma Key Registry V2 new owner cannot accept ownership after cancellation', - DharmaKeyRegistryV2Coverage, - 'acceptOwnership', - 'send', - [], - false - ) - - await tester.runTest( - 'Dharma Key Registry V2 can prepare to transfer to a new owner again', - DharmaKeyRegistryV2Coverage, - 'transferOwnership', - 'send', - [ - tester.address - ] - ) - - await tester.runTest( - 'Dharma Key Registry V2 new owner can accept ownership', - DharmaKeyRegistryV2Coverage, - 'acceptOwnership' - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets the new owner', - DharmaKeyRegistryV2Coverage, - 'owner', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets the global key correctly', - DharmaKeyRegistryV2Coverage, - 'getGlobalKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.addressTwo) - } - ) - - const messageV2Coverage = ( - DharmaKeyRegistryV2Coverage.options.address + - tester.address.slice(2) + - web3.utils.asciiToHex( - "This signature demonstrates that the supplied signing key is valid." - ).slice(2) - ) - - const v2KeySignatureCoverage = tester.signHashedPrefixedHashedHexString(messageV2Coverage, tester.address) - - await tester.runTest( - 'Dharma Key Registry V2 cannot set a previously used global key', - DharmaKeyRegistryV2Coverage, - 'setGlobalKey', - 'send', - [ - tester.address, - v2KeySignatureCoverage - ], - false + await testKeyRegistryV2( + tester, DharmaKeyRegistryV2Coverage, DharmaKeyRegistryV2.options.address ) const DharmaAccountRecoveryManagerV2Coverage = await tester.runTest( From e8b653435db9e3cf3258b8501a283c89b301da90 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Fri, 7 Feb 2020 13:06:54 -0500 Subject: [PATCH 24/47] refactor implementation upgrades --- .../upgradeability/testPerformingUpgrade.js | 177 +++++++ scripts/test/deploy.js | 100 +--- scripts/test/test.js | 500 ++---------------- scripts/test/testHelpers.js | 55 ++ 4 files changed, 298 insertions(+), 534 deletions(-) create mode 100644 scripts/test/contracts/upgradeability/testPerformingUpgrade.js diff --git a/scripts/test/contracts/upgradeability/testPerformingUpgrade.js b/scripts/test/contracts/upgradeability/testPerformingUpgrade.js new file mode 100644 index 0000000..50c5fe9 --- /dev/null +++ b/scripts/test/contracts/upgradeability/testPerformingUpgrade.js @@ -0,0 +1,177 @@ +const constants = require("../../constants"); +const assert = require("assert"); + +async function testPerformingUpgrade( + tester, + contract, // new implementation + userSmartWalletContract, + upgradeBeaconControllerContract, + upgradeBeaconAddress, + newImplementationVersion +) { + let nonce; + let userSigningKey; + let oldImplementation; + let oldImplementationCodeHash; + let newImplementationCodeHash; + + await tester.runTest( + 'User Smart Wallet can check the user signing key prior to upgrade', + userSmartWalletContract, + 'getUserSigningKey', + 'call', + [], + true, + value => { + userSigningKey = value + } + ) + + await tester.runTest( + 'User Smart Wallet can get the nonce prior to upgrade', + userSmartWalletContract, + 'getNonce', + 'call', + [], + true, + value => { + nonce = value + } + ) + + await tester.runTest( + 'DharmaUpgradeBeacon current implementation can be retrieved', + upgradeBeaconControllerContract, + 'getImplementation', + 'call', + [upgradeBeaconAddress], + true, + value => { + oldImplementation = value; + } + ) + + await tester.runTest( + 'Old implementation code hash can be retrieved', + tester.MockCodeCheck, + 'hash', + 'call', + [oldImplementation], + true, + value => { + oldImplementationCodeHash = value; + } + ) + + await tester.runTest( + 'New implementation code hash can be retrieved', + tester.MockCodeCheck, + 'hash', + 'call', + [contract.options.address], + true, + value => { + newImplementationCodeHash = value; + } + ) + + await tester.runTest( + `Dharma Upgrade Beacon Controller can upgrade to V${newImplementationVersion.toString()} implementation`, + upgradeBeaconControllerContract, + 'upgrade', + 'send', + [ + upgradeBeaconAddress, + contract.options.address + ], + true, + receipt => { + if (tester.context !== 'coverage') { + assert.strictEqual( + receipt.events.Upgraded.returnValues.upgradeBeacon, + upgradeBeaconAddress + ) + + assert.strictEqual( + receipt.events.Upgraded.returnValues.oldImplementation, + oldImplementation + ) + assert.strictEqual( + receipt.events.Upgraded.returnValues.oldImplementationCodeHash, + oldImplementationCodeHash + ) + + assert.strictEqual( + receipt.events.Upgraded.returnValues.newImplementation, + contract.options.address + ) + assert.strictEqual( + receipt.events.Upgraded.returnValues.newImplementationCodeHash, + newImplementationCodeHash + ) + } + } + ) + + await tester.runTest( + 'DharmaUpgradeBeacon has the new implementation set', + upgradeBeaconControllerContract, + 'getImplementation', + 'call', + [upgradeBeaconAddress], + true, + value => { + assert.strictEqual(value, contract.options.address) + } + ) + + await tester.runTest( + `UpgradeBeaconImplementationCheck deployment`, + tester.UpgradeBeaconImplementationCheckDeployer, + '', + 'deploy', + [ + upgradeBeaconAddress, contract.options.address + ] + ) + + await tester.runTest( + `V${newImplementationVersion.toString()} user smart wallet still has the same user signing key set`, + userSmartWalletContract, + 'getUserSigningKey', + 'call', + [], + true, + value => { + assert.strictEqual(value, userSigningKey) + } + ) + + await tester.runTest( + `V${newImplementationVersion.toString()} User Smart Wallet can get the new version (${newImplementationVersion.toString()})`, + userSmartWalletContract, + 'getVersion', + 'call', + [], + true, + value => { + assert.strictEqual(value, newImplementationVersion.toString()) + } + ) + + await tester.runTest( + `V${newImplementationVersion.toString()} User Smart Wallet nonce is still set to value from before upgrade`, + userSmartWalletContract, + 'getNonce', + 'call', + [], + true, + value => { + assert.strictEqual(value, nonce) + } + ) +} + +module.exports = { + testPerformingUpgrade +}; \ No newline at end of file diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index b8ec901..8c79804 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -467,11 +467,6 @@ async function test(testingContext) { constants.IMMUTABLE_CREATE2_FACTORY_ADDRESS ) - const MockCodeCheckDeployer = new web3.eth.Contract( - MockCodeCheckArtifact.abi - ) - MockCodeCheckDeployer.options.data = MockCodeCheckArtifact.bytecode - // construct the payload passed to create2 in order to verify correct behavior const testCreate2payload = ( '0xff' + @@ -491,12 +486,6 @@ async function test(testingContext) { ).slice(12).substring(14) ) - const MockCodeCheckTwo = new web3.eth.Contract( - MockCodeCheckArtifact.abi, - targetCodeCheckAddress - ) - - const tester = new Tester(testingContext); await tester.init(); @@ -511,47 +500,10 @@ async function test(testingContext) { console.log('running tests...') - const MockCodeCheck = await tester.runTest( - `MockCodeCheck contract deployment`, - MockCodeCheckDeployer, - '', - 'deploy' - ) - - await tester.runTest( - 'Deployed MockCodeCheck code is correct', - MockCodeCheck, - 'code', - 'call', - [MockCodeCheck.options.address], - true, - value => { - assert.strictEqual(value, MockCodeCheckArtifact.deployedBytecode) - } - ) - - await tester.runTest( - 'Deployed MockCodeCheck has correct extcodehash', - MockCodeCheck, - 'hash', - 'call', - [MockCodeCheck.options.address], - true, - value => { - assert.strictEqual( - value, - web3.utils.keccak256( - MockCodeCheckArtifact.deployedBytecode, - {encoding: 'hex'} - ) - ) - } - ) - let currentKeylessCreate2Runtime; await tester.runTest( 'Current runtime code at address of initial create2 factory can be retrieved', - MockCodeCheck, + tester.MockCodeCheck, 'code', 'call', [constants.KEYLESS_CREATE2_ADDRESS], @@ -587,7 +539,7 @@ async function test(testingContext) { let currentInefficientImmutableCreate2FactoryRuntimeHash; await tester.runTest( 'Current runtime hash at address of inefficient immutable create2 factory can be retrieved', - MockCodeCheck, + tester.MockCodeCheck, 'hash', 'call', [constants.INEFFICIENT_IMMUTABLE_CREATE2_FACTORY_ADDRESS], @@ -619,7 +571,7 @@ async function test(testingContext) { let currentImmutableCreate2FactoryRuntimeHash; await tester.runTest( 'Current runtime hash at address of immutable create2 factory can be retrieved', - MockCodeCheck, + tester.MockCodeCheck, 'hash', 'call', [constants.IMMUTABLE_CREATE2_FACTORY_ADDRESS], @@ -649,7 +601,7 @@ async function test(testingContext) { let currentIndestructibleRegistryRuntimeHash; await tester.runTest( 'Current runtime hash at address of indestructible registry can be retrieved', - MockCodeCheck, + tester.MockCodeCheck, 'hash', 'call', [constants.INDESTRUCTIBLE_REGISTRY_ADDRESS], @@ -703,7 +655,7 @@ async function test(testingContext) { constants.UPGRADE_BEACON_ENVOY_SALT, constants.UPGRADE_BEACON_ENVOY_RUNTIME_CODE, constants.UPGRADE_BEACON_ENVOY_CREATION_CODE, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -725,7 +677,7 @@ async function test(testingContext) { constants.UPGRADE_BEACON_CONTROLLER_SALT, upgradeBeaconControllerRuntimeCode, upgradeBeaconControllerCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -747,7 +699,7 @@ async function test(testingContext) { constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_SALT, keyRingUpgradeBeaconControllerRuntimeCode, keyRingUpgradeBeaconControllerCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -785,7 +737,7 @@ async function test(testingContext) { constants.UPGRADE_BEACON_SALT, upgradeBeaconRuntimeCode, upgradeBeaconCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -815,7 +767,7 @@ async function test(testingContext) { constants.KEY_RING_UPGRADE_BEACON_SALT, keyRingUpgradeBeaconRuntimeCode, keyRingUpgradeBeaconCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -844,7 +796,7 @@ async function test(testingContext) { constants.KEY_REGISTRY_SALT, keyRegistryRuntimeCode, keyRegistryCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -866,7 +818,7 @@ async function test(testingContext) { constants.KEY_REGISTRY_V2_SALT, keyRegistryV2RuntimeCode, keyRegistryV2CreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -888,7 +840,7 @@ async function test(testingContext) { constants.NULL_BYTES_32, revertReasonHelperRuntimeCode, revertReasonHelperCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -910,7 +862,7 @@ async function test(testingContext) { constants.ESCAPE_HATCH_REGISTRY_SALT, escapeHatchRegistryRuntimeCode, escapeHatchRegistryCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -1018,7 +970,7 @@ async function test(testingContext) { constants.ACCOUNT_RECOVERY_MANAGER_V2_SALT, accountRecoveryManagerRuntimeCode, accountRecoveryManagerCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -1047,7 +999,7 @@ async function test(testingContext) { constants.FACTORY_SALT, dharmaSmartWalletFactoryRuntimeCode, dharmaSmartWalletFactoryCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -1077,7 +1029,7 @@ async function test(testingContext) { constants.KEY_RING_FACTORY_V2_SALT, keyRingFactoryRuntimeCode, keyRingFactoryCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -1106,7 +1058,7 @@ async function test(testingContext) { constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_SALT, adharmaSmartWalletImplementationRuntimeCode, adharmaSmartWalletImplementationCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -1128,7 +1080,7 @@ async function test(testingContext) { constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_SALT, dharmaDaiUpgradeBeaconControllerRuntimeCode, dharmaDaiUpgradeBeaconControllerCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -1150,7 +1102,7 @@ async function test(testingContext) { constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_SALT, dharmaUSDCUpgradeBeaconControllerRuntimeCode, dharmaUSDCUpgradeBeaconControllerCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -1171,7 +1123,7 @@ async function test(testingContext) { constants.DHARMA_DAI_UPGRADE_BEACON_SALT, dharmaDaiUpgradeBeaconRuntimeCode, dharmaDaiUpgradeBeaconCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -1192,7 +1144,7 @@ async function test(testingContext) { constants.DHARMA_USDC_UPGRADE_BEACON_SALT, dharmaUSDCUpgradeBeaconRuntimeCode, dharmaUSDCUpgradeBeaconCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -1214,7 +1166,7 @@ async function test(testingContext) { constants.DHARMA_DAI_SALT, dharmaDaiRuntimeCode, dharmaDaiCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -1235,7 +1187,7 @@ async function test(testingContext) { constants.DHARMA_USDC_SALT, dharmaUSDCRuntimeCode, dharmaUSDCCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -1337,7 +1289,7 @@ async function test(testingContext) { constants.ADHARMA_KEY_RING_IMPLEMENTATION_SALT, adharmaKeyRingImplementationRuntimeCode, adharmaKeyRingImplementationCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -1446,7 +1398,7 @@ async function test(testingContext) { constants.UPGRADE_BEACON_CONTROLLER_MANAGER_SALT, upgradeBeaconControllerManagerRuntimeCode, upgradeBeaconControllerManagerCreationCode, - MockCodeCheck, + tester.MockCodeCheck, ImmutableCreate2Factory ); @@ -1482,7 +1434,7 @@ async function test(testingContext) { let currentSaiCode; await tester.runTest( 'Checking for required external contracts...', - MockCodeCheck, + tester.MockCodeCheck, 'code', 'call', [constants.SAI_MAINNET_ADDRESS], diff --git a/scripts/test/test.js b/scripts/test/test.js index c542867..e09589c 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -8,6 +8,7 @@ const { testAccountRecoveryManager } = require("./contracts/account-recovery/tes const { testUpgradeBeaconController } = require("./contracts/upgradeability/testUpgradeBeaconController"); const { testUpgradeBeaconControllerManagerPartOne, testUpgradeBeaconControllerManagerPartTwo } = require("./contracts/upgradeability/testUpgradeBeaconControllerManager"); const { testKeyRegistryV2 } = require("./contracts/registries/testKeyRegistryV2"); +const { testPerformingUpgrade } = require("./contracts/upgradeability/testPerformingUpgrade"); const AdharmaSmartWalletImplementationArtifact = require('../../build/contracts/AdharmaSmartWalletImplementation.json') const AdharmaKeyRingImplementationArtifact = require('../../build/contracts/AdharmaKeyRingImplementation.json') @@ -51,7 +52,6 @@ const BadBeaconArtifact = require('../../build/contracts/BadBeacon.json') const BadBeaconTwoArtifact = require('../../build/contracts/BadBeaconTwo.json') const TimelockEdgecaseTesterArtifact = require('../../build/contracts/TimelockEdgecaseTester.json') -const MockCodeCheckArtifact = require('../../build/contracts/MockCodeCheck.json') const MockDharmaKeyRingFactoryArtifact = require('../../build/contracts/MockDharmaKeyRingFactory.json') const IERC20Artifact = require('../../build/contracts/IERC20.json') const ComptrollerArtifact = require('../../build/contracts/ComptrollerInterface.json') @@ -231,11 +231,6 @@ async function test(testingContext) { TimelockEdgecaseTesterArtifact.bytecode ) - const MockCodeCheckDeployer = new web3.eth.Contract( - MockCodeCheckArtifact.abi - ) - MockCodeCheckDeployer.options.data = MockCodeCheckArtifact.bytecode - const DharmaUpgradeBeaconControllerDeployer = new web3.eth.Contract( DharmaUpgradeBeaconControllerArtifact.abi ) @@ -376,7 +371,6 @@ async function test(testingContext) { DharmaEscapeHatchRegistryArtifact.bytecode ) - const tester = new Tester(testingContext); await tester.init(); @@ -390,13 +384,6 @@ async function test(testingContext) { [tester.address] ) - const MockCodeCheck = await tester.runTest( - `MockCodeCheck contract deployment`, - MockCodeCheckDeployer, - '', - 'deploy' - ) - await tester.runTest( 'Dharma Key Registry V1 gets the initial global key correctly', DharmaKeyRegistryV1, @@ -943,7 +930,7 @@ async function test(testingContext) { let currentSaiCode; await tester.runTest( 'Checking for required external contracts...', - MockCodeCheck, + tester.MockCodeCheck, 'code', 'call', [constants.SAI_MAINNET_ADDRESS], @@ -1888,266 +1875,44 @@ async function test(testingContext) { false ) - let originalNonce + let originalNonce; await tester.runTest( - 'UserSmartWallet can get the nonce prior to upgrade', + 'UserSmartWallet nonce can be retrieved', UserSmartWallet, 'getNonce', 'call', [], true, value => { - originalNonce = value - } - ) - - await tester.runTest( - 'Dharma Upgrade Beacon Controller can upgrade to V1 implementation', - DharmaUpgradeBeaconController, - 'upgrade', - 'send', - [ - DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV1.options.address - ], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Upgraded.returnValues.upgradeBeacon, - DharmaUpgradeBeacon.options.address - ) - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementation, - DharmaSmartWalletImplementationV0.options.address - ) - /* TODO - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementationCodeHash, - constants.EMPTY_HASH - ) - */ - assert.strictEqual( - receipt.events.Upgraded.returnValues.newImplementation, - DharmaSmartWalletImplementationV1.options.address - ) - /* TODO - assert.strictEqual( - receipt.events.Upgraded.returnValues.newImplementationCodeHash, - ... - ) - */ - } - } - ) - - const UpgradeBeaconImplementationCheckV1 = await tester.runTest( - `UpgradeBeaconImplementationCheck deployment`, - UpgradeBeaconImplementationCheckDeployer, - '', - 'deploy', - [ - DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV1.options.address - ] - ) - - await tester.runTest( - 'DharmaUpgradeBeacon has the implementation set', - DharmaUpgradeBeaconController, - 'getImplementation', - 'call', - [DharmaUpgradeBeacon.options.address], - true, - value => { - assert.strictEqual(value, DharmaSmartWalletImplementationV1.options.address) + originalNonce = value; } ) - await tester.runTest( - 'Dharma Upgrade Beacon Controller can upgrade to V2 implementation', - DharmaUpgradeBeaconController, - 'upgrade', - 'send', - [ - DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV2.options.address - ], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Upgraded.returnValues.upgradeBeacon, - DharmaUpgradeBeacon.options.address - ) - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementation, - DharmaSmartWalletImplementationV1.options.address - ) - /* TODO - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementationCodeHash, - constants.EMPTY_HASH - ) - */ - assert.strictEqual( - receipt.events.Upgraded.returnValues.newImplementation, - DharmaSmartWalletImplementationV2.options.address - ) - /* TODO - assert.strictEqual( - receipt.events.Upgraded.returnValues.newImplementationCodeHash, - ... - ) - */ - } - } - ) - - const UpgradeBeaconImplementationCheckV2 = await tester.runTest( - `UpgradeBeaconImplementationCheck deployment`, - UpgradeBeaconImplementationCheckDeployer, - '', - 'deploy', - [ + await testPerformingUpgrade( + tester, + DharmaSmartWalletImplementationV1, // new implementation + UserSmartWallet, + DharmaUpgradeBeaconController, DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV2.options.address - ] - ) - - await tester.runTest( - 'DharmaUpgradeBeacon has the implementation set', - DharmaUpgradeBeaconController, - 'getImplementation', - 'call', - [DharmaUpgradeBeacon.options.address], - true, - value => { - assert.strictEqual(value, DharmaSmartWalletImplementationV2.options.address) - } + 1 ) - await tester.runTest( - 'V2 user smart wallet can be called and still has original dharma key set', - UserSmartWallet, - 'getUserSigningKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - 'V2 UserSmartWallet can get the new version (2)', - UserSmartWallet, - 'getVersion', - 'call', - [], - true, - value => { - assert.strictEqual(value, '2') - } - ) - - await tester.runTest( - 'Dharma Upgrade Beacon Controller can upgrade to V5 implementation', - DharmaUpgradeBeaconController, - 'upgrade', - 'send', - [ + await testPerformingUpgrade( + tester, + DharmaSmartWalletImplementationV2, // new implementation + UserSmartWallet, + DharmaUpgradeBeaconController, DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV5.options.address - ], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Upgraded.returnValues.upgradeBeacon, - DharmaUpgradeBeacon.options.address - ) - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementation, - DharmaSmartWalletImplementationV2.options.address - ) - /* TODO - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementationCodeHash, - constants.EMPTY_HASH - ) - */ - assert.strictEqual( - receipt.events.Upgraded.returnValues.newImplementation, - DharmaSmartWalletImplementationV5.options.address - ) - /* TODO - assert.strictEqual( - receipt.events.Upgraded.returnValues.newImplementationCodeHash, - ... - ) - */ - } - } + 2 ) - await tester.runTest( - 'DharmaUpgradeBeacon has the implementation set', - DharmaUpgradeBeaconController, - 'getImplementation', - 'call', - [DharmaUpgradeBeacon.options.address], - true, - value => { - assert.strictEqual(value, DharmaSmartWalletImplementationV5.options.address) - } - ) - - const UpgradeBeaconImplementationCheckV5 = await tester.runTest( - `UpgradeBeaconImplementationCheck deployment`, - UpgradeBeaconImplementationCheckDeployer, - '', - 'deploy', - [ + await testPerformingUpgrade( + tester, + DharmaSmartWalletImplementationV5, // new implementation + UserSmartWallet, + DharmaUpgradeBeaconController, DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV5.options.address - ] - ) - - await tester.runTest( - 'V5 user smart wallet can be called and still has original dharma key set', - UserSmartWalletV5, - 'getUserSigningKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - 'V5 UserSmartWallet can get the new version (5)', - UserSmartWalletV5, - 'getVersion', - 'call', - [], - true, - value => { - assert.strictEqual(value, '5') - } - ) - - await tester.runTest( - 'V5 UserSmartWallet nonce is still set to value from before upgrade', - UserSmartWalletV5, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, originalNonce) - } + 5 ) await tester.runTest( @@ -4869,107 +4634,14 @@ async function test(testingContext) { } ) - // XXXXX - - - - await tester.runTest( - 'Dharma Upgrade Beacon Controller can upgrade to V6 implementation', - DharmaUpgradeBeaconController, - 'upgrade', - 'send', - [ - DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV6.options.address - ], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Upgraded.returnValues.upgradeBeacon, - DharmaUpgradeBeacon.options.address - ) - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementation, - DharmaSmartWalletImplementationV5.options.address - ) - /* TODO - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementationCodeHash, - constants.EMPTY_HASH - ) - */ - assert.strictEqual( - receipt.events.Upgraded.returnValues.newImplementation, - DharmaSmartWalletImplementationV6.options.address - ) - /* TODO - assert.strictEqual( - receipt.events.Upgraded.returnValues.newImplementationCodeHash, - ... - ) - */ - } - } - ) - - await tester.runTest( - 'DharmaUpgradeBeacon has the implementation set', - DharmaUpgradeBeaconController, - 'getImplementation', - 'call', - [DharmaUpgradeBeacon.options.address], - true, - value => { - assert.strictEqual(value, DharmaSmartWalletImplementationV6.options.address) - } - ) - const UpgradeBeaconImplementationCheckV6 = await tester.runTest( - `UpgradeBeaconImplementationCheck deployment`, - UpgradeBeaconImplementationCheckDeployer, - '', - 'deploy', - [ + await testPerformingUpgrade( + tester, + DharmaSmartWalletImplementationV6, // new implementation + UserSmartWallet, + DharmaUpgradeBeaconController, DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV6.options.address - ] - ) - - await tester.runTest( - 'V6 user smart wallet can be called and still has the same dharma key set', - UserSmartWalletV6, - 'getUserSigningKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.originalAddress) - } - ) - - await tester.runTest( - 'V6 UserSmartWallet can get the new version (6)', - UserSmartWalletV6, - 'getVersion', - 'call', - [], - true, - value => { - assert.strictEqual(value, '6') - } - ) - - await tester.runTest( - 'V6 UserSmartWallet nonce is still set to value from before upgrade', - UserSmartWalletV6, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, originalNonce) - } + 6 ) await tester.runTest( @@ -7707,20 +7379,6 @@ async function test(testingContext) { tester.addressTwo ) - // YYYYY - - await tester.runTest( - 'UserSmartWalletV6 can get the nonce prior to upgrade', - UserSmartWalletV6, - 'getNonce', - 'call', - [], - true, - value => { - originalNonce = value - } - ) - await tester.runTest( 'UserSmartWalletV6 can check the user signing key prior to upgrade', UserSmartWalletV6, @@ -7734,102 +7392,24 @@ async function test(testingContext) { ) await tester.runTest( - 'Dharma Upgrade Beacon Controller can upgrade to V7 implementation', - DharmaUpgradeBeaconController, - 'upgrade', - 'send', - [ - DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV7.options.address - ], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Upgraded.returnValues.upgradeBeacon, - DharmaUpgradeBeacon.options.address - ) - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementation, - DharmaSmartWalletImplementationV6.options.address - ) - /* TODO - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementationCodeHash, - constants.EMPTY_HASH - ) - */ - assert.strictEqual( - receipt.events.Upgraded.returnValues.newImplementation, - DharmaSmartWalletImplementationV7.options.address - ) - /* TODO - assert.strictEqual( - receipt.events.Upgraded.returnValues.newImplementationCodeHash, - ... - ) - */ - } - } - ) - - await tester.runTest( - 'DharmaUpgradeBeacon has the implementation set', - DharmaUpgradeBeaconController, - 'getImplementation', - 'call', - [DharmaUpgradeBeacon.options.address], - true, - value => { - assert.strictEqual(value, DharmaSmartWalletImplementationV7.options.address) - } - ) - - const UpgradeBeaconImplementationCheckV7 = await tester.runTest( - `UpgradeBeaconImplementationCheck deployment`, - UpgradeBeaconImplementationCheckDeployer, - '', - 'deploy', - [ - DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV7.options.address - ] - ) - - await tester.runTest( - 'V7 user smart wallet can be called and still has the same dharma key set', - UserSmartWalletV7, - 'getUserSigningKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.addressTwo) - } - ) - - await tester.runTest( - 'V7 UserSmartWallet can get the new version (7)', - UserSmartWalletV7, - 'getVersion', + 'UserSmartWallet nonce can be retrieved', + UserSmartWallet, + 'getNonce', 'call', [], true, value => { - assert.strictEqual(value, '7') + originalNonce = value; } ) - await tester.runTest( - 'V7 UserSmartWallet nonce is still set to value from before upgrade', - UserSmartWalletV7, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, originalNonce) - } + await testPerformingUpgrade( + tester, + DharmaSmartWalletImplementationV7, // new implementation + UserSmartWallet, + DharmaUpgradeBeaconController, + DharmaUpgradeBeacon.options.address, + 7 ) await tester.runTest( diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index db464a6..774a11e 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -3,6 +3,9 @@ const constants = require("./constants"); const assert = require("assert"); const util = require('ethereumjs-util'); +const MockCodeCheckArtifact = require('../../build/contracts/MockCodeCheck.json') +const UpgradeBeaconImplementationCheckArtifact = require('../../build/contracts/UpgradeBeaconImplementationCheck.json') + const SCALING_FACTOR = web3.utils.toBN("1000000000000000000"); const ZERO = web3.utils.toBN("0"); const ONE = web3.utils.toBN("1"); @@ -14,6 +17,16 @@ class Tester { this.context = testingContext; this.failed = 0; this.passed = 0; + + const UpgradeBeaconImplementationCheckDeployer = new web3.eth.Contract( + UpgradeBeaconImplementationCheckArtifact.abi + ); + UpgradeBeaconImplementationCheckDeployer.options.data = ( + UpgradeBeaconImplementationCheckArtifact.bytecode + ); + this.UpgradeBeaconImplementationCheckDeployer = ( + UpgradeBeaconImplementationCheckDeployer + ); } async init() { @@ -53,6 +66,48 @@ class Tester { ); this.gasLimit = latestBlock.gasLimit + + const MockCodeCheckDeployer = new web3.eth.Contract( + MockCodeCheckArtifact.abi + ); + MockCodeCheckDeployer.options.data = MockCodeCheckArtifact.bytecode; + + this.MockCodeCheck = await this.runTest( + `MockCodeCheck contract deployment`, + MockCodeCheckDeployer, + '', + 'deploy' + ) + + await this.runTest( + 'Deployed MockCodeCheck code is correct', + this.MockCodeCheck, + 'code', + 'call', + [this.MockCodeCheck.options.address], + true, + value => { + assert.strictEqual(value, MockCodeCheckArtifact.deployedBytecode) + } + ) + + await this.runTest( + 'Deployed MockCodeCheck has correct extcodehash', + this.MockCodeCheck, + 'hash', + 'call', + [this.MockCodeCheck.options.address], + true, + value => { + assert.strictEqual( + value, + web3.utils.keccak256( + MockCodeCheckArtifact.deployedBytecode, + {encoding: 'hex'} + ) + ) + } + ) } async setupNewDefaultAddress(newPrivateKey) { From 8fb7872c05cc52daa091a39b9cf1139746a8facb Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Fri, 7 Feb 2020 17:05:18 -0500 Subject: [PATCH 25/47] move unused contracts into extra-contracts --- .solcover.js | 6 +- .soliumignore | 2 +- ....sol => MockDharmaDaiImplementationV1.sol} | 0 .../DharmaAccountRecoveryManager.sol | 0 .../DharmaSmartWalletImplementationV0.sol | 0 .../DharmaSmartWalletImplementationV1.sol | 0 .../DharmaSmartWalletImplementationV2.sol | 0 .../DharmaSmartWalletImplementationV5.sol | 0 .../registries/DharmaKeyRegistryV1.sol | 0 scripts/test/constants.js | 54 + .../testIndestructibleRegistry.js | 17 +- .../upgradeability/testPerformingUpgrade.js | 119 +- scripts/test/deploy.js | 33 +- scripts/test/test.js | 4096 +---------------- 14 files changed, 402 insertions(+), 3925 deletions(-) rename contracts/implementations/token/{DharmaDaiImplementationV1.sol => MockDharmaDaiImplementationV1.sol} (100%) rename {contracts => extra-contracts}/account-recovery/DharmaAccountRecoveryManager.sol (100%) rename {contracts => extra-contracts}/implementations/smart-wallet/DharmaSmartWalletImplementationV0.sol (100%) rename {contracts => extra-contracts}/implementations/smart-wallet/DharmaSmartWalletImplementationV1.sol (100%) rename {contracts => extra-contracts}/implementations/smart-wallet/DharmaSmartWalletImplementationV2.sol (100%) rename {contracts => extra-contracts}/implementations/smart-wallet/DharmaSmartWalletImplementationV5.sol (100%) rename {contracts => extra-contracts}/registries/DharmaKeyRegistryV1.sol (100%) diff --git a/.solcover.js b/.solcover.js index 34837de..12fdb55 100644 --- a/.solcover.js +++ b/.solcover.js @@ -1,7 +1,7 @@ module.exports = { norpc: true, testCommand: 'node --max-old-space-size=4096 ./scripts/test/testCoverage.js', - compileCommand: 'node --max-old-space-size=4096 ../node_modules/.bin/truffle compile', + compileCommand: 'node --max-old-space-size=8192 ../node_modules/.bin/truffle compile', copyPackages: ['web3'], skipFiles: [ 'account-recovery/DharmaAccountRecoveryManager.sol', @@ -29,7 +29,7 @@ module.exports = { 'implementations/smart-wallet/DharmaSmartWalletImplementationV6.sol', //'implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol' 'implementations/smart-wallet/DharmaSmartWalletImplementationVX.sol', - 'implementations/token/DharmaDaiImplementationV1.sol', + 'implementations/token/MockDharmaDaiImplementationV1.sol', 'implementations/token/DharmaDaiInitializer.sol', 'implementations/token/DharmaTokenHelpers.sol', 'implementations/token/DharmaTokenOverrides.sol', @@ -52,6 +52,8 @@ module.exports = { 'openzeppelin-upgradeability/upgradeability/ProxyAdmin.sol', 'openzeppelin-upgradeability/upgradeability/UpgradeabilityProxy.sol', 'openzeppelin-upgradeability/utils/Address.sol', + 'proxies/token/DharmaDai.sol', + 'proxies/token/DharmaUSDC.sol', 'registries/DharmaKeyRegistryV1.sol', 'test/BadBeacon.sol', 'test/BadBeaconTwo.sol', diff --git a/.soliumignore b/.soliumignore index d92a017..6ff98f4 100644 --- a/.soliumignore +++ b/.soliumignore @@ -21,7 +21,7 @@ contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV6.sol contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol contracts/implementations/smart-wallet/DharmaSmartWalletImplementationVX.sol -contracts/implementations/token/DharmaDaiImplementationV1.sol +contracts/implementations/token/MockDharmaDaiImplementationV1.sol extra-contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV0.sol extra-contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV1.sol diff --git a/contracts/implementations/token/DharmaDaiImplementationV1.sol b/contracts/implementations/token/MockDharmaDaiImplementationV1.sol similarity index 100% rename from contracts/implementations/token/DharmaDaiImplementationV1.sol rename to contracts/implementations/token/MockDharmaDaiImplementationV1.sol diff --git a/contracts/account-recovery/DharmaAccountRecoveryManager.sol b/extra-contracts/account-recovery/DharmaAccountRecoveryManager.sol similarity index 100% rename from contracts/account-recovery/DharmaAccountRecoveryManager.sol rename to extra-contracts/account-recovery/DharmaAccountRecoveryManager.sol diff --git a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV0.sol b/extra-contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV0.sol similarity index 100% rename from contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV0.sol rename to extra-contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV0.sol diff --git a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV1.sol b/extra-contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV1.sol similarity index 100% rename from contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV1.sol rename to extra-contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV1.sol diff --git a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV2.sol b/extra-contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV2.sol similarity index 100% rename from contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV2.sol rename to extra-contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV2.sol diff --git a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV5.sol b/extra-contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV5.sol similarity index 100% rename from contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV5.sol rename to extra-contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV5.sol diff --git a/contracts/registries/DharmaKeyRegistryV1.sol b/extra-contracts/registries/DharmaKeyRegistryV1.sol similarity index 100% rename from contracts/registries/DharmaKeyRegistryV1.sol rename to extra-contracts/registries/DharmaKeyRegistryV1.sol diff --git a/scripts/test/constants.js b/scripts/test/constants.js index 7bf8075..81a68b0 100644 --- a/scripts/test/constants.js +++ b/scripts/test/constants.js @@ -455,6 +455,60 @@ module.exports = Object.freeze({ '0x00000000001876eB1444c986fD502e618c587430': 'DDAI', '0x0000000000946A7848C50C8f0AE1BB2792602Cb7': 'DUSDC' }, + COMPTROLLER_ABI: [ + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "err", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shortfall", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address[]", + "name": "cTokens", + "type": "address[]" + } + ], + "name": "enterMarkets", + "outputs": [ + { + "internalType": "uint256[]", + "name": "errs", + "type": "uint256[]" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ], EVENT_DETAILS: { // keccak256 of NewUserSigningKey(address) -> userSigningKey '0x7083aac3cab97f1219cedd0ab328a5b138a10b0fc72dd9348f1dc50199b21fda': { diff --git a/scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js b/scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js index e98603e..e170063 100644 --- a/scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js +++ b/scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js @@ -5,10 +5,6 @@ const IndestructibleRegistryArtifact = require('../../../../build/contracts/Inde async function testIndestructibleRegistry(tester, contracts) { const { - DharmaSmartWalletImplementationV0, - DharmaSmartWalletImplementationV1, - DharmaSmartWalletImplementationV2, - DharmaSmartWalletImplementationV5, DharmaSmartWalletImplementationV6, DharmaSmartWalletImplementationV7, DharmaKeyRingImplementationV1, @@ -74,13 +70,14 @@ async function testIndestructibleRegistry(tester, contracts) { ) await tester.runTest( - 'IndestructibleRegistry can register the account recovery manager as indestructible', + 'IndestructibleRegistry can register the account recovery manager V2 as indestructible', IndestructibleRegistry, 'registerAsIndestructible', 'send', [constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS] ) + /* await tester.runTest( 'IndestructibleRegistry can register DharmaKeyRegistryV1 as indestructible', IndestructibleRegistry, @@ -88,6 +85,7 @@ async function testIndestructibleRegistry(tester, contracts) { 'send', [constants.KEY_REGISTRY_ADDRESS] ) + */ await tester.runTest( 'IndestructibleRegistry can register DharmaKeyRegistryV2 as indestructible', @@ -130,6 +128,7 @@ async function testIndestructibleRegistry(tester, contracts) { [constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS] ) + /* await tester.runTest( 'IndestructibleRegistry can register V0 implementation as indestructible', IndestructibleRegistry, @@ -138,7 +137,6 @@ async function testIndestructibleRegistry(tester, contracts) { [DharmaSmartWalletImplementationV0.options.address] ) - /* await runTest( 'IndestructibleRegistry can register V0 key ring implementation as indestructible', IndestructibleRegistry, @@ -148,6 +146,7 @@ async function testIndestructibleRegistry(tester, contracts) { ) */ + /* await tester.runTest( 'IndestructibleRegistry can register V1 implementation as indestructible', IndestructibleRegistry, @@ -155,8 +154,10 @@ async function testIndestructibleRegistry(tester, contracts) { 'send', [DharmaSmartWalletImplementationV1.options.address] ) + */ if (tester.testingContext !== 'coverage') { + /* await tester.runTest( 'IndestructibleRegistry can register V2 implementation as indestructible', IndestructibleRegistry, @@ -165,7 +166,6 @@ async function testIndestructibleRegistry(tester, contracts) { [DharmaSmartWalletImplementationV2.options.address] ) - /* await runTest( 'IndestructibleRegistry can register V3 implementation as indestructible', IndestructibleRegistry, @@ -181,7 +181,7 @@ async function testIndestructibleRegistry(tester, contracts) { 'send', [DharmaSmartWalletImplementationV4.options.address] ) - */ + await tester.runTest( 'IndestructibleRegistry can register V5 implementation as indestructible', @@ -190,6 +190,7 @@ async function testIndestructibleRegistry(tester, contracts) { 'send', [DharmaSmartWalletImplementationV5.options.address] ) + */ await tester.runTest( 'IndestructibleRegistry can register V6 implementation as indestructible', diff --git a/scripts/test/contracts/upgradeability/testPerformingUpgrade.js b/scripts/test/contracts/upgradeability/testPerformingUpgrade.js index 50c5fe9..b5f7d99 100644 --- a/scripts/test/contracts/upgradeability/testPerformingUpgrade.js +++ b/scripts/test/contracts/upgradeability/testPerformingUpgrade.js @@ -7,7 +7,8 @@ async function testPerformingUpgrade( userSmartWalletContract, upgradeBeaconControllerContract, upgradeBeaconAddress, - newImplementationVersion + newImplementationVersion, + initial = false ) { let nonce; let userSigningKey; @@ -15,29 +16,31 @@ async function testPerformingUpgrade( let oldImplementationCodeHash; let newImplementationCodeHash; - await tester.runTest( - 'User Smart Wallet can check the user signing key prior to upgrade', - userSmartWalletContract, - 'getUserSigningKey', - 'call', - [], - true, - value => { - userSigningKey = value - } - ) + if (!initial) { + await tester.runTest( + 'User Smart Wallet can check the user signing key prior to upgrade', + userSmartWalletContract, + 'getUserSigningKey', + 'call', + [], + true, + value => { + userSigningKey = value + } + ) - await tester.runTest( - 'User Smart Wallet can get the nonce prior to upgrade', - userSmartWalletContract, - 'getNonce', - 'call', - [], - true, - value => { - nonce = value - } - ) + await tester.runTest( + 'User Smart Wallet can get the nonce prior to upgrade', + userSmartWalletContract, + 'getNonce', + 'call', + [], + true, + value => { + nonce = value + } + ) + } await tester.runTest( 'DharmaUpgradeBeacon current implementation can be retrieved', @@ -135,41 +138,43 @@ async function testPerformingUpgrade( ] ) - await tester.runTest( - `V${newImplementationVersion.toString()} user smart wallet still has the same user signing key set`, - userSmartWalletContract, - 'getUserSigningKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, userSigningKey) - } - ) - - await tester.runTest( - `V${newImplementationVersion.toString()} User Smart Wallet can get the new version (${newImplementationVersion.toString()})`, - userSmartWalletContract, - 'getVersion', - 'call', - [], - true, - value => { - assert.strictEqual(value, newImplementationVersion.toString()) - } - ) + if (!initial) { + await tester.runTest( + `V${newImplementationVersion.toString()} User Smart Wallet can get the new version (${newImplementationVersion.toString()})`, + userSmartWalletContract, + 'getVersion', + 'call', + [], + true, + value => { + assert.strictEqual(value, newImplementationVersion.toString()) + } + ) + + await tester.runTest( + `V${newImplementationVersion.toString()} user smart wallet still has the same user signing key set`, + userSmartWalletContract, + 'getUserSigningKey', + 'call', + [], + true, + value => { + assert.strictEqual(value, userSigningKey) + } + ) - await tester.runTest( - `V${newImplementationVersion.toString()} User Smart Wallet nonce is still set to value from before upgrade`, - userSmartWalletContract, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, nonce) - } - ) + await tester.runTest( + `V${newImplementationVersion.toString()} User Smart Wallet nonce is still set to value from before upgrade`, + userSmartWalletContract, + 'getNonce', + 'call', + [], + true, + value => { + assert.strictEqual(value, nonce) + } + ) + } } module.exports = { diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index 8c79804..b651129 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -14,7 +14,7 @@ let DharmaUpgradeBeaconArtifact; let DharmaUpgradeBeaconControllerArtifact; let DharmaUpgradeBeaconEnvoyArtifact; let DharmaKeyRingUpgradeBeaconArtifact; -let DharmaKeyRegistryV1Artifact; +//let DharmaKeyRegistryV1Artifact; let DharmaKeyRegistryV2Artifact; let DharmaAccountRecoveryManagerV2Artifact; let DharmaSmartWalletFactoryV1Artifact; @@ -45,12 +45,12 @@ const DharmaAccountRecoveryOperatorMultisigArtifact = require('../../build/contr const DharmaKeyRegistryMultisigArtifact = require('../../build/contracts/DharmaKeyRegistryMultisig.json') const DharmaTestingMultisigArtifact = require('../../build/contracts/DharmaTestingMultisig.json') -const DharmaSmartWalletImplementationV0Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV0.json') -const DharmaSmartWalletImplementationV1Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV1.json') -const DharmaSmartWalletImplementationV2Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV2.json') +//const DharmaSmartWalletImplementationV0Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV0.json') +//const DharmaSmartWalletImplementationV1Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV1.json') +//const DharmaSmartWalletImplementationV2Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV2.json') //const DharmaSmartWalletImplementationV3Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV3.json') //const DharmaSmartWalletImplementationV4Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV4.json') -const DharmaSmartWalletImplementationV5Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV5.json') +//const DharmaSmartWalletImplementationV5Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV5.json') const DharmaSmartWalletImplementationV6Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV6.json') const DharmaSmartWalletImplementationV7Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV7.json') @@ -79,7 +79,7 @@ async function test(testingContext) { DharmaKeyRingUpgradeBeaconArtifact = require('../../../build/contracts/DharmaKeyRingUpgradeBeacon.json') DharmaDaiUpgradeBeaconArtifact = require('../../../build/contracts/DharmaDaiUpgradeBeacon.json') DharmaUSDCUpgradeBeaconArtifact = require('../../../build/contracts/DharmaUSDCUpgradeBeacon.json') - DharmaKeyRegistryV1Artifact = require('../../../build/contracts/DharmaKeyRegistryV1.json') + //DharmaKeyRegistryV1Artifact = require('../../../build/contracts/DharmaKeyRegistryV1.json') DharmaKeyRegistryV2Artifact = require('../../../build/contracts/DharmaKeyRegistryV2.json') DharmaSmartWalletFactoryV1Artifact = require('../../../build/contracts/DharmaSmartWalletFactoryV1.json') DharmaKeyRingFactoryV2Artifact = require('../../../build/contracts/DharmaKeyRingFactoryV2.json') @@ -101,7 +101,7 @@ async function test(testingContext) { DharmaKeyRingUpgradeBeaconArtifact = require('../../build/contracts/DharmaKeyRingUpgradeBeacon.json') DharmaDaiUpgradeBeaconArtifact = require('../../build/contracts/DharmaDaiUpgradeBeacon.json') DharmaUSDCUpgradeBeaconArtifact = require('../../build/contracts/DharmaUSDCUpgradeBeacon.json') - DharmaKeyRegistryV1Artifact = require('../../build/contracts/DharmaKeyRegistryV1.json') + //DharmaKeyRegistryV1Artifact = require('../../build/contracts/DharmaKeyRegistryV1.json') DharmaKeyRegistryV2Artifact = require('../../build/contracts/DharmaKeyRegistryV2.json') DharmaSmartWalletFactoryV1Artifact = require('../../build/contracts/DharmaSmartWalletFactoryV1.json') DharmaKeyRingFactoryV2Artifact = require('../../build/contracts/DharmaKeyRingFactoryV2.json') @@ -157,10 +157,12 @@ async function test(testingContext) { constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS ) + /* const DharmaKeyRegistryV1 = new web3.eth.Contract( DharmaKeyRegistryV1Artifact.abi, constants.KEY_REGISTRY_ADDRESS ) + */ const DharmaKeyRegistryV2 = new web3.eth.Contract( DharmaKeyRegistryV2Artifact.abi, @@ -306,12 +308,14 @@ async function test(testingContext) { UpgradeBeaconProxyV1Artifact.bytecode ) + /* const DharmaKeyRegistryV1Deployer = new web3.eth.Contract( DharmaKeyRegistryV1Artifact.abi ) DharmaKeyRegistryV1Deployer.options.data = ( DharmaKeyRegistryV1Artifact.bytecode ) + */ const DharmaKeyRegistryV2Deployer = new web3.eth.Contract( DharmaKeyRegistryV2Artifact.abi @@ -342,11 +346,11 @@ async function test(testingContext) { AdharmaKeyRingImplementationArtifact ); - const DharmaAccountRecoveryManagerV2Deployer = newContractAndSwapMetadataHash( DharmaAccountRecoveryManagerV2Artifact ); + /* const DharmaSmartWalletImplementationV0Deployer = newContractAndSwapMetadataHash( DharmaSmartWalletImplementationV0Artifact ); @@ -359,7 +363,6 @@ async function test(testingContext) { DharmaSmartWalletImplementationV2Artifact ); - /* const DharmaSmartWalletImplementationV3Deployer = new web3.eth.Contract( DharmaSmartWalletImplementationV3Artifact.abi ) @@ -379,11 +382,11 @@ async function test(testingContext) { ['0000000000000000000000000000000000000000000000000000000000000000'] ) ) - */ const DharmaSmartWalletImplementationV5Deployer = newContractAndSwapMetadataHash( DharmaSmartWalletImplementationV5Artifact ); + */ const DharmaSmartWalletImplementationV6Deployer = newContractAndSwapMetadataHash( DharmaSmartWalletImplementationV6Artifact @@ -780,6 +783,7 @@ async function test(testingContext) { // KeyRegistry + /* const keyRegistryRuntimeCode = swapMetadataHash( DharmaKeyRegistryV1Artifact.deployedBytecode, constants.KEY_REGISTRY_METADATA @@ -799,6 +803,7 @@ async function test(testingContext) { tester.MockCodeCheck, ImmutableCreate2Factory ); + */ // KeyRegistryV2 @@ -868,6 +873,7 @@ async function test(testingContext) { // Dharma Smart Wallet Implementations + /* const DharmaSmartWalletImplementationV0 = await tester.runTest( `DharmaSmartWalletImplementationV0 contract deployment`, DharmaSmartWalletImplementationV0Deployer, @@ -889,7 +895,6 @@ async function test(testingContext) { 'deploy' ) - /* const DharmaSmartWalletImplementationV3 = await runTest( `DharmaSmartWalletImplementationV3 contract deployment`, DharmaSmartWalletImplementationV3Deployer, @@ -903,7 +908,6 @@ async function test(testingContext) { '', 'deploy' ) - */ const DharmaSmartWalletImplementationV5 = await tester.runTest( `DharmaSmartWalletImplementationV5 contract deployment`, @@ -911,6 +915,7 @@ async function test(testingContext) { '', 'deploy' ) + */ const DharmaSmartWalletImplementationV6 = await tester.runTest( `DharmaSmartWalletImplementationV6 contract deployment`, @@ -1404,10 +1409,6 @@ async function test(testingContext) { const testIndestructibleRegistryContracts = { - DharmaSmartWalletImplementationV0, - DharmaSmartWalletImplementationV1, - DharmaSmartWalletImplementationV2, - DharmaSmartWalletImplementationV5, DharmaSmartWalletImplementationV6, DharmaSmartWalletImplementationV7, DharmaKeyRingImplementationV1, diff --git a/scripts/test/test.js b/scripts/test/test.js index e09589c..a9e05b3 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -20,15 +20,11 @@ const DharmaKeyRingUpgradeBeaconArtifact = require('../../build/contracts/Dharma const DharmaUpgradeBeaconEnvoyArtifact = require('../../build/contracts/DharmaUpgradeBeaconEnvoy.json') const DharmaAccountRecoveryManagerV2Artifact = require('../../build/contracts/DharmaAccountRecoveryManagerV2.json') -const DharmaKeyRegistryV1Artifact = require('../../build/contracts/DharmaKeyRegistryV1.json') +//const DharmaKeyRegistryV1Artifact = require('../../build/contracts/DharmaKeyRegistryV1.json') const DharmaKeyRegistryV2Artifact = require('../../build/contracts/DharmaKeyRegistryV2.json') const DharmaSmartWalletFactoryV1Artifact = require('../../build/contracts/DharmaSmartWalletFactoryV1.json') const DharmaSmartWalletFactoryV2Artifact = require('../../build/contracts/DharmaSmartWalletFactoryV2.json') -const DharmaSmartWalletImplementationV0Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV0.json') -const DharmaSmartWalletImplementationV1Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV1.json') -const DharmaSmartWalletImplementationV2Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV2.json') -const DharmaSmartWalletImplementationV5Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV5.json') const DharmaSmartWalletImplementationV6Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV6.json') const DharmaSmartWalletImplementationV7Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV7.json') @@ -54,7 +50,7 @@ const TimelockEdgecaseTesterArtifact = require('../../build/contracts/TimelockEd const MockDharmaKeyRingFactoryArtifact = require('../../build/contracts/MockDharmaKeyRingFactory.json') const IERC20Artifact = require('../../build/contracts/IERC20.json') -const ComptrollerArtifact = require('../../build/contracts/ComptrollerInterface.json') +//const ComptrollerArtifact = require('../../build/contracts/ComptrollerInterface.json') const contractNames = Object.assign({}, constants.CONTRACT_NAMES) @@ -85,10 +81,12 @@ async function test(testingContext) { constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS ) + /* const DharmaKeyRegistryV1 = new web3.eth.Contract( DharmaKeyRegistryV1Artifact.abi, constants.KEY_REGISTRY_ADDRESS ) + */ const DharmaKeyRegistryV2 = new web3.eth.Contract( DharmaKeyRegistryV2Artifact.abi, @@ -106,7 +104,7 @@ async function test(testingContext) { ) const Comptroller = new web3.eth.Contract( - ComptrollerArtifact.abi, + constants.COMPTROLLER_ABI, constants.COMPTROLLER_MAINNET_ADDRESS ) @@ -123,6 +121,41 @@ async function test(testingContext) { constants.CSAI_MAINNET_ADDRESS ) + const FIAT_TOKEN = new web3.eth.Contract( + [ + { + "constant": true, "inputs": [], "name": "blacklister", + "outputs": [{"name": "", "type": "address"}], "payable": false, + "stateMutability": "view", "type": "function" + }, { + "constant": false, "inputs": [{"name": "_account", "type": "address"}], + "name": "unBlacklist", "outputs": [], "payable": false, + "stateMutability": "nonpayable", "type": "function" + }, { + "constant": false, "inputs": [{"name": "_account", "type": "address"}], + "name": "blacklist", "outputs": [], "payable": false, + "stateMutability": "nonpayable", "type": "function" + }, { + "constant": true, "inputs": [{"name": "_account", "type": "address"}], + "name": "isBlacklisted", "outputs": [{"name": "", "type": "bool"}], + "payable": false, "stateMutability": "view", "type": "function" + }, { + "constant": false, "inputs": [], + "name": "pause", "outputs": [], "payable": false, + "stateMutability": "nonpayable", "type": "function" + }, { + "constant": false, "inputs": [], + "name": "unpause", "outputs": [], "payable": false, + "stateMutability": "nonpayable", "type": "function" + }, { + "constant": true, "inputs": [], "name": "pauser", + "outputs": [{"name": "", "type": "address"}], "payable": false, + "stateMutability": "view", "type": "function" + } + ], + constants.USDC_MAINNET_ADDRESS + ) + const SAI = new web3.eth.Contract( IERC20Artifact.abi, constants.SAI_MAINNET_ADDRESS ) @@ -161,34 +194,6 @@ async function test(testingContext) { AdharmaSmartWalletImplementationArtifact.bytecode ) - const DharmaSmartWalletImplementationV0Deployer = new web3.eth.Contract( - DharmaSmartWalletImplementationV0Artifact.abi - ) - DharmaSmartWalletImplementationV0Deployer.options.data = ( - DharmaSmartWalletImplementationV0Artifact.bytecode - ) - - const DharmaSmartWalletImplementationV1Deployer = new web3.eth.Contract( - DharmaSmartWalletImplementationV1Artifact.abi - ) - DharmaSmartWalletImplementationV1Deployer.options.data = ( - DharmaSmartWalletImplementationV1Artifact.bytecode - ) - - const DharmaSmartWalletImplementationV2Deployer = new web3.eth.Contract( - DharmaSmartWalletImplementationV2Artifact.abi - ) - DharmaSmartWalletImplementationV2Deployer.options.data = ( - DharmaSmartWalletImplementationV2Artifact.bytecode - ) - - const DharmaSmartWalletImplementationV5Deployer = new web3.eth.Contract( - DharmaSmartWalletImplementationV5Artifact.abi - ) - DharmaSmartWalletImplementationV5Deployer.options.data = ( - DharmaSmartWalletImplementationV5Artifact.bytecode - ) - const DharmaSmartWalletImplementationV6Deployer = new web3.eth.Contract( DharmaSmartWalletImplementationV6Artifact.abi ) @@ -385,186 +390,7 @@ async function test(testingContext) { ) await tester.runTest( - 'Dharma Key Registry V1 gets the initial global key correctly', - DharmaKeyRegistryV1, - 'getGlobalKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - 'Dharma Key Registry V1 attempt to get an unset specific key throws', - DharmaKeyRegistryV1, - 'getSpecificKey', - 'call', - [tester.address], - false - ) - - await tester.runTest( - 'Dharma Key Registry V1 gets the global key when requesting unset key', - DharmaKeyRegistryV1, - 'getKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - 'Dharma Key Registry V1 cannot set a new empty global key', - DharmaKeyRegistryV1, - 'setGlobalKey', - 'send', - [ - constants.NULL_ADDRESS, - '0x' - ], - false, - receipt => {}, - tester.originalAddress - ) - - const message = ( - DharmaKeyRegistryV1.options.address + - tester.address.slice(2) + - web3.utils.asciiToHex( - "This signature demonstrates that the supplied signing key is valid." - ).slice(2) - ) - - const newKeySignature = tester.signHashedPrefixedHashedHexString(message, tester.address) - - const badNewKeySignature = tester.signHashedPrefixedHashedHexString('0x12', tester.address) - - await tester.runTest( - 'Dharma Key Registry V1 cannot set a new global key unless called by owner', - DharmaKeyRegistryV1, - 'setGlobalKey', - 'send', - [ - tester.address, - newKeySignature - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'Dharma Key Registry V1 cannot set a new global key with a bad signature', - DharmaKeyRegistryV1, - 'setGlobalKey', - 'send', - [ - tester.address, - badNewKeySignature - ], - false - ) - - await tester.runTest( - 'Dharma Key Registry V1 can set a new global key correctly', - DharmaKeyRegistryV1, - 'setGlobalKey', - 'send', - [ - tester.address, - newKeySignature - ] - ) - - await tester.runTest( - 'Dharma Key Registry V1 gets the new global key correctly', - DharmaKeyRegistryV1, - 'getGlobalKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - 'Dharma Key Registry V1 cannot set a new specific key unless called by owner', - DharmaKeyRegistryV1, - 'setSpecificKey', - 'send', - [ - tester.address, - DharmaKeyRegistryV1.options.address - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'Dharma Key Registry V1 can set a new specific key', - DharmaKeyRegistryV1, - 'setSpecificKey', - 'send', - [ - tester.address, - DharmaKeyRegistryV1.options.address - ] - ) - - await tester.runTest( - 'Dharma Key Registry V1 gets the new specific key correctly', - DharmaKeyRegistryV1, - 'getSpecificKey', - 'call', - [tester.address], - true, - value => { - assert.strictEqual(value, DharmaKeyRegistryV1.options.address) - } - ) - - await tester.runTest( - 'Dharma Key Registry V1 gets the specific key when requesting set key', - DharmaKeyRegistryV1, - 'getKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, DharmaKeyRegistryV1.options.address) - } - ) - - await tester.runTest( - 'Dharma Key Registry V1 can set a new owner', - DharmaKeyRegistryV1, - 'transferOwnership', - 'send', - [ - tester.address - ] - ) - - await tester.runTest( - 'Dharma Key Registry V1 gets the new owner', - DharmaKeyRegistryV1, - 'owner', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets the new global key correctly', + 'Dharma Key Registry V2 gets the initial global key correctly', DharmaKeyRegistryV2, 'getGlobalKey', 'call', @@ -611,34 +437,6 @@ async function test(testingContext) { 'deploy' ) - const DharmaSmartWalletImplementationV0 = await tester.runTest( - `DharmaSmartWalletImplementationV0 contract deployment`, - DharmaSmartWalletImplementationV0Deployer, - '', - 'deploy' - ) - - const DharmaSmartWalletImplementationV1 = await tester.runTest( - `DharmaSmartWalletImplementationV1 contract deployment`, - DharmaSmartWalletImplementationV1Deployer, - '', - 'deploy' - ) - - const DharmaSmartWalletImplementationV2 = await tester.runTest( - `DharmaSmartWalletImplementationV2 contract deployment`, - DharmaSmartWalletImplementationV2Deployer, - '', - 'deploy' - ) - - const DharmaSmartWalletImplementationV5 = await tester.runTest( - `DharmaSmartWalletImplementationV5 contract deployment`, - DharmaSmartWalletImplementationV5Deployer, - '', - 'deploy' - ) - const DharmaSmartWalletImplementationV6 = await tester.runTest( `DharmaSmartWalletImplementationV6 contract deployment`, DharmaSmartWalletImplementationV6Deployer, @@ -691,7 +489,7 @@ async function test(testingContext) { 'send', [ BadBeacon.options.address, - DharmaSmartWalletImplementationV0.options.address + DharmaSmartWalletImplementationV6.options.address ], false ) @@ -703,7 +501,7 @@ async function test(testingContext) { 'send', [ BadBeaconTwo.options.address, - DharmaSmartWalletImplementationV0.options.address + DharmaSmartWalletImplementationV6.options.address ], false ) @@ -715,7 +513,7 @@ async function test(testingContext) { 'send', [ DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV0.options.address + DharmaSmartWalletImplementationV6.options.address ], false, receipt => {}, @@ -729,7 +527,7 @@ async function test(testingContext) { 'send', [ DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV0.options.address + DharmaSmartWalletImplementationV6.options.address ], true, receipt => { @@ -748,7 +546,7 @@ async function test(testingContext) { ) assert.strictEqual( receipt.events.Upgraded.returnValues.newImplementation, - DharmaSmartWalletImplementationV0.options.address + DharmaSmartWalletImplementationV6.options.address ) /* TODO assert.strictEqual( @@ -779,7 +577,7 @@ async function test(testingContext) { 'send', [ DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV0.options.address + DharmaSmartWalletImplementationV6.options.address ], true, receipt => { @@ -790,7 +588,7 @@ async function test(testingContext) { ) assert.strictEqual( receipt.events.Upgraded.returnValues.oldImplementation, - DharmaSmartWalletImplementationV0.options.address + DharmaSmartWalletImplementationV6.options.address ) /* TODO assert.strictEqual( @@ -800,7 +598,7 @@ async function test(testingContext) { */ assert.strictEqual( receipt.events.Upgraded.returnValues.newImplementation, - DharmaSmartWalletImplementationV0.options.address + DharmaSmartWalletImplementationV6.options.address ) /* TODO assert.strictEqual( @@ -819,7 +617,7 @@ async function test(testingContext) { 'deploy', [ DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV0.options.address + DharmaSmartWalletImplementationV6.options.address ] ) @@ -831,7 +629,7 @@ async function test(testingContext) { [DharmaUpgradeBeacon.options.address], true, value => { - assert.strictEqual(value, DharmaSmartWalletImplementationV0.options.address) + assert.strictEqual(value, DharmaSmartWalletImplementationV6.options.address) } ) @@ -911,19 +709,19 @@ async function test(testingContext) { ) const DharmaSmartWalletImplementationTest = new web3.eth.Contract( - DharmaSmartWalletImplementationV0Artifact.abi, + DharmaSmartWalletImplementationV6Artifact.abi, DharmaSmartWalletNoFactoryNoConstructor.options.address ) await tester.runTest( 'test passes', DharmaSmartWalletImplementationTest, - 'test', + 'getVersion', 'call', [], true, value => { - assert.ok(value) + assert.ok(value.length > 0) } ) @@ -977,19 +775,19 @@ async function test(testingContext) { ) const DharmaSmartWalletImplementationTestWithConstructor = new web3.eth.Contract( - DharmaSmartWalletImplementationV0Artifact.abi, + DharmaSmartWalletImplementationV6Artifact.abi, DharmaSmartWalletNoFactory.options.address ) await tester.runTest( 'test passes', DharmaSmartWalletImplementationTestWithConstructor, - 'test', + 'getVersion', 'call', [], true, value => { - assert.ok(value) + assert.ok(value.length > 0) } ) @@ -1027,6 +825,26 @@ async function test(testingContext) { } ) + const UserSmartWalletV6 = new web3.eth.Contract( + DharmaSmartWalletImplementationV6Artifact.abi, + targetWalletAddress + ) + + const UserSmartWalletV7 = new web3.eth.Contract( + DharmaSmartWalletImplementationV7Artifact.abi, + targetWalletAddress + ) + + await testPerformingUpgrade( + tester, + DharmaSmartWalletImplementationV6, // new implementation + UserSmartWalletV6, + DharmaUpgradeBeaconController, + DharmaUpgradeBeacon.options.address, + 6, + true + ) + contractNames[DharmaSmartWalletFactoryV1.options.address] = 'Smart Wallet Factory' contractNames[targetWalletAddress] = 'Smart Wallet' @@ -1056,3594 +874,193 @@ async function test(testingContext) { console.log(' ✓ Sai Whale can receive eth if needed') } - if (usdcWhaleBalance === '0') { + if (daiWhaleBalance === '0') { await web3.eth.sendTransaction({ from: tester.address, - to: constants.USDC_WHALE_ADDRESS, + to: constants.DAI_WHALE_ADDRESS, value: web3.utils.toWei('.1', 'ether'), gas: (testingContext !== 'coverage') ? '0x5208' : tester.gasLimit - 1, gasPrice: 1 }) - console.log(' ✓ USDC Whale can receive eth if needed') + console.log(' ✓ Dai Whale can receive eth if needed') } - await web3.eth.sendTransaction({ - from: constants.ETH_WHALE_ADDRESS, - to: targetWalletAddress, - value: web3.utils.toWei('.1', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : tester.gasLimit - 1, - gasPrice: 1 - }) - console.log(' ✓ Eth Whale can deposit eth into the yet-to-be-deployed smart wallet') - - await tester.runTest( - 'Sai Whale can deposit sai into the yet-to-be-deployed smart wallet', - SAI, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'ether')], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.SAI_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'ether') - ) - } - }, - constants.SAI_WHALE_ADDRESS - ) - - await tester.runTest( - 'USDC Whale can deposit usdc into the yet-to-be-deployed smart wallet', - USDC, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.USDC_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'lovelace') - ) - } - }, - constants.USDC_WHALE_ADDRESS - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 cannot deploy a new smart wallet with no key', - DharmaSmartWalletFactoryV1, - 'newSmartWallet', - 'send', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can deploy a new smart wallet using a Dharma Key', - DharmaSmartWalletFactoryV1, - 'newSmartWallet', - 'send', - [tester.address], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - if (typeof log === 'undefined') { - console.log(value) - } - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - - assert.strictEqual(events[0].address, 'Smart Wallet') - assert.strictEqual(events[0].eventName, 'NewUserSigningKey') - assert.strictEqual(events[0].returnValues.userSigningKey, tester.address) - - assert.strictEqual(events[1].address, 'SAI') - assert.strictEqual(events[1].eventName, 'Approval') - assert.strictEqual(events[1].returnValues.value, constants.FULL_APPROVAL) - - assert.strictEqual(events[2].address, 'CSAI') - assert.strictEqual(events[2].eventName, 'AccrueInterest') - - assert.strictEqual(events[3].address, 'SAI') - assert.strictEqual(events[3].eventName, 'Transfer') - assert.strictEqual(events[3].returnValues.value, web3.utils.toWei('100', 'ether')) - - assert.strictEqual(events[4].address, 'CSAI') - assert.strictEqual(events[4].eventName, 'Mint') - assert.strictEqual(events[4].returnValues.mintTokens, web3.utils.toWei('100', 'ether')) - - assert.strictEqual(events[5].address, 'CSAI') - assert.strictEqual(events[5].eventName, 'Transfer') - - assert.strictEqual(events[6].address, 'USDC') - assert.strictEqual(events[6].eventName, 'Approval') - assert.strictEqual(events[6].returnValues.value, constants.FULL_APPROVAL) - - assert.strictEqual(events[7].address, 'CUSDC') - assert.strictEqual(events[7].eventName, 'AccrueInterest') - - assert.strictEqual(events[8].address, 'USDC') - assert.strictEqual(events[8].eventName, 'Transfer') - assert.strictEqual(events[8].returnValues.value, web3.utils.toWei('100', 'lovelace')) - - assert.strictEqual(events[9].address, 'CUSDC') - assert.strictEqual(events[9].eventName, 'Mint') - assert.strictEqual(events[9].returnValues.mintTokens, web3.utils.toWei('100', 'lovelace')) - - assert.strictEqual(events[10].address, 'CUSDC') - assert.strictEqual(events[10].eventName, 'Transfer') - } - } - ) - - const UserSmartWallet = new web3.eth.Contract( - DharmaSmartWalletImplementationV0Artifact.abi, - targetWalletAddress - ) - - const UserSmartWalletV5 = new web3.eth.Contract( - DharmaSmartWalletImplementationV5Artifact.abi, - targetWalletAddress - ) - - const UserSmartWalletV6 = new web3.eth.Contract( - DharmaSmartWalletImplementationV6Artifact.abi, - targetWalletAddress - ) - - const UserSmartWalletV7 = new web3.eth.Contract( - DharmaSmartWalletImplementationV7Artifact.abi, - targetWalletAddress - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 gets a new smart wallet address with same key', - DharmaSmartWalletFactoryV1, - 'getNextSmartWallet', - 'call', - [tester.address], - true, - value => { - // TODO: verify against expected value - assert.ok(targetWalletAddress !== value) - } - ) - - await web3.eth.sendTransaction({ - from: constants.ETH_WHALE_ADDRESS, - to: targetWalletAddress, - value: web3.utils.toWei('100', 'ether'), - gas: (testingContext !== 'coverage') ? '0xffff' : tester.gasLimit - 1, - gasPrice: 1 - }).catch(error => { - console.log(' ✓ Eth Whale can no longer deposit eth into the deployed smart wallet') - }) - - await tester.runTest( - 'Sai Whale can deposit sai into the deployed smart wallet', - SAI, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'ether')], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.SAI_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'ether') - ) - } - }, - constants.SAI_WHALE_ADDRESS - ) - - await tester.runTest( - 'USDC Whale can deposit usdc into the deployed smart wallet', - USDC, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.USDC_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'lovelace') - ) - } - }, - constants.USDC_WHALE_ADDRESS - ) - - await tester.runTest( - 'new user smart wallet can trigger repayAndDeposit to deposit all new funds', - UserSmartWallet, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - - assert.strictEqual(events[0].address, 'CSAI') - assert.strictEqual(events[0].eventName, 'AccrueInterest') - - assert.strictEqual(events[1].address, 'SAI') - assert.strictEqual(events[1].eventName, 'Transfer') - assert.strictEqual(events[1].returnValues.value, web3.utils.toWei('100', 'ether')) - - assert.strictEqual(events[2].address, 'CSAI') - assert.strictEqual(events[2].eventName, 'Mint') - assert.strictEqual(events[2].returnValues.mintTokens, web3.utils.toWei('100', 'ether')) - - assert.strictEqual(events[3].address, 'CSAI') - assert.strictEqual(events[3].eventName, 'Transfer') - - assert.strictEqual(events[4].address, 'CUSDC') - assert.strictEqual(events[4].eventName, 'AccrueInterest') - - assert.strictEqual(events[5].address, 'USDC') - assert.strictEqual(events[5].eventName, 'Transfer') - assert.strictEqual(events[5].returnValues.value, web3.utils.toWei('100', 'lovelace')) - - assert.strictEqual(events[6].address, 'CUSDC') - assert.strictEqual(events[6].eventName, 'Mint') - assert.strictEqual(events[6].returnValues.mintTokens, web3.utils.toWei('100', 'lovelace')) - - assert.strictEqual(events[7].address, 'CUSDC') - assert.strictEqual(events[7].eventName, 'Transfer') - } - } - ) - - await tester.runTest( - 'new user smart wallet can trigger repayAndDeposit even with no funds', - UserSmartWallet, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - - assert.strictEqual(events.length, 0) - } - } - ) - - await tester.runTest( - 'test passes', - UserSmartWallet, - 'test', - 'call', - [], - true, - value => { - assert.ok(value) - } - ) - - // TODO: wrap in a contract to validate revert reason - await tester.runTest( - 'revert test with revert reason passes', - UserSmartWallet, - 'testRevert', - 'call', - [], - false // set this to true to verify that the revert reason is displayed - ) - - await tester.runTest( - 'new user smart wallet can be called and has the correct dharma key set', - UserSmartWallet, - 'getUserSigningKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - 'UserSmartWallet can get the version (0)', - UserSmartWallet, - 'getVersion', - 'call', - [], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - 'UserSmartWallet nonce is initially set to 0', - UserSmartWallet, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - 'UserSmartWallet can get balances', - UserSmartWallet, - 'getBalances', - 'call', - [], - true, - value => { - //console.log(value) - } - ) - - await tester.runTest( - 'UserSmartWallet secondary can call to withdraw sai', - UserSmartWallet, - 'withdrawDai', - 'send', - [ - '1000000000000000000', - tester.address, - 0, - '0x', - '0x' - ], - true, - receipt => { - // TODO: verify logs - if (testingContext !== 'coverage') { - //console.log(receipt.events) - } - //console.log(receipt.events.ExternalError.returnValues) - //console.log(receipt.events.ExternalError) - /* - console.log(Object.values(receipt.events).map(value => { - return ( - value.raw - ) - })) - */ - } - ) - - await tester.runTest( - 'UserSmartWallet nonce is now set to 1', - UserSmartWallet, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, '1') - } - ) - - await tester.runTest( - 'UserSmartWallet secondary can call to withdraw usdc', - UserSmartWallet, - 'withdrawUSDC', - 'send', - [ - 1, - tester.address, - 0, - '0x', - '0x' - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - } - ) - - await tester.runTest( - 'UserSmartWallet nonce is now set to 2', - UserSmartWallet, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, '2') - } - ) - - await tester.runTest( - 'UserSmartWallet secondary can call to cancel', - UserSmartWallet, - 'cancel', - 'send', - [ - 0, - '0x' - ] - ) - - await tester.runTest( - 'UserSmartWallet nonce is now set to 3', - UserSmartWallet, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, '3') - } - ) - - await tester.runTest( - 'UserSmartWallet secondary can call to set userSigningKey', - UserSmartWallet, - 'setUserSigningKey', - 'send', - [ - tester.address, - 0, - '0x', - '0x' - ] - ) - - await tester.runTest( - 'UserSmartWallet nonce is now set to 4', - UserSmartWallet, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, '4') - } - ) - - let customActionId - await tester.runTest( - 'UserSmartWallet can get next custom action ID', - UserSmartWallet, - 'getNextCustomActionID', - 'call', - [ - 4, // SAIWithdrawal, - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - await tester.runTest( - 'UserSmartWallet can get custom action ID 4 and it matches next action ID', - UserSmartWallet, - 'getCustomActionID', - 'call', - [ - 4, // SAIWithdrawal, - constants.FULL_APPROVAL, - tester.address, - 4, - 0 - ], - true, - value => { - assert.strictEqual(value, customActionId) - } - ) - - await tester.runTest( - 'UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWallet, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - let usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - await tester.runTest( - 'UserSmartWallet relay cannot call with bad signature to withdraw USDC', - UserSmartWallet, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - '0x', - '0xffffffff' + usdcWithdrawalSignature.slice(10) - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'UserSmartWallet relay can call with signature to withdraw USDC', - UserSmartWallet, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - '0x', - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt.events) - }, - tester.originalAddress - ) - - /* TODO: get this working manually - const withdrawalMessage = ( - UserSmartWallet.options.address + // smart wallet address - constants.NULL_BYTES_32.slice(2) + // smart wallet version - address.slice(2) + // user dharma key - address.slice(2) + // dharma key registry key - '5'.padStart(64, '0') + // nonce - constants.NULL_BYTES_32.slice(2) + // minimum gas - '04' + // action type - 'f'.padStart(64, 'f') + // amount - address.slice(2) // recipient - ) - - const saiWithdrawalSignature = tester.signHashedPrefixedHashedHexString( - withdrawalMessage, - address - ) - */ - - await tester.runTest( - 'UserSmartWallet cannot withdraw too much sai', - UserSmartWallet, - 'withdrawDai', - 'send', - [ - '100000000000000000000000000000000000000', - tester.address, - 0, - '0x', - '0x' - ], - true, - receipt => { - if (testingContext !== 'coverage') { - //console.log(receipt.events) - } - // TODO: verify logs - //console.log(receipt.events.ExternalError.returnValues) - //console.log(receipt.events.ExternalError) - /* - console.log(Object.values(receipt.events).map(value => { - return ( - value.raw - ) - })) - */ - } - ) - - await tester.runTest( - 'UserSmartWallet cannot withdraw too much usdc', - UserSmartWallet, - 'withdrawUSDC', - 'send', - [ - '100000000000000000000000000000000', - tester.address, - 0, - '0x', - '0x' - ], - true, - receipt => { - if (testingContext !== 'coverage') { - //console.log(receipt.events) - } - // TODO: verify logs - //console.log(receipt.events.ExternalError.returnValues) - //console.log(receipt.events.ExternalError) - /* - console.log(Object.values(receipt.events).map(value => { - return ( - value.raw - ) - })) - */ - } - ) - - await tester.runTest( - 'UserSmartWallet cannot withdraw too little sai', - UserSmartWallet, - 'withdrawDai', - 'send', - [ - '1', - tester.address, - 0, - '0x', - '0x' - ], - true, - receipt => { - //console.log(receipt.events.ExternalError) - // TODO: verify logs - //console.log(receipt.events.ExternalError.returnValues) - //console.log(receipt.events.ExternalError) - /* - console.log(Object.values(receipt.events).map(value => { - return ( - value.raw - ) - })) - */ - } - ) - - await tester.runTest( - 'UserSmartWallet can get a Sai withdrawal custom action ID', - UserSmartWallet, - 'getNextCustomActionID', - 'call', - [ - 10, // SaiWithdrawal, - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - let saiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - await tester.runTest( - 'UserSmartWallet relay cannot call with bad signature to withdraw sai', - UserSmartWallet, - 'withdrawDai', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - '0x', - '0xffffffff' + saiWithdrawalSignature.slice(10) - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'UserSmartWallet relay can call with signature to withdraw sai', - UserSmartWallet, - 'withdrawDai', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - '0x', - saiWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'UserSmartWallet calls revert if insufficient action gas is supplied', - UserSmartWallet, - 'cancel', - 'send', - [ - constants.FULL_APPROVAL, - '0x' - ], - false - ) - - await tester.runTest( - 'UserSmartWallet calls succeed if sufficient non-zero action gas supplied', - UserSmartWallet, - 'cancel', - 'send', - [ - '1', - '0x' - ] - ) - - await tester.runTest( - 'UserSmartWallet calls to atomic methods revert', - UserSmartWallet, - '_withdrawDaiAtomic', - 'send', - [ - '1', - tester.address - ], - false - ) - - let originalNonce; - await tester.runTest( - 'UserSmartWallet nonce can be retrieved', - UserSmartWallet, - 'getNonce', - 'call', - [], - true, - value => { - originalNonce = value; - } - ) - - await testPerformingUpgrade( - tester, - DharmaSmartWalletImplementationV1, // new implementation - UserSmartWallet, - DharmaUpgradeBeaconController, - DharmaUpgradeBeacon.options.address, - 1 - ) - - await testPerformingUpgrade( - tester, - DharmaSmartWalletImplementationV2, // new implementation - UserSmartWallet, - DharmaUpgradeBeaconController, - DharmaUpgradeBeacon.options.address, - 2 - ) - - await testPerformingUpgrade( - tester, - DharmaSmartWalletImplementationV5, // new implementation - UserSmartWallet, - DharmaUpgradeBeaconController, - DharmaUpgradeBeacon.options.address, - 5 - ) - - await tester.runTest( - 'V5 UserSmartWallet can get balances', - UserSmartWalletV5, - 'getBalances', - 'call', - [], - true, - value => { - //console.log(value) - } - ) - - await tester.runTest( - 'V5 UserSmartWallet secondary can call to cancel', - UserSmartWalletV5, - 'cancel', - 'send', - [ - 0, - '0x' - ] - ) - - await tester.runTest( - 'V5 UserSmartWallet nonce is now set to original + 1', - UserSmartWalletV5, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, (parseInt(originalNonce) + 1).toString()) - } - ) - - await tester.runTest( - 'V5 UserSmartWallet can get next custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 4, // SAIWithdrawal, - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - await tester.runTest( - 'V5 UserSmartWallet can get custom action ID and it matches next action ID', - UserSmartWalletV5, - 'getCustomActionID', - 'call', - [ - 4, // SAIWithdrawal, - constants.FULL_APPROVAL, - tester.address, - parseInt(originalNonce) + 1, - 0 - ], - true, - value => { - assert.strictEqual(value, customActionId) - } - ) - - let genericActionID - await tester.runTest( - 'V5 UserSmartWallet can get next generic action ID', - UserSmartWalletV5, - 'getNextGenericActionID', - 'call', - [ - tester.address, - '0x', - 0 - ], - true, - value => { - genericActionID = value - } - ) - - await tester.runTest( - 'V5 UserSmartWallet can get generic action ID and it matches next action ID', - UserSmartWalletV5, - 'getGenericActionID', - 'call', - [ - tester.address, - '0x', - parseInt(originalNonce) + 1, - 0 - ], - true, - value => { - assert.strictEqual(value, genericActionID) - } - ) - - await tester.runTest( - 'UserSmartWallet calls to atomic methods revert', - UserSmartWalletV5, - '_withdrawSaiAtomic', - 'send', - [ - '1', - tester.address - ], - false - ) - - await tester.runTest( - 'Sai Whale can deposit sai into the V5 smart wallet', - SAI, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'ether')], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.SAI_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'ether') - ) - } - }, - constants.SAI_WHALE_ADDRESS - ) - - await tester.runTest( - 'USDC Whale can deposit usdc into the V5 smart wallet', - USDC, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.USDC_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'lovelace') - ) - } - }, - constants.USDC_WHALE_ADDRESS - ) - - await tester.runTest( - 'V5 user smart wallet can trigger repayAndDeposit to deposit all new funds', - UserSmartWalletV5, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - - assert.strictEqual(events[0].address, 'CSAI') - assert.strictEqual(events[0].eventName, 'AccrueInterest') - - assert.strictEqual(events[1].address, 'SAI') - assert.strictEqual(events[1].eventName, 'Transfer') - //assert.strictEqual(events[1].returnValues.value, web3.utils.toWei('100', 'ether')) - - assert.strictEqual(events[2].address, 'CSAI') - assert.strictEqual(events[2].eventName, 'Mint') - //assert.strictEqual(events[2].returnValues.mintTokens, web3.utils.toWei('100', 'ether')) - - - assert.strictEqual(events[3].address, 'CSAI') - assert.strictEqual(events[3].eventName, 'Transfer') - - assert.strictEqual(events[4].address, 'CUSDC') - assert.strictEqual(events[4].eventName, 'AccrueInterest') - - assert.strictEqual(events[5].address, 'USDC') - assert.strictEqual(events[5].eventName, 'Transfer') - //assert.strictEqual(events[5].returnValues.value, web3.utils.toWei('100', 'lovelace')) - - assert.strictEqual(events[6].address, 'CUSDC') - assert.strictEqual(events[6].eventName, 'Mint') - //assert.strictEqual(events[6].returnValues.mintTokens, web3.utils.toWei('100', 'lovelace')) - - assert.strictEqual(events[7].address, 'CUSDC') - assert.strictEqual(events[7].eventName, 'Transfer') - } - } - ) - - await tester.runTest( - 'Sai Whale can deposit sai into the V5 smart wallet again', - SAI, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'ether')], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.SAI_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'ether') - ) - } - }, - constants.SAI_WHALE_ADDRESS - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a generic action ID', - UserSmartWalletV5, - 'getNextGenericActionID', - 'call', - [ - constants.ESCAPE_HATCH_REGISTRY_ADDRESS, - '0x', - 0 - ], - true, - value => { - customActionId = value - } - ) - - let executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - let executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet cannot call executeAction and target Escape Hatch Registry', - UserSmartWalletV5, - 'executeAction', - 'send', - [ - constants.ESCAPE_HATCH_REGISTRY_ADDRESS, - '0x', - 0, - executeActionUserSignature, - executeActionSignature - ], - false - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a generic action ID', - UserSmartWalletV5, - 'getNextGenericActionID', - 'call', - [ - SAI.options.address, - SAI.methods.approve(CSAI.options.address, 0).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet can call executeAction', - UserSmartWalletV5, - 'executeAction', - 'send', - [ - SAI.options.address, - SAI.methods.approve(CSAI.options.address, 0).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'V5 user smart wallet repayAndDeposit cannot deposit without approval', - UserSmartWalletV5, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - - // TODO: verify - } - } - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a generic action ID', - UserSmartWalletV5, - 'getNextGenericActionID', - 'call', - [ - SAI.options.address, - SAI.methods.approve(CSAI.options.address, constants.FULL_APPROVAL).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet can call executeAction', - UserSmartWalletV5, - 'executeAction', - 'send', - [ - SAI.options.address, - SAI.methods.approve(CSAI.options.address, constants.FULL_APPROVAL).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'V5 user smart wallet repayAndDeposit can deposit with approval added back', - UserSmartWalletV5, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - - // TODO: verify - } - } - ) - - await tester.runTest( - 'V5 user smart wallet can trigger repayAndDeposit even with no funds', - UserSmartWalletV5, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - - assert.strictEqual(events.length, 0) - } - } - ) - - await tester.runTest( - 'V5 UserSmartWallet secondary cannot set an empty user userSigningKey', - UserSmartWalletV5, - 'setUserSigningKey', - 'send', - [ - constants.NULL_ADDRESS, - 0, - '0x', - '0x' - ], - false - ) - - await tester.runTest( - 'V5 UserSmartWallet secondary can set a custom user userSigningKey', - UserSmartWalletV5, - 'setUserSigningKey', - 'send', - [ - tester.addressTwo, - 0, - '0x', - '0x' - ] - ) - - await tester.runTest( - 'V5 UserSmartWallet can get next custom action ID to set a user signing key', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 1, // SetUserSigningKey, - constants.FULL_APPROVAL, // This value shouldn't matter - tester.addressTwo, - 0 - ], - true, - value => { - customActionId = value - } - ) - - let currentNonce - await tester.runTest( - 'UserSmartWallet can get the nonce', - UserSmartWalletV5, - 'getNonce', - 'call', - [], - true, - value => { - currentNonce = value - } - ) - - await tester.runTest( - 'V5 UserSmartWallet can get custom action ID and it matches next action ID', - UserSmartWalletV5, - 'getCustomActionID', - 'call', - [ - 1, // SetUserSigningKey, - 0, // Note that this value differs from above - tester.addressTwo, - currentNonce, - 0 - ], - true, - value => { - assert.strictEqual(value, customActionId) - } - ) - - let setUserSigningKeyUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - let setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - await tester.runTest( - 'V5 UserSmartWallet can set a new user signing key with signatures', - UserSmartWalletV5, - 'setUserSigningKey', - 'send', - [ - tester.addressTwo, - 0, - setUserSigningKeyUserSignature, - setUserSigningKeyDharmaSignature - ], - true, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get next custom action ID to cancel', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 0, // Cancel - constants.FULL_APPROVAL, // This value shouldn't matter - tester.originalAddress, // This value shouldn't matter either - 0 - ], - true, - value => { - customActionId = value - } - ) - - await tester.runTest( - 'UserSmartWallet can get the nonce', - UserSmartWalletV5, - 'getNonce', - 'call', - [], - true, - value => { - currentNonce = value - } - ) - - await tester.runTest( - 'V5 UserSmartWallet can get custom action ID and it matches next action ID', - UserSmartWalletV5, - 'getCustomActionID', - 'call', - [ - 0, // Cancel - 0, // Note that this value differs from above - tester.addressTwo, // This one too - currentNonce, - 0 - ], - true, - value => { - assert.strictEqual(value, customActionId) - } - ) - - let cancelUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet secondary can cancel using a signature', - UserSmartWalletV5, - 'cancel', - 'send', - [ - 0, - cancelUserSignature - ], - true, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'UserSmartWallet nonce is incremented after cancelling', - UserSmartWalletV5, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(parseInt(value), parseInt(currentNonce) + 1) - } - ) - - await tester.runTest( - 'V5 UserSmartWallet secondary cannot call to withdraw sai without primary', - UserSmartWalletV5, - 'withdrawSai', - 'send', - [ - '1000000000000000000', - tester.address, - 0, - '0x', - '0x' - ], - false - ) - - await tester.runTest( - 'V5 UserSmartWallet secondary cannot call to withdraw usdc without primary', - UserSmartWalletV5, - 'withdrawUSDC', - 'send', - [ - 1, - tester.address, - 0, - '0x', - '0x' - ], - false - ) - - await tester.runTest( - 'V5 UserSmartWallet secondary can no longer call to set userSigningKey without primary', - UserSmartWalletV5, - 'setUserSigningKey', - 'send', - [ - tester.address, - 0, - '0x', - '0x' - ], - false - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - '1', // dust - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - let usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay cannot withdraw "dust" USDC', - UserSmartWalletV5, - 'withdrawUSDC', - 'send', - [ - '1', - tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - '100000', - constants.NULL_ADDRESS, // bad recipient - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay cannot withdraw USDC to null address', - UserSmartWalletV5, - 'withdrawUSDC', - 'send', - [ - '100000', - constants.NULL_ADDRESS, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - '100000', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay can call with two signatures to withdraw USDC', - UserSmartWalletV5, - 'withdrawUSDC', - 'send', - [ - '100000', - tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay cannot call with bad signature to withdraw USDC', - UserSmartWalletV5, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - usdcUserWithdrawalSignature, - '0xffffffff' + usdcWithdrawalSignature.slice(10) - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet cannot call with bad user signature to withdraw USDC', - UserSmartWalletV5, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - '0xffffffff' + usdcUserWithdrawalSignature.slice(10), - usdcWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet relay can call with two signatures to withdraw max USDC', - UserSmartWalletV5, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - /* TODO: get this working manually - const withdrawalMessage = ( - UserSmartWallet.options.address + // smart wallet address - constants.NULL_BYTES_32.slice(2) + // smart wallet version - address.slice(2) + // user dharma key - address.slice(2) + // dharma key registry key - '5'.padStart(64, '0') + // nonce - constants.NULL_BYTES_32.slice(2) + // minimum gas - '04' + // action type - 'f'.padStart(64, 'f') + // amount - address.slice(2) // recipient - ) - - const saiWithdrawalSignature = tester.signHashedPrefixedHashedHexString( - withdrawalMessage, - address - ) - */ - - await tester.runTest( - 'V5 UserSmartWallet can get a Sai withdrawal custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 4, // SaiWithdrawal, - '1', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - saiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - let saiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay cannot withdraw "dust" sai', - UserSmartWalletV5, - 'withdrawDai', - 'send', - [ - '1', - tester.address, - 0, - saiUserWithdrawalSignature, - saiWithdrawalSignature - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a Sai withdrawal custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 4, // SaiWithdrawal, - '1000000000000000', - constants.NULL_ADDRESS, - 0 - ], - true, - value => { - customActionId = value - } - ) - - saiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - saiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay cannot withdraw sai to null address', - UserSmartWalletV5, - 'withdrawDai', - 'send', - [ - '1000000000000000', - constants.NULL_ADDRESS, - 0, - saiUserWithdrawalSignature, - saiWithdrawalSignature - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a Sai withdrawal custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 4, // SaiWithdrawal, - '1000000000000000', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - saiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - saiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay can call with signature to withdraw sai', - UserSmartWalletV5, - 'withdrawDai', - 'send', - [ - '1000000000000000', - tester.address, - 0, - saiUserWithdrawalSignature, - saiWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt.events) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet cannot get a non-custom "custom" next action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 2, // Generic, - constants.FULL_APPROVAL, - tester.address, - 0 - ], - false - ) - - await tester.runTest( - 'V5 UserSmartWallet cannot get a non-custom "custom" action ID', - UserSmartWalletV5, - 'getCustomActionID', - 'call', - [ - 2, // Generic, - constants.FULL_APPROVAL, - tester.address, - 0, - 0 - ], - false - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a Sai withdrawal custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 4, // SaiWithdrawal, - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - saiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - saiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay cannot call with bad signature to withdraw sai', - UserSmartWalletV5, - 'withdrawDai', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - saiUserWithdrawalSignature, - '0xffffffff' + saiWithdrawalSignature.slice(10) - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet relay cannot call with bad user signature to withdraw sai', - UserSmartWalletV5, - 'withdrawDai', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - '0xffffffff' + saiUserWithdrawalSignature.slice(10), - saiWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet relay can call with signature to withdraw sai', - UserSmartWalletV5, - 'withdrawDai', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - saiUserWithdrawalSignature, - saiWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a Ether withdrawal custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 6, // ETHWithdrawal, - '0', // no amount - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - let ethWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - let ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay cannot to withdraw ether with no amount', - UserSmartWalletV5, - 'withdrawEther', - 'send', - [ - '0', - tester.address, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a Ether withdrawal custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 6, // ETHWithdrawal, - '1', - constants.NULL_ADDRESS, // no recipient - 0 - ], - true, - value => { - customActionId = value - } - ) - - ethWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay cannot to withdraw ether with no recipient', - UserSmartWalletV5, - 'withdrawEther', - 'send', - [ - '1', - constants.NULL_ADDRESS, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a Ether withdrawal custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 6, // ETHWithdrawal, - '1', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - ethWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay cannot call with bad signature to withdraw eth', - UserSmartWalletV5, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - ethUserWithdrawalSignature, - '0xffffffff' + ethWithdrawalSignature.slice(10) - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet relay cannot call with bad user signature to withdraw eth', - UserSmartWalletV5, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - '0xffffffff' + ethUserWithdrawalSignature.slice(10), - ethWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet relay can call with signature to withdraw ether', - UserSmartWalletV5, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a Ether withdrawal custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 6, // ETHWithdrawal, - '1', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - ethWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay cannot call with bad signature to withdraw eth', - UserSmartWalletV5, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - ethUserWithdrawalSignature, - '0xffffffff' + ethWithdrawalSignature.slice(10) - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet relay cannot call with bad user signature to withdraw eth', - UserSmartWalletV5, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - '0xffffffff' + ethUserWithdrawalSignature.slice(10), - ethWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet relay can call with signature to withdraw ether', - UserSmartWalletV5, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet cancel reverts with bad signature', - UserSmartWalletV5, - 'cancel', - 'send', - [ - 0, - '0x' - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet calls revert if insufficient action gas is supplied', - UserSmartWalletV5, - 'cancel', - 'send', - [ - constants.FULL_APPROVAL, - '0x' - ], - false - ) - - await tester.runTest( - 'V5 UserSmartWallet calls succeed if sufficient non-zero action gas supplied', - UserSmartWalletV5, - 'cancel', - 'send', - [ - '1', - '0x' - ] - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a cancel custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 0, // Cancel, - '0', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - let cancelSignature = tester.signHashedPrefixedHexString(customActionId, tester.addressTwo) - - await tester.runTest( - 'V5 UserSmartWallet can cancel using a signature', - UserSmartWalletV5, - 'cancel', - 'send', - [ - '0', - cancelSignature - ], - true, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet calls to atomic methods revert', - UserSmartWalletV5, - '_withdrawSaiAtomic', - 'send', - [ - '1', - tester.address - ], - false - ) - - await tester.runTest( - 'V5 UserSmartWallet calls to recover from random address revert', - UserSmartWalletV5, - 'recover', - 'send', - [ - tester.address - ], - false - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can deploy a V5 smart wallet using a Dharma Key', - DharmaSmartWalletFactoryV1, - 'newSmartWallet', - 'send', - [tester.addressTwo], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - - assert.strictEqual(events[0].eventName, 'NewUserSigningKey') - assert.strictEqual(events[0].returnValues.userSigningKey, tester.addressTwo) - //console.log(events) - - // TODO: test more events - } - } - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a generic action ID', - UserSmartWalletV5, - 'getNextGenericActionID', - 'call', - [ - USDC.options.address, - USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet cannot call executeAction and target a non-contract', - UserSmartWalletV5, - 'executeAction', - 'send', - [ - tester.address, - USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ], - false - ) - - await tester.runTest( - 'V5 UserSmartWallet cannot call executeAction and target itself', - UserSmartWalletV5, - 'executeAction', - 'send', - [ - UserSmartWalletV5.options.address, - USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ], - false - ) - - await tester.runTest( - 'V5 UserSmartWallet can call executeAction', - UserSmartWalletV5, - 'executeAction', - 'send', - [ - USDC.options.address, - USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'V5 UserSmartWallet can get the next generic batch action ID', - UserSmartWalletV5, - 'getNextGenericAtomicBatchActionID', - 'call', - [ - [{to: SAI.options.address, data: SAI.methods.totalSupply().encodeABI()}], - 0 - ], - true, - value => { - customActionId = value - } - ) - - await tester.runTest( - 'UserSmartWallet can get the nonce', - UserSmartWalletV5, - 'getNonce', - 'call', - [], - true, - value => { - currentNonce = value - } - ) - - await tester.runTest( - 'V5 UserSmartWallet generic batch action ID with nonce matches next ID', - UserSmartWalletV5, - 'getGenericAtomicBatchActionID', - 'call', - [ - [{to: SAI.options.address, data: SAI.methods.totalSupply().encodeABI()}], - currentNonce, - 0 - ], - true, - value => { - assert.strictEqual(value, customActionId) - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet can call executeActionWithAtomicBatchCalls', - UserSmartWalletV5, - 'executeActionWithAtomicBatchCalls', - 'send', - [ - [{to: SAI.options.address, data: SAI.methods.totalSupply().encodeABI()}], - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'USDC Whale can deposit usdc into the deployed smart wallet', - USDC, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.USDC_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'lovelace') - ) - } - }, - constants.USDC_WHALE_ADDRESS - ) - - await tester.runTest( - 'new user smart wallet can trigger repayAndDeposit to deposit all new funds', - UserSmartWalletV5, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - assert.strictEqual(events[0].address, 'USDC') - assert.strictEqual(events[0].eventName, 'Approval') - assert.strictEqual(events[0].returnValues.value, constants.FULL_APPROVAL) - - assert.strictEqual(events[1].address, 'CUSDC') - assert.strictEqual(events[1].eventName, 'AccrueInterest') - - assert.strictEqual(events[2].address, 'USDC') - assert.strictEqual(events[2].eventName, 'Transfer') - assert.strictEqual(events[2].returnValues.value, web3.utils.toWei('100', 'lovelace')) - - assert.strictEqual(events[3].address, 'CUSDC') - assert.strictEqual(events[3].eventName, 'Mint') - assert.strictEqual(events[3].returnValues.mintTokens, web3.utils.toWei('100', 'lovelace')) - - assert.strictEqual(events[4].address, 'CUSDC') - assert.strictEqual(events[4].eventName, 'Transfer') - } - } - ) - - const FIAT_TOKEN = new web3.eth.Contract( - [ - { - "constant": true, "inputs": [], "name": "blacklister", - "outputs": [{"name": "", "type": "address"}], "payable": false, - "stateMutability": "view", "type": "function" - }, { - "constant": false, "inputs": [{"name": "_account", "type": "address"}], - "name": "unBlacklist", "outputs": [], "payable": false, - "stateMutability": "nonpayable", "type": "function" - }, { - "constant": false, "inputs": [{"name": "_account", "type": "address"}], - "name": "blacklist", "outputs": [], "payable": false, - "stateMutability": "nonpayable", "type": "function" - }, { - "constant": true, "inputs": [{"name": "_account", "type": "address"}], - "name": "isBlacklisted", "outputs": [{"name": "", "type": "bool"}], - "payable": false, "stateMutability": "view", "type": "function" - }, { - "constant": false, "inputs": [], - "name": "pause", "outputs": [], "payable": false, - "stateMutability": "nonpayable", "type": "function" - }, { - "constant": false, "inputs": [], - "name": "unpause", "outputs": [], "payable": false, - "stateMutability": "nonpayable", "type": "function" - }, { - "constant": true, "inputs": [], "name": "pauser", - "outputs": [{"name": "", "type": "address"}], "payable": false, - "stateMutability": "view", "type": "function" - } - ], - constants.USDC_MAINNET_ADDRESS - ) - - let blacklister - await tester.runTest( - 'Check blacklister address', - FIAT_TOKEN, - 'blacklister', - 'call', - [], - true, - value => { - blacklister = value - } - ) - - let pausear - await tester.runTest( - 'Check pauser address', - FIAT_TOKEN, - 'pauser', - 'call', - [], - true, - value => { - pauser = value - } - ) - - await tester.runTest( - 'blacklist mock address', - FIAT_TOKEN, - 'blacklist', - 'send', - [constants.MOCK_USDC_BLACKLISTED_ADDRESS], - true, - receipt => {}, - blacklister - ) - - let targetBlacklistAddress; - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', - DharmaSmartWalletFactoryV1, - 'getNextSmartWallet', - 'call', - [constants.MOCK_USDC_BLACKLISTED_ADDRESS], - true, - value => { - targetBlacklistAddress = value - } - ) - - const BlacklistedUserSmartWalletV5 = new web3.eth.Contract( - DharmaSmartWalletImplementationV5Artifact.abi, - targetBlacklistAddress - ) - - await tester.runTest( - 'USDC Whale can deposit usdc into the yet-to-be-blacklisted smart wallet', - USDC, - 'transfer', - 'send', - [targetBlacklistAddress, web3.utils.toWei('100', 'lovelace')], // six decimals - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.USDC_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetBlacklistAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'lovelace') - ) - } - }, - constants.USDC_WHALE_ADDRESS - ) - - await tester.runTest( - 'blacklist counterfactual deployment address', - FIAT_TOKEN, - 'blacklist', - 'send', - [targetBlacklistAddress], - true, - receipt => {}, - blacklister - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can deploy to a blacklisted address', - DharmaSmartWalletFactoryV1, - 'newSmartWallet', - 'send', - [constants.MOCK_USDC_BLACKLISTED_ADDRESS], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - 'blacklisted smart wallet will not approve USDC during repayAndDeposit', - BlacklistedUserSmartWalletV5, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - 'un-blacklist counterfactual deployment address', - FIAT_TOKEN, - 'unBlacklist', - 'send', - [targetBlacklistAddress], - true, - receipt => {}, - blacklister - ) - - await tester.runTest( - 'pause USDC', - FIAT_TOKEN, - 'pause', - 'send', - [], - true, - receipt => {}, - pauser - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet attempt to withdraw max USDC when paused causes ExternalError', - UserSmartWalletV5, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'smart wallet will not approve USDC when paused during repayAndDeposit', - BlacklistedUserSmartWalletV5, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - 'unpause USDC', - FIAT_TOKEN, - 'unpause', - 'send', - [], - true, - receipt => {}, - pauser - ) - - await tester.runTest( - 'unblacklisted, unpaused smart wallet approves USDC during repayAndDeposit', - BlacklistedUserSmartWalletV5, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', - UserSmartWallet, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - web3.utils.toWei('50', 'lovelace'), - constants.MOCK_USDC_BLACKLISTED_ADDRESS, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay call to withdraw USDC to blacklisted address', - UserSmartWallet, - 'withdrawUSDC', - 'send', - [ - web3.utils.toWei('50', 'lovelace'), - constants.MOCK_USDC_BLACKLISTED_ADDRESS, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt.events[0]) - //console.log(receipt.events.ExternalError) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWallet, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - constants.FULL_APPROVAL, - UserSmartWallet.options.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay call to withdraw USDC to itself', - UserSmartWallet, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - UserSmartWallet.options.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', - UserSmartWallet, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - constants.FULL_APPROVAL, - constants.MOCK_USDC_BLACKLISTED_ADDRESS, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay call to withdraw USDC to blacklisted address', - UserSmartWallet, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - constants.MOCK_USDC_BLACKLISTED_ADDRESS, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt.events[0]) - //console.log(receipt.events.ExternalError) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a Ether withdrawal custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 6, // ETHWithdrawal, - '1', - targetWalletAddress, - 0 - ], - true, - value => { - customActionId = value - } - ) - - ethWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay cannot withdraw eth to a non-payable account', - UserSmartWalletV5, - 'withdrawEther', - 'send', - [ - '1', - targetWalletAddress, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - let targetWalletAddressTwo; - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', - DharmaSmartWalletFactoryV1, - 'getNextSmartWallet', - 'call', - [targetWalletAddress], - true, - value => { - // TODO: verify against expected value - targetWalletAddressTwo = value - } - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can deploy a V5 smart wallet using a contract key', - DharmaSmartWalletFactoryV1, - 'newSmartWallet', - 'send', - [targetWalletAddress] - ) - - const UserSmartWalletV5Two = new web3.eth.Contract( - DharmaSmartWalletImplementationV5Artifact.abi, - targetWalletAddressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet cancel reverts with bad contract signature', - UserSmartWalletV5Two, - 'cancel', - 'send', - [ - 0, - '0x' - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a generic action ID', - UserSmartWalletV5, - 'getNextGenericActionID', - 'call', - [ - SAI.options.address, - SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet can call executeAction', - UserSmartWalletV5, - 'executeAction', - 'send', - [ - SAI.options.address, - SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a Sai withdrawal custom action ID', - UserSmartWallet, - 'getNextCustomActionID', - 'call', - [ - 4, // SaiWithdrawal, - '100000000000000000000000000000000000000', // too much - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - saiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - saiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet relay cannot withdraw too much sai', - UserSmartWallet, - 'withdrawDai', - 'send', - [ - '100000000000000000000000000000000000000', // too much - tester.address, - 0, - saiUserWithdrawalSignature, - saiWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt.events) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWallet, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - '100000000000000000000000000000000000000', // too much - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - - await tester.runTest( - 'V5 UserSmartWallet relay can call with two signatures to withdraw USDC', - UserSmartWallet, - 'withdrawUSDC', - 'send', - [ - '100000000000000000000000000000000000000', // too much - tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get next generic batch action ID', - UserSmartWalletV5, - 'getNextGenericAtomicBatchActionID', - 'call', - [ - [{ - to: SAI.options.address, - data: SAI.methods.transfer( - tester.address, '100000000000000000000000000000' - ).encodeABI() - }], - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet bad executeActionWithAtomicBatchCalls emits CallFailure', - UserSmartWalletV5, - 'executeActionWithAtomicBatchCalls', - 'send', - [ - [{ - to: SAI.options.address, - data: SAI.methods.transfer( - tester.address, '100000000000000000000000000000' - ).encodeABI() - }], - 0, - executeActionUserSignature, - executeActionSignature - ], - true, - receipt => { - //console.log(receipt) - } - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a generic action ID', - UserSmartWalletV5, - 'getNextGenericActionID', - 'call', - [ - Comptroller.options.address, - Comptroller.methods.enterMarkets( - [constants.CSAI_MAINNET_ADDRESS] - ).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet can call executeAction to enter sai market', - UserSmartWalletV5, - 'executeAction', - 'send', - [ - Comptroller.options.address, - Comptroller.methods.enterMarkets( - [constants.CSAI_MAINNET_ADDRESS] - ).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'Sai Whale can deposit sai into the smart wallet', - SAI, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'ether')], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.SAI_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'ether') - ) - } - }, - constants.SAI_WHALE_ADDRESS - ) - - await tester.runTest( - 'V5 UserSmartWallet can trigger repayAndDeposit to deposit all new funds', - UserSmartWalletV5, - 'repayAndDeposit' - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a generic action ID', - UserSmartWalletV5, - 'getNextGenericActionID', - 'call', - [ - CSAI.options.address, - CSAI.methods.transfer(tester.address, web3.utils.toWei('1', 'mwei')).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V5 UserSmartWallet can call executeAction to transfer cSai', - UserSmartWalletV5, - 'executeAction', - 'send', - [ - CSAI.options.address, - CSAI.methods.transfer(tester.address, web3.utils.toWei('1', 'mwei')).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ], - true, - receipt => { - //console.log(receipt.events) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a generic action ID', - UserSmartWalletV5, - 'getNextGenericActionID', - 'call', - [ - CSAI_BORROW.options.address, - CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) + if (usdcWhaleBalance === '0') { + await web3.eth.sendTransaction({ + from: tester.address, + to: constants.USDC_WHALE_ADDRESS, + value: web3.utils.toWei('.1', 'ether'), + gas: (testingContext !== 'coverage') ? '0x5208' : tester.gasLimit - 1, + gasPrice: 1 + }) + console.log(' ✓ USDC Whale can receive eth if needed') + } + + await web3.eth.sendTransaction({ + from: constants.ETH_WHALE_ADDRESS, + to: targetWalletAddress, + value: web3.utils.toWei('.1', 'ether'), + gas: (testingContext !== 'coverage') ? '0x5208' : tester.gasLimit - 1, + gasPrice: 1 + }) + console.log(' ✓ Eth Whale can deposit eth into the yet-to-be-deployed smart wallet') await tester.runTest( - 'V5 UserSmartWallet can call executeAction to perform a borrow', - UserSmartWalletV5, - 'executeAction', + 'Dai Whale can deposit dai into the yet-to-be-deployed smart wallet', + DAI, + 'transfer', 'send', - [ - CSAI_BORROW.options.address, - CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ], + [targetWalletAddress, web3.utils.toWei('100', 'ether')], true, receipt => { - //console.log(receipt.events) + if (testingContext !== 'coverage') { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.DAI_WHALE_ADDRESS + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei('100', 'ether') + ) + } }, - tester.originalAddress - ) - - await tester.runTest( - 'V5 UserSmartWallet can get a Sai withdrawal custom action ID', - UserSmartWalletV5, - 'getNextCustomActionID', - 'call', - [ - 4, // SaiWithdrawal, - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - saiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - saiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo + constants.DAI_WHALE_ADDRESS ) await tester.runTest( - 'V5 UserSmartWallet relay cannot withdraw max sai with an outstanding borrow', - UserSmartWalletV5, - 'withdrawDai', + 'USDC Whale can deposit usdc into the yet-to-be-deployed smart wallet', + USDC, + 'transfer', 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - saiUserWithdrawalSignature, - saiWithdrawalSignature - ], + [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals true, receipt => { - // TODO: verify logs - //console.log(receipt.events) + if (testingContext !== 'coverage') { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.USDC_WHALE_ADDRESS + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ) + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei('100', 'lovelace') + ) + } }, - tester.originalAddress + constants.USDC_WHALE_ADDRESS ) - // Initiate account recovery await tester.runTest( - 'smart wallet account recovery can be initiated', - DharmaAccountRecoveryManagerV2, - 'initiateAccountRecovery', + 'DharmaSmartWalletFactoryV1 cannot deploy a new smart wallet with no key', + DharmaSmartWalletFactoryV1, + 'newSmartWallet', 'send', - [ - UserSmartWalletV5.options.address, - tester.originalAddress, - 0 // extraTime in seconds - ], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } + [constants.NULL_ADDRESS], + false ) await tester.runTest( - 'smart wallet account recovery cannot be performed right away', - DharmaAccountRecoveryManagerV2, - 'recover', + 'DharmaSmartWalletFactoryV1 can deploy a new smart wallet using a Dharma Key', + DharmaSmartWalletFactoryV1, + 'newSmartWallet', 'send', - [ - UserSmartWalletV5.options.address, - tester.originalAddress - ], - false - ) + [tester.address], + true, + receipt => { + //console.log(receipt.status, receipt.gasUsed) + if (testingContext !== 'coverage') { + let events = [] + Object.values(receipt.events).forEach((value) => { + const log = constants.EVENT_DETAILS[value.raw.topics[0]] + if (typeof log === 'undefined') { + console.log(value) + } + const decoded = web3.eth.abi.decodeLog( + log.abi, value.raw.data, value.raw.topics + ) + events.push({ + address: contractNames[value.address], + eventName: log.name, + returnValues: decoded + }) + }) - // advance time by 3 days - await tester.advanceTime((60 * 60 * 24 * 3) + 5) + assert.strictEqual(events[0].address, 'Smart Wallet') + assert.strictEqual(events[0].eventName, 'NewUserSigningKey') + assert.strictEqual(events[0].returnValues.userSigningKey, tester.address) + + assert.strictEqual(events[1].address, 'DAI') + assert.strictEqual(events[1].eventName, 'Approval') + assert.strictEqual(events[1].returnValues.value, constants.FULL_APPROVAL) + + assert.strictEqual(events[2].address, 'CDAI') + assert.strictEqual(events[2].eventName, 'AccrueInterest') + + assert.strictEqual(events[3].address, 'DAI') + assert.strictEqual(events[3].eventName, 'Transfer') + assert.strictEqual(events[3].returnValues.value, web3.utils.toWei('100', 'ether')) + + assert.strictEqual(events[4].address, 'CDAI') + assert.strictEqual(events[4].eventName, 'Mint') + assert.strictEqual(events[4].returnValues.mintTokens, web3.utils.toWei('100', 'ether')) + + assert.strictEqual(events[5].address, 'CDAI') + assert.strictEqual(events[5].eventName, 'Transfer') + + assert.strictEqual(events[6].address, 'USDC') + assert.strictEqual(events[6].eventName, 'Approval') + assert.strictEqual(events[6].returnValues.value, constants.FULL_APPROVAL) + + assert.strictEqual(events[7].address, 'CUSDC') + assert.strictEqual(events[7].eventName, 'AccrueInterest') + + assert.strictEqual(events[8].address, 'USDC') + assert.strictEqual(events[8].eventName, 'Transfer') + assert.strictEqual(events[8].returnValues.value, web3.utils.toWei('100', 'lovelace')) + + assert.strictEqual(events[9].address, 'CUSDC') + assert.strictEqual(events[9].eventName, 'Mint') + assert.strictEqual(events[9].returnValues.mintTokens, web3.utils.toWei('100', 'lovelace')) + + assert.strictEqual(events[10].address, 'CUSDC') + assert.strictEqual(events[10].eventName, 'Transfer') + } + } + ) - // recover account await tester.runTest( - 'smart wallet account recovery can be performed after three days', - DharmaAccountRecoveryManagerV2, - 'recover', - 'send', - [ - UserSmartWalletV5.options.address, - tester.originalAddress - ], + 'DharmaSmartWalletFactoryV1 gets a new smart wallet address with same key', + DharmaSmartWalletFactoryV1, + 'getNextSmartWallet', + 'call', + [tester.address], true, - receipt => { - // TODO: verify - //console.log(receipt.events) + value => { + // TODO: verify against expected value + assert.ok(targetWalletAddress !== value) } ) + let originalNonce = 0 await tester.runTest( - 'UserSmartWalletV5 can get the nonce prior to upgrade', - UserSmartWalletV5, + 'UserSmartWalletV6 nonce can be retrieved and starts at zero', + UserSmartWalletV6, 'getNonce', 'call', [], true, value => { - originalNonce = value + assert.strictEqual(value, originalNonce.toString()); } ) - - await testPerformingUpgrade( - tester, - DharmaSmartWalletImplementationV6, // new implementation - UserSmartWallet, - DharmaUpgradeBeaconController, - DharmaUpgradeBeacon.options.address, - 6 - ) - await tester.runTest( 'V6 UserSmartWallet can get balances', UserSmartWalletV6, @@ -4711,10 +1128,7 @@ async function test(testingContext) { 0, '0x', setUserSigningKeyDharmaSignature - ], - true, - receipt => {}, - tester.originalAddress + ] ) await tester.runTest( @@ -5784,8 +2198,8 @@ async function test(testingContext) { '1000000000000000', constants.NULL_ADDRESS, 0, - saiUserWithdrawalSignature, - saiWithdrawalSignature + daiUserWithdrawalSignature, + daiWithdrawalSignature ], false, receipt => {}, @@ -6771,7 +3185,7 @@ async function test(testingContext) { await tester.runTest( 'V6 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', - UserSmartWallet, + UserSmartWalletV6, 'getNextCustomActionID', 'call', [ @@ -6798,7 +3212,7 @@ async function test(testingContext) { await tester.runTest( 'V6 UserSmartWallet relay call to withdraw USDC to blacklisted address', - UserSmartWallet, + UserSmartWalletV6, 'withdrawUSDC', 'send', [ @@ -6819,13 +3233,13 @@ async function test(testingContext) { await tester.runTest( 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWallet, + UserSmartWalletV6, 'getNextCustomActionID', 'call', [ 5, // USDCWithdrawal, constants.FULL_APPROVAL, - UserSmartWallet.options.address, + UserSmartWalletV6.options.address, 0 ], true, @@ -6846,12 +3260,12 @@ async function test(testingContext) { await tester.runTest( 'V6 UserSmartWallet relay call to withdraw USDC to itself', - UserSmartWallet, + UserSmartWalletV6, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - UserSmartWallet.options.address, + UserSmartWalletV6.options.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -6865,7 +3279,7 @@ async function test(testingContext) { await tester.runTest( 'V6 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', - UserSmartWallet, + UserSmartWalletV6, 'getNextCustomActionID', 'call', [ @@ -6892,7 +3306,7 @@ async function test(testingContext) { await tester.runTest( 'V6 UserSmartWallet relay call to withdraw USDC to blacklisted address', - UserSmartWallet, + UserSmartWalletV6, 'withdrawUSDC', 'send', [ @@ -7040,7 +3454,7 @@ async function test(testingContext) { await tester.runTest( 'V6 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWallet, + UserSmartWalletV6, 'getNextCustomActionID', 'call', [ @@ -7067,7 +3481,7 @@ async function test(testingContext) { await tester.runTest( 'V6 UserSmartWallet relay cannot withdraw to the null address', - UserSmartWallet, + UserSmartWalletV6, 'withdrawDai', 'send', [ @@ -7087,7 +3501,7 @@ async function test(testingContext) { await tester.runTest( 'V6 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWallet, + UserSmartWalletV6, 'getNextCustomActionID', 'call', [ @@ -7114,7 +3528,7 @@ async function test(testingContext) { await tester.runTest( 'V6 UserSmartWallet relay cannot withdraw too much dai', - UserSmartWallet, + UserSmartWalletV6, 'withdrawDai', 'send', [ @@ -7134,7 +3548,7 @@ async function test(testingContext) { await tester.runTest( 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWallet, + UserSmartWalletV6, 'getNextCustomActionID', 'call', [ @@ -7161,7 +3575,7 @@ async function test(testingContext) { await tester.runTest( 'V6 UserSmartWallet relay can call with two signatures to withdraw USDC', - UserSmartWallet, + UserSmartWalletV6, 'withdrawUSDC', 'send', [ @@ -7392,8 +3806,8 @@ async function test(testingContext) { ) await tester.runTest( - 'UserSmartWallet nonce can be retrieved', - UserSmartWallet, + 'UserSmartWalletV6 nonce can be retrieved', + UserSmartWalletV6, 'getNonce', 'call', [], @@ -7406,7 +3820,7 @@ async function test(testingContext) { await testPerformingUpgrade( tester, DharmaSmartWalletImplementationV7, // new implementation - UserSmartWallet, + UserSmartWalletV7, DharmaUpgradeBeaconController, DharmaUpgradeBeacon.options.address, 7 @@ -8459,8 +4873,8 @@ async function test(testingContext) { '1000000000000000', constants.NULL_ADDRESS, 0, - saiUserWithdrawalSignature, - saiWithdrawalSignature + daiUserWithdrawalSignature, + daiWithdrawalSignature ], false, receipt => {}, @@ -9415,7 +5829,7 @@ async function test(testingContext) { await tester.runTest( 'V7 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', - UserSmartWallet, + UserSmartWalletV7, 'getNextCustomActionID', 'call', [ @@ -9442,7 +5856,7 @@ async function test(testingContext) { await tester.runTest( 'V7 UserSmartWallet relay call to withdraw USDC to blacklisted address', - UserSmartWallet, + UserSmartWalletV7, 'withdrawUSDC', 'send', [ @@ -9463,13 +5877,13 @@ async function test(testingContext) { await tester.runTest( 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWallet, + UserSmartWalletV7, 'getNextCustomActionID', 'call', [ 5, // USDCWithdrawal, constants.FULL_APPROVAL, - UserSmartWallet.options.address, + UserSmartWalletV7.options.address, 0 ], true, @@ -9490,12 +5904,12 @@ async function test(testingContext) { await tester.runTest( 'V7 UserSmartWallet relay call to withdraw USDC to itself', - UserSmartWallet, + UserSmartWalletV7, 'withdrawUSDC', 'send', [ constants.FULL_APPROVAL, - UserSmartWallet.options.address, + UserSmartWalletV7.options.address, 0, usdcUserWithdrawalSignature, usdcWithdrawalSignature @@ -9509,7 +5923,7 @@ async function test(testingContext) { await tester.runTest( 'V7 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', - UserSmartWallet, + UserSmartWalletV7, 'getNextCustomActionID', 'call', [ @@ -9536,7 +5950,7 @@ async function test(testingContext) { await tester.runTest( 'V7 UserSmartWallet relay call to withdraw USDC to blacklisted address', - UserSmartWallet, + UserSmartWalletV7, 'withdrawUSDC', 'send', [ @@ -9684,7 +6098,7 @@ async function test(testingContext) { await tester.runTest( 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWallet, + UserSmartWalletV7, 'getNextCustomActionID', 'call', [ @@ -9711,7 +6125,7 @@ async function test(testingContext) { await tester.runTest( 'V7 UserSmartWallet relay cannot withdraw to the null address', - UserSmartWallet, + UserSmartWalletV7, 'withdrawDai', 'send', [ @@ -9731,7 +6145,7 @@ async function test(testingContext) { await tester.runTest( 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWallet, + UserSmartWalletV7, 'getNextCustomActionID', 'call', [ @@ -9758,7 +6172,7 @@ async function test(testingContext) { await tester.runTest( 'V7 UserSmartWallet relay cannot withdraw too much dai', - UserSmartWallet, + UserSmartWalletV7, 'withdrawDai', 'send', [ @@ -9778,7 +6192,7 @@ async function test(testingContext) { await tester.runTest( 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWallet, + UserSmartWalletV7, 'getNextCustomActionID', 'call', [ @@ -9805,7 +6219,7 @@ async function test(testingContext) { await tester.runTest( 'V7 UserSmartWallet relay can call with two signatures to withdraw USDC', - UserSmartWallet, + UserSmartWalletV7, 'withdrawUSDC', 'send', [ From 9a26c743e93be93f4f193a79c31cb95a51d75048 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Fri, 7 Feb 2020 17:26:53 -0500 Subject: [PATCH 26/47] fix coverage --- .solcover.js | 5 ++++- .../testIndestructibleRegistry.js | 2 +- scripts/test/test.js | 1 + scripts/test/testCoverage.js | 9 +++------ scripts/test/web3.js | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.solcover.js b/.solcover.js index 12fdb55..082f5cd 100644 --- a/.solcover.js +++ b/.solcover.js @@ -13,6 +13,7 @@ module.exports = { 'helpers/FactoryFactFinder.sol', 'helpers/ImmutableCreate2Factory.sol', 'helpers/IndestructibleRegistry.sol', + 'helpers/SmartWalletRevertReasonHelperV1.sol', 'helpers/SmartWalletFactoryV1UserSigningKeyUpdater.sol', //'helpers/Timelocker.sol', //'helpers/TimelockerV2.sol', @@ -62,6 +63,8 @@ module.exports = { 'test/MockAdharmaKeyRingFactory.sol', 'test/TimelockEdgecaseTester.sol', 'test/TimelockTwoStepOwnableTestContract.sol', - 'test/UpgradeBeaconImplementationCheck.sol' + 'test/UpgradeBeaconImplementationCheck.sol', + 'upgradeability/token/DharmaDaiUpgradeBeacon.sol', + 'upgradeability/token/DharmaUSDCUpgradeBeacon.sol' ] } \ No newline at end of file diff --git a/scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js b/scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js index e170063..b474853 100644 --- a/scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js +++ b/scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js @@ -156,7 +156,7 @@ async function testIndestructibleRegistry(tester, contracts) { ) */ - if (tester.testingContext !== 'coverage') { + if (tester.context !== 'coverage') { /* await tester.runTest( 'IndestructibleRegistry can register V2 implementation as indestructible', diff --git a/scripts/test/test.js b/scripts/test/test.js index a9e05b3..1b02889 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -850,6 +850,7 @@ async function test(testingContext) { const ethWhaleBalance = await web3.eth.getBalance(constants.ETH_WHALE_ADDRESS) const saiWhaleBalance = await web3.eth.getBalance(constants.SAI_WHALE_ADDRESS) + const daiWhaleBalance = await web3.eth.getBalance(constants.DAI_WHALE_ADDRESS) const usdcWhaleBalance = await web3.eth.getBalance(constants.USDC_WHALE_ADDRESS) if (ethWhaleBalance === '0') { diff --git a/scripts/test/testCoverage.js b/scripts/test/testCoverage.js index afdbaec..597f059 100644 --- a/scripts/test/testCoverage.js +++ b/scripts/test/testCoverage.js @@ -1,6 +1,3 @@ -var Web3 = require('web3') -web3Provider = new Web3('ws://localhost:8555') - // import tests var deployMockExternal = require('./deployMockExternal.js') var deploy = require('./deploy.js') @@ -8,9 +5,9 @@ var test = require('./test.js') // run tests async function runTests() { - await deployMockExternal.test(web3Provider, 'coverage') - await deploy.test(web3Provider, 'coverage') - await test.test(web3Provider, 'coverage') + await deployMockExternal.test('coverage') + await deploy.test('coverage') + await test.test('coverage') process.exit(0) } diff --git a/scripts/test/web3.js b/scripts/test/web3.js index 77443e1..d91debb 100644 --- a/scripts/test/web3.js +++ b/scripts/test/web3.js @@ -1,6 +1,6 @@ const connectionConfig = require('../../truffle-config.js'); -const connection = connectionConfig.networks['development']; +const connection = connectionConfig.networks['coverage']; const web3 = connection.provider; From 12c6c5abe962241c0cc519e324cb1288ef512c16 Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Fri, 7 Feb 2020 18:53:52 -0800 Subject: [PATCH 27/47] refactor contracts and web3 --- package.json | 6 +- scripts/test/ci.js | 8 +- scripts/test/test.js | 768 ++++++++++------------------------- scripts/test/testCoverage.js | 11 +- scripts/test/testHelpers.js | 367 ++++++++++++++++- scripts/test/web3.js | 6 +- 6 files changed, 587 insertions(+), 579 deletions(-) diff --git a/package.json b/package.json index 7ad5f24..7ab28d7 100644 --- a/package.json +++ b/package.json @@ -17,15 +17,15 @@ "web3": "1.2.1" }, "scripts": { - "all": "./node_modules/.bin/ganache-cli --gasLimit 8000000 -i 1234 -e 10000 -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' 2>&1 > ganache-output.log & echo 'local chain started.' && ./node_modules/.bin/truffle compile && node scripts/test/ci.js && ./node_modules/.bin/solhint 'contracts/**/*.sol' && ./node_modules/.bin/solium -d .; kill -9 \"$(ps -ax | grep -m1 '[n]ode ./node_modules/.bin/ganache-cli' | awk '{print $1;}')\" && echo 'local chain stopped.'", + "all": "export TESTING_CONTEXT=development ; ./node_modules/.bin/ganache-cli --gasLimit 8000000 -i 1234 -e 10000 -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' 2>&1 > ganache-output.log & echo 'local chain started.' && ./node_modules/.bin/truffle compile && node scripts/test/ci.js && ./node_modules/.bin/solhint 'contracts/**/*.sol' && ./node_modules/.bin/solium -d .; kill -9 \"$(ps -ax | grep -m1 '[n]ode ./node_modules/.bin/ganache-cli' | awk '{print $1;}')\" && echo 'local chain stopped.'", "build": "./node_modules/.bin/truffle compile", "ci": "./node_modules/.bin/ganache-cli --gasLimit 8000000 -i 1234 -q & echo 'local chain started.' && ./node_modules/.bin/truffle compile && node scripts/test/ci.js && ./node_modules/.bin/solhint 'contracts/**/*.sol' && ./node_modules/.bin/solium -d .", - "coverage": "./node_modules/.bin/ganache-cli-coverage --emitFreeLogs true --allowUnlimitedContractSize true --gasLimit 0xfffffffffff --port 8555 -e 10000 -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' 2>&1 > ganache-coverage-output.log & echo 'coverage chain started.' && node --max-old-space-size=8192 ./node_modules/.bin/solidity-coverage; kill -9 \"$(ps -ax | grep -m1 '[n]ode ./node_modules/.bin/ganache-cli' | awk '{print $1;}')\" && echo 'coverage chain stopped.'", + "coverage": "export TESTING_CONTEXT=coverage ; ./node_modules/.bin/ganache-cli-coverage --emitFreeLogs true --allowUnlimitedContractSize true --gasLimit 0xfffffffffff --port 8555 -e 10000 -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' 2>&1 > ganache-coverage-output.log & echo 'coverage chain started.' && node --max-old-space-size=8192 ./node_modules/.bin/solidity-coverage; kill -9 \"$(ps -ax | grep -m1 '[n]ode ./node_modules/.bin/ganache-cli' | awk '{print $1;}')\" && echo 'coverage chain stopped.'", "forkCoverage": "./node_modules/.bin/ganache-cli-coverage --emitFreeLogs true --allowUnlimitedContractSize true --gasLimit 0xfffffffffff --port 8555 --fork https://mainnet.infura.io/v3/e7faf3dd07254d76859ec8c7c3259d9d@8396520 -e 10000 -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' -u '0x5dB0115f3B72d19cEa34dD697cf412Ff86dc7E1b' -u '0xf0d160DEC1749aFaF5A831668093B1431f7C8527' 2>&1 > ganache-coverage-output.log & echo 'fork coverage chain started on port 8555.' && node --max-old-space-size=8192 ./node_modules/.bin/solidity-coverage; kill -9 \"$(ps -ax | grep -m1 '[n]ode ./node_modules/.bin/ganache-cli' | awk '{print $1;}')\" && echo 'coverage chain stopped.'", "lint": "./node_modules/.bin/solhint 'contracts/**/*.sol' && ./node_modules/.bin/solium -d .", "start": "./node_modules/.bin/ganache-cli --gasLimit 8000000 -i 1234 -e 10000 -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' 2>&1 > ganache-output.log & echo 'local chain started.'", "forkStart": "./node_modules/.bin/ganache-cli --port 8545 --gasLimit 8000000 --fork https://mainnet.infura.io/v3/e7faf3dd07254d76859ec8c7c3259d9d@8396520 -e 10000 -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' -u '0x5dB0115f3B72d19cEa34dD697cf412Ff86dc7E1b' -u '0xf0d160DEC1749aFaF5A831668093B1431f7C8527' 2>&1 > ganache-output.log & echo 'fork chain started on port 8545.'", "stop": "kill -9 \"$(ps -ax | grep -m1 '[n]ode ./node_modules/.bin/ganache-cli' | awk '{print $1;}')\" && echo 'local chain stopped.'", - "test": "./node_modules/.bin/truffle compile && node scripts/test/ci.js" + "test": "export TESTING_CONTEXT=development ; ./node_modules/.bin/truffle compile && node scripts/test/ci.js" } } \ No newline at end of file diff --git a/scripts/test/ci.js b/scripts/test/ci.js index 44b6119..ec8fbf6 100644 --- a/scripts/test/ci.js +++ b/scripts/test/ci.js @@ -1,11 +1,11 @@ // import tests const deployMockExternal = require('./deployMockExternal.js'); -const deploy = require('./deploy.js'); -const test = require('./test.js'); +const deploy = require('./deploy'); +const test = require('./test'); // run tests async function runTests() { - const context = "development"; + const context = process.env.TESTING_CONTEXT; await deployMockExternal.test(context); await deploy.test(context); @@ -13,4 +13,4 @@ async function runTests() { process.exit(0) } -runTests(); +runTests(); \ No newline at end of file diff --git a/scripts/test/test.js b/scripts/test/test.js index 1b02889..160e97d 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -13,369 +13,15 @@ const { testPerformingUpgrade } = require("./contracts/upgradeability/testPerfor const AdharmaSmartWalletImplementationArtifact = require('../../build/contracts/AdharmaSmartWalletImplementation.json') const AdharmaKeyRingImplementationArtifact = require('../../build/contracts/AdharmaKeyRingImplementation.json') -const DharmaUpgradeBeaconControllerManagerArtifact = require('../../build/contracts/DharmaUpgradeBeaconControllerManager.json') -const DharmaUpgradeBeaconControllerArtifact = require('../../build/contracts/DharmaUpgradeBeaconController.json') -const DharmaUpgradeBeaconArtifact = require('../../build/contracts/DharmaUpgradeBeacon.json') -const DharmaKeyRingUpgradeBeaconArtifact = require('../../build/contracts/DharmaKeyRingUpgradeBeacon.json') -const DharmaUpgradeBeaconEnvoyArtifact = require('../../build/contracts/DharmaUpgradeBeaconEnvoy.json') - -const DharmaAccountRecoveryManagerV2Artifact = require('../../build/contracts/DharmaAccountRecoveryManagerV2.json') -//const DharmaKeyRegistryV1Artifact = require('../../build/contracts/DharmaKeyRegistryV1.json') -const DharmaKeyRegistryV2Artifact = require('../../build/contracts/DharmaKeyRegistryV2.json') -const DharmaSmartWalletFactoryV1Artifact = require('../../build/contracts/DharmaSmartWalletFactoryV1.json') -const DharmaSmartWalletFactoryV2Artifact = require('../../build/contracts/DharmaSmartWalletFactoryV2.json') - const DharmaSmartWalletImplementationV6Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV6.json') const DharmaSmartWalletImplementationV7Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV7.json') const DharmaKeyRingImplementationV1Artifact = require('../../build/contracts/DharmaKeyRingImplementationV1.json') -const DharmaKeyRingFactoryV1Artifact = require('../../build/contracts/DharmaKeyRingFactoryV1.json') -const DharmaKeyRingFactoryV2Artifact = require('../../build/contracts/DharmaKeyRingFactoryV2.json') -const DharmaKeyRingFactoryV3Artifact = require('../../build/contracts/DharmaKeyRingFactoryV3.json') - -const UpgradeBeaconProxyV1Artifact = require('../../build/contracts/UpgradeBeaconProxyV1.json') -const KeyRingUpgradeBeaconProxyV1Artifact = require('../../build/contracts/KeyRingUpgradeBeaconProxyV1.json') - -const DharmaUpgradeMultisigArtifact = require('../../build/contracts/DharmaUpgradeMultisig.json') -const DharmaAccountRecoveryMultisigArtifact = require('../../build/contracts/DharmaAccountRecoveryMultisig.json') -const DharmaAccountRecoveryOperatorMultisigArtifact = require('../../build/contracts/DharmaAccountRecoveryOperatorMultisig.json') -const DharmaKeyRegistryMultisigArtifact = require('../../build/contracts/DharmaKeyRegistryMultisig.json') - -const DharmaEscapeHatchRegistryArtifact = require('../../build/contracts/DharmaEscapeHatchRegistry.json') - -const UpgradeBeaconImplementationCheckArtifact = require('../../build/contracts/UpgradeBeaconImplementationCheck.json') -const BadBeaconArtifact = require('../../build/contracts/BadBeacon.json') -const BadBeaconTwoArtifact = require('../../build/contracts/BadBeaconTwo.json') -const TimelockEdgecaseTesterArtifact = require('../../build/contracts/TimelockEdgecaseTester.json') - -const MockDharmaKeyRingFactoryArtifact = require('../../build/contracts/MockDharmaKeyRingFactory.json') -const IERC20Artifact = require('../../build/contracts/IERC20.json') -//const ComptrollerArtifact = require('../../build/contracts/ComptrollerInterface.json') const contractNames = Object.assign({}, constants.CONTRACT_NAMES) async function test(testingContext) { - const DharmaUpgradeBeaconController = new web3.eth.Contract( - DharmaUpgradeBeaconControllerArtifact.abi, - constants.UPGRADE_BEACON_CONTROLLER_ADDRESS - ) - - const DharmaUpgradeBeacon = new web3.eth.Contract( - DharmaUpgradeBeaconArtifact.abi, - constants.UPGRADE_BEACON_ADDRESS - ) - - const DharmaKeyRingUpgradeBeaconController = new web3.eth.Contract( - DharmaUpgradeBeaconControllerArtifact.abi, - constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS - ) - - const DharmaKeyRingUpgradeBeacon = new web3.eth.Contract( - DharmaKeyRingUpgradeBeaconArtifact.abi, - constants.KEY_RING_UPGRADE_BEACON_ADDRESS - ) - - const DharmaAccountRecoveryManagerV2 = new web3.eth.Contract( - DharmaAccountRecoveryManagerV2Artifact.abi, - constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS - ) - - /* - const DharmaKeyRegistryV1 = new web3.eth.Contract( - DharmaKeyRegistryV1Artifact.abi, - constants.KEY_REGISTRY_ADDRESS - ) - */ - - const DharmaKeyRegistryV2 = new web3.eth.Contract( - DharmaKeyRegistryV2Artifact.abi, - constants.KEY_REGISTRY_V2_ADDRESS - ) - - const DharmaUpgradeBeaconControllerManager = new web3.eth.Contract( - DharmaUpgradeBeaconControllerManagerArtifact.abi, - constants.UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS - ) - - const DharmaSmartWalletFactoryV1OnChain = new web3.eth.Contract( - DharmaSmartWalletFactoryV1Artifact.abi, - constants.FACTORY_ADDRESS - ) - - const Comptroller = new web3.eth.Contract( - constants.COMPTROLLER_ABI, - constants.COMPTROLLER_MAINNET_ADDRESS - ) - - const CSAI_BORROW = new web3.eth.Contract( - [{ - "constant": false, - "inputs": [{"name": "borrowAmount", "type": "uint256"}], - "name": "borrow", - "outputs": [{"name": "", "type": "uint256"}], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }], - constants.CSAI_MAINNET_ADDRESS - ) - - const FIAT_TOKEN = new web3.eth.Contract( - [ - { - "constant": true, "inputs": [], "name": "blacklister", - "outputs": [{"name": "", "type": "address"}], "payable": false, - "stateMutability": "view", "type": "function" - }, { - "constant": false, "inputs": [{"name": "_account", "type": "address"}], - "name": "unBlacklist", "outputs": [], "payable": false, - "stateMutability": "nonpayable", "type": "function" - }, { - "constant": false, "inputs": [{"name": "_account", "type": "address"}], - "name": "blacklist", "outputs": [], "payable": false, - "stateMutability": "nonpayable", "type": "function" - }, { - "constant": true, "inputs": [{"name": "_account", "type": "address"}], - "name": "isBlacklisted", "outputs": [{"name": "", "type": "bool"}], - "payable": false, "stateMutability": "view", "type": "function" - }, { - "constant": false, "inputs": [], - "name": "pause", "outputs": [], "payable": false, - "stateMutability": "nonpayable", "type": "function" - }, { - "constant": false, "inputs": [], - "name": "unpause", "outputs": [], "payable": false, - "stateMutability": "nonpayable", "type": "function" - }, { - "constant": true, "inputs": [], "name": "pauser", - "outputs": [{"name": "", "type": "address"}], "payable": false, - "stateMutability": "view", "type": "function" - } - ], - constants.USDC_MAINNET_ADDRESS - ) - - const SAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.SAI_MAINNET_ADDRESS - ) - - const DAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.DAI_MAINNET_ADDRESS - ) - - const USDC = new web3.eth.Contract( - IERC20Artifact.abi, constants.USDC_MAINNET_ADDRESS - ) - - const CSAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.CSAI_MAINNET_ADDRESS - ) - - const CDAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.CDAI_MAINNET_ADDRESS - ) - - const CUSDC = new web3.eth.Contract( - IERC20Artifact.abi, constants.CUSDC_MAINNET_ADDRESS - ) - - const BadBeaconDeployer = new web3.eth.Contract(BadBeaconArtifact.abi) - BadBeaconDeployer.options.data = BadBeaconArtifact.bytecode - - const BadBeaconTwoDeployer = new web3.eth.Contract(BadBeaconTwoArtifact.abi) - BadBeaconTwoDeployer.options.data = BadBeaconTwoArtifact.bytecode - - - const AdharmaSmartWalletImplementationDeployer = new web3.eth.Contract( - AdharmaSmartWalletImplementationArtifact.abi - ) - AdharmaSmartWalletImplementationDeployer.options.data = ( - AdharmaSmartWalletImplementationArtifact.bytecode - ) - - const DharmaSmartWalletImplementationV6Deployer = new web3.eth.Contract( - DharmaSmartWalletImplementationV6Artifact.abi - ) - DharmaSmartWalletImplementationV6Deployer.options.data = ( - DharmaSmartWalletImplementationV6Artifact.bytecode - ) - - const DharmaSmartWalletImplementationV7Deployer = new web3.eth.Contract( - DharmaSmartWalletImplementationV7Artifact.abi - ) - DharmaSmartWalletImplementationV7Deployer.options.data = ( - DharmaSmartWalletImplementationV7Artifact.bytecode - ) - - const AdharmaKeyRingImplementationDeployer = new web3.eth.Contract( - AdharmaKeyRingImplementationArtifact.abi - ) - AdharmaKeyRingImplementationDeployer.options.data = ( - AdharmaKeyRingImplementationArtifact.bytecode - ) - - const DharmaKeyRingImplementationV1Deployer = new web3.eth.Contract( - DharmaKeyRingImplementationV1Artifact.abi - ) - DharmaKeyRingImplementationV1Deployer.options.data = ( - DharmaKeyRingImplementationV1Artifact.bytecode - ) - - const UpgradeBeaconImplementationCheckDeployer = new web3.eth.Contract( - UpgradeBeaconImplementationCheckArtifact.abi - ) - UpgradeBeaconImplementationCheckDeployer.options.data = ( - UpgradeBeaconImplementationCheckArtifact.bytecode - ) - - const TimelockEdgecaseTesterDeployer = new web3.eth.Contract( - TimelockEdgecaseTesterArtifact.abi - ) - TimelockEdgecaseTesterDeployer.options.data = ( - TimelockEdgecaseTesterArtifact.bytecode - ) - - const DharmaUpgradeBeaconControllerDeployer = new web3.eth.Contract( - DharmaUpgradeBeaconControllerArtifact.abi - ) - DharmaUpgradeBeaconControllerDeployer.options.data = ( - DharmaUpgradeBeaconControllerArtifact.bytecode - ) - - const DharmaUpgradeBeaconDeployer = new web3.eth.Contract( - DharmaUpgradeBeaconArtifact.abi - ) - DharmaUpgradeBeaconDeployer.options.data = ( - DharmaUpgradeBeaconArtifact.bytecode - ) - - const DharmaKeyRingUpgradeBeaconDeployer = new web3.eth.Contract( - DharmaKeyRingUpgradeBeaconArtifact.abi - ) - DharmaKeyRingUpgradeBeaconDeployer.options.data = ( - DharmaKeyRingUpgradeBeaconArtifact.bytecode - ) - - const DharmaUpgradeBeaconEnvoyDeployer = new web3.eth.Contract( - DharmaUpgradeBeaconEnvoyArtifact.abi - ) - DharmaUpgradeBeaconEnvoyDeployer.options.data = ( - DharmaUpgradeBeaconEnvoyArtifact.bytecode - ) - - const DharmaUpgradeBeaconControllerManagerDeployer = new web3.eth.Contract( - DharmaUpgradeBeaconControllerManagerArtifact.abi - ) - DharmaUpgradeBeaconControllerManagerDeployer.options.data = ( - DharmaUpgradeBeaconControllerManagerArtifact.bytecode - ) - - const UpgradeBeaconProxyV1Deployer = new web3.eth.Contract( - UpgradeBeaconProxyV1Artifact.abi - ) - UpgradeBeaconProxyV1Deployer.options.data = ( - UpgradeBeaconProxyV1Artifact.bytecode - ) - - const KeyRingUpgradeBeaconProxyV1Deployer = new web3.eth.Contract( - KeyRingUpgradeBeaconProxyV1Artifact.abi - ) - KeyRingUpgradeBeaconProxyV1Deployer.options.data = ( - KeyRingUpgradeBeaconProxyV1Artifact.bytecode - ) - - const DharmaKeyRegistryV2Deployer = new web3.eth.Contract( - DharmaKeyRegistryV2Artifact.abi - ) - DharmaKeyRegistryV2Deployer.options.data = ( - DharmaKeyRegistryV2Artifact.bytecode - ) - - const DharmaSmartWalletFactoryV1Deployer = new web3.eth.Contract( - DharmaSmartWalletFactoryV1Artifact.abi - ) - DharmaSmartWalletFactoryV1Deployer.options.data = ( - DharmaSmartWalletFactoryV1Artifact.bytecode - ) - - const DharmaSmartWalletFactoryV2Deployer = new web3.eth.Contract( - DharmaSmartWalletFactoryV2Artifact.abi - ) - DharmaSmartWalletFactoryV2Deployer.options.data = ( - DharmaSmartWalletFactoryV2Artifact.bytecode - ) - - const DharmaKeyRingFactoryV1Deployer = new web3.eth.Contract( - DharmaKeyRingFactoryV1Artifact.abi - ) - DharmaKeyRingFactoryV1Deployer.options.data = ( - DharmaKeyRingFactoryV1Artifact.bytecode - ) - - const DharmaKeyRingFactoryV2Deployer = new web3.eth.Contract( - DharmaKeyRingFactoryV2Artifact.abi - ) - DharmaKeyRingFactoryV2Deployer.options.data = ( - DharmaKeyRingFactoryV2Artifact.bytecode - ) - - const DharmaKeyRingFactoryV3Deployer = new web3.eth.Contract( - DharmaKeyRingFactoryV3Artifact.abi - ) - DharmaKeyRingFactoryV3Deployer.options.data = ( - DharmaKeyRingFactoryV3Artifact.bytecode - ) - - const MockDharmaKeyRingFactoryDeployer = new web3.eth.Contract( - MockDharmaKeyRingFactoryArtifact.abi - ) - MockDharmaKeyRingFactoryDeployer.options.data = ( - MockDharmaKeyRingFactoryArtifact.bytecode - ) - - const DharmaAccountRecoveryManagerV2Deployer = new web3.eth.Contract( - DharmaAccountRecoveryManagerV2Artifact.abi - ) - DharmaAccountRecoveryManagerV2Deployer.options.data = ( - DharmaAccountRecoveryManagerV2Artifact.bytecode - ) - - const DharmaUpgradeMultisigDeployer = new web3.eth.Contract( - DharmaUpgradeMultisigArtifact.abi - ) - DharmaUpgradeMultisigDeployer.options.data = ( - DharmaUpgradeMultisigArtifact.bytecode - ) - - const DharmaAccountRecoveryMultisigDeployer = new web3.eth.Contract( - DharmaAccountRecoveryMultisigArtifact.abi - ) - DharmaAccountRecoveryMultisigDeployer.options.data = ( - DharmaAccountRecoveryMultisigArtifact.bytecode - ) - - const DharmaAccountRecoveryOperatorMultisigDeployer = new web3.eth.Contract( - DharmaAccountRecoveryOperatorMultisigArtifact.abi - ) - DharmaAccountRecoveryOperatorMultisigDeployer.options.data = ( - DharmaAccountRecoveryOperatorMultisigArtifact.bytecode - ) - - const DharmaKeyRegistryMultisigDeployer = new web3.eth.Contract( - DharmaKeyRegistryMultisigArtifact.abi - ) - DharmaKeyRegistryMultisigDeployer.options.data = ( - DharmaKeyRegistryMultisigArtifact.bytecode - ) - - const DharmaEscapeHatchRegistryDeployer = new web3.eth.Contract( - DharmaEscapeHatchRegistryArtifact.abi - ) - DharmaEscapeHatchRegistryDeployer.options.data = ( - DharmaEscapeHatchRegistryArtifact.bytecode - ) - const tester = new Tester(testingContext); await tester.init(); @@ -383,7 +29,7 @@ async function test(testingContext) { await tester.runTest( `DharmaUpgradeBeaconController can transfer owner`, - DharmaUpgradeBeaconController, + tester.DharmaUpgradeBeaconController, 'transferOwnership', 'send', [tester.address] @@ -391,7 +37,7 @@ async function test(testingContext) { await tester.runTest( 'Dharma Key Registry V2 gets the initial global key correctly', - DharmaKeyRegistryV2, + tester.DharmaKeyRegistryV2, 'getGlobalKey', 'call', [], @@ -402,7 +48,7 @@ async function test(testingContext) { ) const messageV2 = ( - DharmaKeyRegistryV2.options.address + + tester.DharmaKeyRegistryV2.options.address + tester.address.slice(2) + web3.utils.asciiToHex( "This signature demonstrates that the supplied signing key is valid." @@ -413,7 +59,7 @@ async function test(testingContext) { await tester.runTest( 'Dharma Key Registry V2 cannot set a previously used global key', - DharmaKeyRegistryV2, + tester.DharmaKeyRegistryV2, 'setGlobalKey', 'send', [ @@ -425,46 +71,46 @@ async function test(testingContext) { const BadBeacon = await tester.runTest( `Mock Bad Beacon contract deployment`, - BadBeaconDeployer, + tester.BadBeaconDeployer, '', 'deploy' ) const BadBeaconTwo = await tester.runTest( `Mock Bad Beacon Two contract deployment`, - BadBeaconTwoDeployer, + tester.BadBeaconTwoDeployer, '', 'deploy' ) const DharmaSmartWalletImplementationV6 = await tester.runTest( `DharmaSmartWalletImplementationV6 contract deployment`, - DharmaSmartWalletImplementationV6Deployer, + tester.DharmaSmartWalletImplementationV6Deployer, '', 'deploy' ) const DharmaSmartWalletImplementationV7 = await tester.runTest( `DharmaSmartWalletImplementationV7 contract deployment`, - DharmaSmartWalletImplementationV7Deployer, + tester.DharmaSmartWalletImplementationV7Deployer, '', 'deploy' ) const DharmaKeyRingImplementationV1 = await tester.runTest( `DharmaKeyRingImplementationV1 contract deployment`, - DharmaKeyRingImplementationV1Deployer, + tester.DharmaKeyRingImplementationV1Deployer, '', 'deploy' ) await tester.runTest( 'Dharma Upgrade Beacon Controller cannot set null address as implementation', - DharmaUpgradeBeaconController, + tester.DharmaUpgradeBeaconController, 'upgrade', 'send', [ - DharmaUpgradeBeacon.options.address, + tester.DharmaUpgradeBeacon.options.address, constants.NULL_ADDRESS ], false @@ -472,11 +118,11 @@ async function test(testingContext) { await tester.runTest( 'Dharma Upgrade Beacon Controller cannot set non-contract as implementation', - DharmaUpgradeBeaconController, + tester.DharmaUpgradeBeaconController, 'upgrade', 'send', [ - DharmaUpgradeBeacon.options.address, + tester.DharmaUpgradeBeacon.options.address, tester.address ], false @@ -484,7 +130,7 @@ async function test(testingContext) { await tester.runTest( 'Dharma Upgrade Beacon Controller cannot support a "bad" beacon that throws', - DharmaUpgradeBeaconController, + tester.DharmaUpgradeBeaconController, 'upgrade', 'send', [ @@ -496,7 +142,7 @@ async function test(testingContext) { await tester.runTest( 'Dharma Upgrade Beacon Controller cannot upgrade a non-upgradeable beacon', - DharmaUpgradeBeaconController, + tester.DharmaUpgradeBeaconController, 'upgrade', 'send', [ @@ -508,11 +154,11 @@ async function test(testingContext) { await tester.runTest( 'Dharma Upgrade Beacon Controller is inaccessible from a non-owner', - DharmaUpgradeBeaconController, + tester.DharmaUpgradeBeaconController, 'upgrade', 'send', [ - DharmaUpgradeBeacon.options.address, + tester.DharmaUpgradeBeacon.options.address, DharmaSmartWalletImplementationV6.options.address ], false, @@ -522,11 +168,11 @@ async function test(testingContext) { await tester.runTest( 'Dharma Upgrade Beacon Controller can set initial upgrade beacon implementation', - DharmaUpgradeBeaconController, + tester.DharmaUpgradeBeaconController, 'upgrade', 'send', [ - DharmaUpgradeBeacon.options.address, + tester.DharmaUpgradeBeacon.options.address, DharmaSmartWalletImplementationV6.options.address ], true, @@ -534,7 +180,7 @@ async function test(testingContext) { if (testingContext !== 'coverage') { assert.strictEqual( receipt.events.Upgraded.returnValues.upgradeBeacon, - DharmaUpgradeBeacon.options.address + tester.DharmaUpgradeBeacon.options.address ) assert.strictEqual( receipt.events.Upgraded.returnValues.oldImplementation, @@ -560,11 +206,11 @@ async function test(testingContext) { await tester.runTest( 'Dharma Upgrade Beacon Controller cannot clear upgrade beacon implementation', - DharmaUpgradeBeaconController, + tester.DharmaUpgradeBeaconController, 'upgrade', 'send', [ - DharmaUpgradeBeacon.options.address, + tester.DharmaUpgradeBeacon.options.address, constants.NULL_ADDRESS ], false @@ -572,11 +218,11 @@ async function test(testingContext) { await tester.runTest( 'Dharma Upgrade Beacon Controller can reset upgrade beacon implementation', - DharmaUpgradeBeaconController, + tester.DharmaUpgradeBeaconController, 'upgrade', 'send', [ - DharmaUpgradeBeacon.options.address, + tester.DharmaUpgradeBeacon.options.address, DharmaSmartWalletImplementationV6.options.address ], true, @@ -584,7 +230,7 @@ async function test(testingContext) { if (testingContext !== 'coverage') { assert.strictEqual( receipt.events.Upgraded.returnValues.upgradeBeacon, - DharmaUpgradeBeacon.options.address + tester.DharmaUpgradeBeacon.options.address ) assert.strictEqual( receipt.events.Upgraded.returnValues.oldImplementation, @@ -612,21 +258,21 @@ async function test(testingContext) { const UpgradeBeaconImplementationCheck = await tester.runTest( `UpgradeBeaconImplementationCheck deployment`, - UpgradeBeaconImplementationCheckDeployer, + tester.UpgradeBeaconImplementationCheckDeployer, '', 'deploy', [ - DharmaUpgradeBeacon.options.address, + tester.DharmaUpgradeBeacon.options.address, DharmaSmartWalletImplementationV6.options.address ] ) await tester.runTest( 'DharmaUpgradeBeacon has the implementation set', - DharmaUpgradeBeaconController, + tester.DharmaUpgradeBeaconController, 'getImplementation', 'call', - [DharmaUpgradeBeacon.options.address], + [tester.DharmaUpgradeBeacon.options.address], true, value => { assert.strictEqual(value, DharmaSmartWalletImplementationV6.options.address) @@ -635,11 +281,11 @@ async function test(testingContext) { await tester.runTest( 'Dharma Key Ring Upgrade Beacon Controller can set initial key ring upgrade beacon implementation', - DharmaKeyRingUpgradeBeaconController, + tester.DharmaKeyRingUpgradeBeaconController, 'upgrade', 'send', [ - DharmaKeyRingUpgradeBeacon.options.address, + tester.DharmaKeyRingUpgradeBeacon.options.address, DharmaKeyRingImplementationV1.options.address ], true, @@ -647,7 +293,7 @@ async function test(testingContext) { if (testingContext !== 'coverage') { assert.strictEqual( receipt.events.Upgraded.returnValues.upgradeBeacon, - DharmaKeyRingUpgradeBeacon.options.address + tester.DharmaKeyRingUpgradeBeacon.options.address ) assert.strictEqual( receipt.events.Upgraded.returnValues.oldImplementation, @@ -673,21 +319,21 @@ async function test(testingContext) { const KeyRingUpgradeBeaconImplementationCheck = await tester.runTest( `KeyRingUpgradeBeaconImplementationCheck deployment`, - UpgradeBeaconImplementationCheckDeployer, + tester.UpgradeBeaconImplementationCheckDeployer, '', 'deploy', [ - DharmaKeyRingUpgradeBeacon.options.address, + tester.DharmaKeyRingUpgradeBeacon.options.address, DharmaKeyRingImplementationV1.options.address ] ) await tester.runTest( 'DharmaKeyRingUpgradeBeacon has the implementation set', - DharmaKeyRingUpgradeBeaconController, + tester.DharmaKeyRingUpgradeBeaconController, 'getImplementation', 'call', - [DharmaKeyRingUpgradeBeacon.options.address], + [tester.DharmaKeyRingUpgradeBeacon.options.address], true, value => { assert.strictEqual(value, DharmaKeyRingImplementationV1.options.address) @@ -697,7 +343,7 @@ async function test(testingContext) { const DharmaSmartWalletNoFactoryNoConstructorDeployer = new web3.eth.Contract([]) DharmaSmartWalletNoFactoryNoConstructorDeployer.options.data = ( '0x600b5981380380925939f359595959365960205959596e' + - DharmaUpgradeBeacon.options.address.slice(12).toLowerCase() + + tester.DharmaUpgradeBeacon.options.address.slice(12).toLowerCase() + '5afa1551368280375af43d3d93803e602e57fd5bf3' ) @@ -760,9 +406,9 @@ async function test(testingContext) { const DharmaSmartWalletNoFactoryDeployer = new web3.eth.Contract([]) DharmaSmartWalletNoFactoryDeployer.options.data = ( '0x595959596076380359602059595973' + - DharmaUpgradeBeacon.options.address.slice(2).toLowerCase() + + tester.DharmaUpgradeBeacon.options.address.slice(2).toLowerCase() + '5afa155182607683395af46038573d903d81803efd5b60356041819339f3595959593659602059595973' + - DharmaUpgradeBeacon.options.address.slice(2).toLowerCase() + + tester.DharmaUpgradeBeacon.options.address.slice(2).toLowerCase() + '5afa1551368280375af43d3d93803e603357fd5bf3' + 'c4d66de80000000000000000000000009999999999999999999999999999999999999999' ) @@ -805,7 +451,7 @@ async function test(testingContext) { const DharmaSmartWalletFactoryV1 = await tester.runTest( `DharmaSmartWalletFactoryV1 contract deployment`, - DharmaSmartWalletFactoryV1Deployer, + tester.DharmaSmartWalletFactoryV1Deployer, '', 'deploy', [] @@ -839,8 +485,8 @@ async function test(testingContext) { tester, DharmaSmartWalletImplementationV6, // new implementation UserSmartWalletV6, - DharmaUpgradeBeaconController, - DharmaUpgradeBeacon.options.address, + tester.DharmaUpgradeBeaconController, + tester.DharmaUpgradeBeacon.options.address, 6, true ) @@ -908,7 +554,7 @@ async function test(testingContext) { await tester.runTest( 'Dai Whale can deposit dai into the yet-to-be-deployed smart wallet', - DAI, + tester.DAI, 'transfer', 'send', [targetWalletAddress, web3.utils.toWei('100', 'ether')], @@ -934,7 +580,7 @@ async function test(testingContext) { await tester.runTest( 'USDC Whale can deposit usdc into the yet-to-be-deployed smart wallet', - USDC, + tester.USDC, 'transfer', 'send', [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals @@ -1146,7 +792,7 @@ async function test(testingContext) { await tester.runTest( 'cSai can be sent to V6 UserSmartWallet', - CSAI, + tester.CSAI, 'transfer', 'send', [UserSmartWalletV6.options.address, web3.utils.toWei('0.5', 'mwei')] @@ -1256,7 +902,7 @@ async function test(testingContext) { await tester.runTest( 'Dai Whale can deposit Dai into the V6 smart wallet', - DAI, + tester.DAI, 'transfer', 'send', [targetWalletAddress, web3.utils.toWei('100', 'ether')], @@ -1282,7 +928,7 @@ async function test(testingContext) { await tester.runTest( 'USDC Whale can deposit usdc into the V6 smart wallet', - USDC, + tester.USDC, 'transfer', 'send', [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals @@ -1312,8 +958,8 @@ async function test(testingContext) { 'getNextGenericActionID', 'call', [ - DAI.options.address, - DAI.methods.approve(CDAI.options.address, 0).encodeABI(), + tester.DAI.options.address, + tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), 0 ], true, @@ -1338,8 +984,8 @@ async function test(testingContext) { 'executeAction', 'send', [ - DAI.options.address, - DAI.methods.approve(CDAI.options.address, 0).encodeABI(), + tester.DAI.options.address, + tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -1405,7 +1051,7 @@ async function test(testingContext) { await tester.runTest( 'Dai Whale can deposit dai into the V6 smart wallet', - DAI, + tester.DAI, 'transfer', 'send', [targetWalletAddress, web3.utils.toWei('100', 'ether')], @@ -1476,8 +1122,8 @@ async function test(testingContext) { 'getNextGenericActionID', 'call', [ - DAI.options.address, - DAI.methods.approve(CDAI.options.address, 0).encodeABI(), + tester.DAI.options.address, + tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), 0 ], true, @@ -1502,8 +1148,8 @@ async function test(testingContext) { 'executeAction', 'send', [ - DAI.options.address, - DAI.methods.approve(CDAI.options.address, 0).encodeABI(), + tester.DAI.options.address, + tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -1544,8 +1190,8 @@ async function test(testingContext) { 'getNextGenericActionID', 'call', [ - DAI.options.address, - DAI.methods.approve(CDAI.options.address, constants.FULL_APPROVAL).encodeABI(), + tester.DAI.options.address, + tester.DAI.methods.approve(tester.CDAI.options.address, constants.FULL_APPROVAL).encodeABI(), 0 ], true, @@ -1570,8 +1216,8 @@ async function test(testingContext) { 'executeAction', 'send', [ - DAI.options.address, - DAI.methods.approve(CDAI.options.address, constants.FULL_APPROVAL).encodeABI(), + tester.DAI.options.address, + tester.DAI.methods.approve(tester.CDAI.options.address, constants.FULL_APPROVAL).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -2764,8 +2410,8 @@ async function test(testingContext) { 'getNextGenericActionID', 'call', [ - USDC.options.address, - USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), + tester.USDC.options.address, + tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), 0 ], true, @@ -2791,7 +2437,7 @@ async function test(testingContext) { 'send', [ tester.address, - USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), + tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -2806,7 +2452,7 @@ async function test(testingContext) { 'send', [ UserSmartWalletV6.options.address, - USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), + tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -2820,8 +2466,8 @@ async function test(testingContext) { 'executeAction', 'send', [ - USDC.options.address, - USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), + tester.USDC.options.address, + tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -2834,7 +2480,7 @@ async function test(testingContext) { 'getNextGenericAtomicBatchActionID', 'call', [ - [{to: SAI.options.address, data: SAI.methods.totalSupply().encodeABI()}], + [{to: tester.SAI.options.address, data: tester.SAI.methods.totalSupply().encodeABI()}], 0 ], true, @@ -2861,7 +2507,7 @@ async function test(testingContext) { 'getGenericAtomicBatchActionID', 'call', [ - [{to: SAI.options.address, data: SAI.methods.totalSupply().encodeABI()}], + [{to: tester.SAI.options.address, data: tester.SAI.methods.totalSupply().encodeABI()}], currentNonce, 0 ], @@ -2887,7 +2533,7 @@ async function test(testingContext) { 'executeActionWithAtomicBatchCalls', 'send', [ - [{to: SAI.options.address, data: SAI.methods.totalSupply().encodeABI()}], + [{to: tester.SAI.options.address, data: tester.SAI.methods.totalSupply().encodeABI()}], 0, executeActionUserSignature, executeActionSignature @@ -2896,7 +2542,7 @@ async function test(testingContext) { await tester.runTest( 'USDC Whale can deposit usdc into the deployed smart wallet', - USDC, + tester.USDC, 'transfer', 'send', [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals @@ -2965,7 +2611,7 @@ async function test(testingContext) { await tester.runTest( 'Check blacklister address', - FIAT_TOKEN, + tester.FIAT_TOKEN, 'blacklister', 'call', [], @@ -2977,7 +2623,7 @@ async function test(testingContext) { await tester.runTest( 'Check pauser address', - FIAT_TOKEN, + tester.FIAT_TOKEN, 'pauser', 'call', [], @@ -2989,7 +2635,7 @@ async function test(testingContext) { await tester.runTest( 'blacklist mock address', - FIAT_TOKEN, + tester.FIAT_TOKEN, 'blacklist', 'send', [constants.MOCK_USDC_BLACKLISTED_ADDRESS], @@ -3017,7 +2663,7 @@ async function test(testingContext) { await tester.runTest( 'USDC Whale can deposit usdc into the yet-to-be-blacklisted smart wallet', - USDC, + tester.USDC, 'transfer', 'send', [targetBlacklistAddress, web3.utils.toWei('100', 'lovelace')], // six decimals @@ -3043,7 +2689,7 @@ async function test(testingContext) { await tester.runTest( 'blacklist counterfactual deployment address', - FIAT_TOKEN, + tester.FIAT_TOKEN, 'blacklist', 'send', [targetBlacklistAddress], @@ -3080,7 +2726,7 @@ async function test(testingContext) { await tester.runTest( 'un-blacklist counterfactual deployment address', - FIAT_TOKEN, + tester.FIAT_TOKEN, 'unBlacklist', 'send', [targetBlacklistAddress], @@ -3091,7 +2737,7 @@ async function test(testingContext) { await tester.runTest( 'pause USDC', - FIAT_TOKEN, + tester.FIAT_TOKEN, 'pause', 'send', [], @@ -3162,7 +2808,7 @@ async function test(testingContext) { await tester.runTest( 'unpause USDC', - FIAT_TOKEN, + tester.FIAT_TOKEN, 'unpause', 'send', [], @@ -3419,8 +3065,8 @@ async function test(testingContext) { 'getNextGenericActionID', 'call', [ - SAI.options.address, - SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), + tester.SAI.options.address, + tester.SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), 0 ], true, @@ -3445,8 +3091,8 @@ async function test(testingContext) { 'executeAction', 'send', [ - SAI.options.address, - SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), + tester.SAI.options.address, + tester.SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -3601,8 +3247,8 @@ async function test(testingContext) { 'call', [ [{ - to: DAI.options.address, - data: DAI.methods.transfer( + to: tester.DAI.options.address, + data: tester.DAI.methods.transfer( tester.address, '100000000000000000000000000000' ).encodeABI() }], @@ -3631,8 +3277,8 @@ async function test(testingContext) { 'send', [ [{ - to: DAI.options.address, - data: DAI.methods.transfer( + to: tester.DAI.options.address, + data: tester.DAI.methods.transfer( tester.address, '100000000000000000000000000000' ).encodeABI() }], @@ -3652,8 +3298,8 @@ async function test(testingContext) { 'getNextGenericActionID', 'call', [ - Comptroller.options.address, - Comptroller.methods.enterMarkets( + tester.Comptroller.options.address, + tester.Comptroller.methods.enterMarkets( [constants.CDAI_MAINNET_ADDRESS] ).encodeABI(), 0 @@ -3680,8 +3326,8 @@ async function test(testingContext) { 'executeAction', 'send', [ - Comptroller.options.address, - Comptroller.methods.enterMarkets( + tester.Comptroller.options.address, + tester.Comptroller.methods.enterMarkets( [constants.CDAI_MAINNET_ADDRESS] ).encodeABI(), 0, @@ -3692,7 +3338,7 @@ async function test(testingContext) { await tester.runTest( 'Dai Whale can deposit dai into the smart wallet', - DAI, + tester.DAI, 'transfer', 'send', [targetWalletAddress, web3.utils.toWei('100', 'ether')], @@ -3728,8 +3374,8 @@ async function test(testingContext) { 'getNextGenericActionID', 'call', [ - CSAI_BORROW.options.address, - CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), + tester.CSAI_BORROW.options.address, + tester.CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), 0 ], true, @@ -3754,8 +3400,8 @@ async function test(testingContext) { 'executeAction', 'send', [ - CSAI_BORROW.options.address, - CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), + tester.CSAI_BORROW.options.address, + tester.CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -3822,8 +3468,8 @@ async function test(testingContext) { tester, DharmaSmartWalletImplementationV7, // new implementation UserSmartWalletV7, - DharmaUpgradeBeaconController, - DharmaUpgradeBeacon.options.address, + tester.DharmaUpgradeBeaconController, + tester.DharmaUpgradeBeacon.options.address, 7 ) @@ -3914,7 +3560,7 @@ async function test(testingContext) { await tester.runTest( 'cSai can be sent to V7 UserSmartWallet', - CSAI, + tester.CSAI, 'transfer', 'send', [UserSmartWalletV7.options.address, web3.utils.toWei('0.5', 'mwei')] @@ -4024,7 +3670,7 @@ async function test(testingContext) { await tester.runTest( 'Dai Whale can deposit Dai into the V7 smart wallet', - DAI, + tester.DAI, 'transfer', 'send', [targetWalletAddress, web3.utils.toWei('100', 'ether')], @@ -4050,7 +3696,7 @@ async function test(testingContext) { await tester.runTest( 'USDC Whale can deposit usdc into the V7 smart wallet', - USDC, + tester.USDC, 'transfer', 'send', [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals @@ -4080,8 +3726,8 @@ async function test(testingContext) { 'getNextGenericActionID', 'call', [ - DAI.options.address, - DAI.methods.approve(CDAI.options.address, 0).encodeABI(), + tester.DAI.options.address, + tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), 0 ], true, @@ -4106,8 +3752,8 @@ async function test(testingContext) { 'executeAction', 'send', [ - DAI.options.address, - DAI.methods.approve(CDAI.options.address, 0).encodeABI(), + tester.DAI.options.address, + tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -4128,7 +3774,7 @@ async function test(testingContext) { await tester.runTest( 'Dai Whale can deposit dai into the V7 smart wallet', - DAI, + tester.DAI, 'transfer', 'send', [targetWalletAddress, web3.utils.toWei('100', 'ether')], @@ -4199,8 +3845,8 @@ async function test(testingContext) { 'getNextGenericActionID', 'call', [ - DAI.options.address, - DAI.methods.approve(CDAI.options.address, 0).encodeABI(), + tester.DAI.options.address, + tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), 0 ], true, @@ -4225,8 +3871,8 @@ async function test(testingContext) { 'executeAction', 'send', [ - DAI.options.address, - DAI.methods.approve(CDAI.options.address, 0).encodeABI(), + tester.DAI.options.address, + tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -4251,8 +3897,8 @@ async function test(testingContext) { 'getNextGenericActionID', 'call', [ - DAI.options.address, - DAI.methods.approve(CDAI.options.address, constants.FULL_APPROVAL).encodeABI(), + tester.DAI.options.address, + tester.DAI.methods.approve(tester.CDAI.options.address, constants.FULL_APPROVAL).encodeABI(), 0 ], true, @@ -4277,8 +3923,8 @@ async function test(testingContext) { 'executeAction', 'send', [ - DAI.options.address, - DAI.methods.approve(CDAI.options.address, constants.FULL_APPROVAL).encodeABI(), + tester.DAI.options.address, + tester.DAI.methods.approve(tester.CDAI.options.address, constants.FULL_APPROVAL).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -5439,8 +5085,8 @@ async function test(testingContext) { 'getNextGenericActionID', 'call', [ - USDC.options.address, - USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), + tester.USDC.options.address, + tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), 0 ], true, @@ -5466,7 +5112,7 @@ async function test(testingContext) { 'send', [ tester.address, - USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), + tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -5481,7 +5127,7 @@ async function test(testingContext) { 'send', [ UserSmartWalletV7.options.address, - USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), + tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -5495,8 +5141,8 @@ async function test(testingContext) { 'executeAction', 'send', [ - USDC.options.address, - USDC.methods.approve(CUSDC.options.address, 0).encodeABI(), + tester.USDC.options.address, + tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -5509,7 +5155,7 @@ async function test(testingContext) { 'getNextGenericAtomicBatchActionID', 'call', [ - [{to: SAI.options.address, data: SAI.methods.totalSupply().encodeABI()}], + [{to: tester.SAI.options.address, data: tester.SAI.methods.totalSupply().encodeABI()}], 0 ], true, @@ -5536,7 +5182,7 @@ async function test(testingContext) { 'getGenericAtomicBatchActionID', 'call', [ - [{to: SAI.options.address, data: SAI.methods.totalSupply().encodeABI()}], + [{to: tester.SAI.options.address, data: tester.SAI.methods.totalSupply().encodeABI()}], currentNonce, 0 ], @@ -5562,7 +5208,7 @@ async function test(testingContext) { 'executeActionWithAtomicBatchCalls', 'send', [ - [{to: SAI.options.address, data: SAI.methods.totalSupply().encodeABI()}], + [{to: tester.SAI.options.address, data: tester.SAI.methods.totalSupply().encodeABI()}], 0, executeActionUserSignature, executeActionSignature @@ -5571,7 +5217,7 @@ async function test(testingContext) { await tester.runTest( 'USDC Whale can deposit usdc into the deployed smart wallet', - USDC, + tester.USDC, 'transfer', 'send', [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals @@ -5609,7 +5255,7 @@ async function test(testingContext) { await tester.runTest( 'Check blacklister address', - FIAT_TOKEN, + tester.FIAT_TOKEN, 'blacklister', 'call', [], @@ -5621,7 +5267,7 @@ async function test(testingContext) { await tester.runTest( 'Check pauser address', - FIAT_TOKEN, + tester.FIAT_TOKEN, 'pauser', 'call', [], @@ -5633,7 +5279,7 @@ async function test(testingContext) { await tester.runTest( 'blacklist mock address', - FIAT_TOKEN, + tester.FIAT_TOKEN, 'blacklist', 'send', [constants.MOCK_USDC_BLACKLISTED_ADDRESS], @@ -5661,7 +5307,7 @@ async function test(testingContext) { await tester.runTest( 'USDC Whale can deposit usdc into the yet-to-be-blacklisted smart wallet', - USDC, + tester.USDC, 'transfer', 'send', [targetBlacklistAddress, web3.utils.toWei('100', 'lovelace')], // six decimals @@ -5687,7 +5333,7 @@ async function test(testingContext) { await tester.runTest( 'blacklist counterfactual deployment address', - FIAT_TOKEN, + tester.FIAT_TOKEN, 'blacklist', 'send', [targetBlacklistAddress], @@ -5724,7 +5370,7 @@ async function test(testingContext) { await tester.runTest( 'un-blacklist counterfactual deployment address', - FIAT_TOKEN, + tester.FIAT_TOKEN, 'unBlacklist', 'send', [targetBlacklistAddress], @@ -5735,7 +5381,7 @@ async function test(testingContext) { await tester.runTest( 'pause USDC', - FIAT_TOKEN, + tester.FIAT_TOKEN, 'pause', 'send', [], @@ -5806,7 +5452,7 @@ async function test(testingContext) { await tester.runTest( 'unpause USDC', - FIAT_TOKEN, + tester.FIAT_TOKEN, 'unpause', 'send', [], @@ -6063,8 +5709,8 @@ async function test(testingContext) { 'getNextGenericActionID', 'call', [ - SAI.options.address, - SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), + tester.SAI.options.address, + tester.SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), 0 ], true, @@ -6089,8 +5735,8 @@ async function test(testingContext) { 'executeAction', 'send', [ - SAI.options.address, - SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), + tester.SAI.options.address, + tester.SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -6245,8 +5891,8 @@ async function test(testingContext) { 'call', [ [{ - to: DAI.options.address, - data: DAI.methods.transfer( + to: tester.DAI.options.address, + data: tester.DAI.methods.transfer( tester.address, '100000000000000000000000000000' ).encodeABI() }], @@ -6275,8 +5921,8 @@ async function test(testingContext) { 'send', [ [{ - to: DAI.options.address, - data: DAI.methods.transfer( + to: tester.DAI.options.address, + data: tester.DAI.methods.transfer( tester.address, '100000000000000000000000000000' ).encodeABI() }], @@ -6296,8 +5942,8 @@ async function test(testingContext) { 'getNextGenericActionID', 'call', [ - Comptroller.options.address, - Comptroller.methods.enterMarkets( + tester.Comptroller.options.address, + tester.Comptroller.methods.enterMarkets( [constants.CDAI_MAINNET_ADDRESS] ).encodeABI(), 0 @@ -6324,8 +5970,8 @@ async function test(testingContext) { 'executeAction', 'send', [ - Comptroller.options.address, - Comptroller.methods.enterMarkets( + tester.Comptroller.options.address, + tester.Comptroller.methods.enterMarkets( [constants.CDAI_MAINNET_ADDRESS] ).encodeABI(), 0, @@ -6336,7 +5982,7 @@ async function test(testingContext) { await tester.runTest( 'Dai Whale can deposit dai into the smart wallet', - DAI, + tester.DAI, 'transfer', 'send', [targetWalletAddress, web3.utils.toWei('100', 'ether')], @@ -6372,8 +6018,8 @@ async function test(testingContext) { 'getNextGenericActionID', 'call', [ - CSAI_BORROW.options.address, - CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), + tester.CSAI_BORROW.options.address, + tester.CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), 0 ], true, @@ -6398,8 +6044,8 @@ async function test(testingContext) { 'executeAction', 'send', [ - CSAI_BORROW.options.address, - CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), + tester.CSAI_BORROW.options.address, + tester.CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), 0, executeActionUserSignature, executeActionSignature @@ -6728,7 +6374,7 @@ async function test(testingContext) { await tester.runTest( 'cSai can be sent to V7 UserSmartWallet', - CSAI, + tester.CSAI, 'transfer', 'send', [UserSmartWalletV7.options.address, web3.utils.toWei('0.5', 'mwei')] @@ -6736,7 +6382,7 @@ async function test(testingContext) { await tester.runTest( 'Sai Whale can deposit sai into the V7 user smart wallet', - SAI, + tester.SAI, 'transfer', 'send', [UserSmartWalletV7.options.address, web3.utils.toWei('1', 'ether')], @@ -6789,7 +6435,7 @@ async function test(testingContext) { // Initiate account recovery await tester.runTest( 'smart wallet account recovery can be initiated', - DharmaAccountRecoveryManagerV2, + tester.DharmaAccountRecoveryManagerV2, 'initiateAccountRecovery', 'send', [ @@ -6806,7 +6452,7 @@ async function test(testingContext) { await tester.runTest( 'smart wallet account recovery cannot be performed right away', - DharmaAccountRecoveryManagerV2, + tester.DharmaAccountRecoveryManagerV2, 'recover', 'send', [ @@ -6822,7 +6468,7 @@ async function test(testingContext) { // recover account await tester.runTest( 'smart wallet account recovery can be performed after three days', - DharmaAccountRecoveryManagerV2, + tester.DharmaAccountRecoveryManagerV2, 'recover', 'send', [ @@ -6841,35 +6487,35 @@ async function test(testingContext) { // COVERAGE TESTING - deployments const DharmaUpgradeBeaconControllerManagerCoverage = await tester.runTest( `DharmaUpgradeBeaconControllerManager contract deployment`, - DharmaUpgradeBeaconControllerManagerDeployer, + tester.DharmaUpgradeBeaconControllerManagerDeployer, '', 'deploy' ) const DharmaUpgradeBeaconControllerCoverage = await tester.runTest( `DharmaUpgradeBeaconController contract deployment`, - DharmaUpgradeBeaconControllerDeployer, + tester.DharmaUpgradeBeaconControllerDeployer, '', 'deploy' ) const DharmaUpgradeBeaconCoverage = await tester.runTest( `DharmaUpgradeBeacon (smart wallet) contract deployment`, - DharmaUpgradeBeaconDeployer, + tester.DharmaUpgradeBeaconDeployer, '', 'deploy' ) const DharmaKeyRingUpgradeBeaconCoverage = await tester.runTest( `DharmaKeyRingUpgradeBeacon contract deployment`, - DharmaKeyRingUpgradeBeaconDeployer, + tester.DharmaKeyRingUpgradeBeaconDeployer, '', 'deploy' ) const DharmaUpgradeBeaconEnvoy = await tester.runTest( `DharmaUpgradeBeaconEnvoy contract deployment`, - DharmaUpgradeBeaconEnvoyDeployer, + tester.DharmaUpgradeBeaconEnvoyDeployer, '', 'deploy' ) @@ -6877,8 +6523,8 @@ async function test(testingContext) { await testUpgradeBeaconController( tester, DharmaUpgradeBeaconControllerCoverage, // controller manager - DharmaUpgradeBeaconController, // smart wallet controller contract - DharmaKeyRingUpgradeBeaconController, // key ring controller contract + tester.DharmaUpgradeBeaconController, // smart wallet controller contract + tester.DharmaKeyRingUpgradeBeaconController, // key ring controller contract DharmaUpgradeBeaconEnvoy, // envoy contract DharmaUpgradeBeaconCoverage.options.address, // owned smart wallet beacon DharmaKeyRingUpgradeBeaconCoverage.options.address, // owned key ring beacon @@ -6887,28 +6533,28 @@ async function test(testingContext) { const DharmaKeyRegistryV2Coverage = await tester.runTest( `DharmaKeyRegistryV2 contract deployment`, - DharmaKeyRegistryV2Deployer, + tester.DharmaKeyRegistryV2Deployer, '', 'deploy' ) const AdharmaSmartWalletImplementation = await tester.runTest( `AdharmaSmartWalletImplementation contract deployment`, - AdharmaSmartWalletImplementationDeployer, + tester.AdharmaSmartWalletImplementationDeployer, '', 'deploy' ) const AdharmaKeyRingImplementation = await tester.runTest( `AdharmaKeyRingImplementation contract deployment`, - AdharmaKeyRingImplementationDeployer, + tester.AdharmaKeyRingImplementationDeployer, '', 'deploy' ) const DharmaSmartWalletFactoryV1Coverage = await tester.runTest( `DharmaSmartWalletFactoryV1 contract deployment`, - DharmaSmartWalletFactoryV1Deployer, + tester.DharmaSmartWalletFactoryV1Deployer, '', 'deploy', [] @@ -6916,7 +6562,7 @@ async function test(testingContext) { const DharmaKeyRingFactoryV1 = await tester.runTest( `DharmaKeyRingFactoryV1 contract deployment`, - DharmaKeyRingFactoryV1Deployer, + tester.DharmaKeyRingFactoryV1Deployer, '', 'deploy', [] @@ -6924,7 +6570,7 @@ async function test(testingContext) { const DharmaKeyRingFactoryV2 = await tester.runTest( `DharmaKeyRingFactoryV2 contract deployment`, - DharmaKeyRingFactoryV2Deployer, + tester.DharmaKeyRingFactoryV2Deployer, '', 'deploy', [] @@ -7271,7 +6917,7 @@ async function test(testingContext) { await tester.runTest( `UpgradeBeaconProxyV1 contract deployment fails with no init data`, - UpgradeBeaconProxyV1Deployer, + tester.UpgradeBeaconProxyV1Deployer, '', 'deploy', ['0x'], @@ -7280,7 +6926,7 @@ async function test(testingContext) { await tester.runTest( `KeyRingUpgradeBeaconProxyV1 contract deployment fails with no init data`, - KeyRingUpgradeBeaconProxyV1Deployer, + tester.KeyRingUpgradeBeaconProxyV1Deployer, '', 'deploy', ['0x'], @@ -7289,7 +6935,7 @@ async function test(testingContext) { const UpgradeBeaconProxyV1 = await tester.runTest( `UpgradeBeaconProxyV1 contract deployment (direct)`, - UpgradeBeaconProxyV1Deployer, + tester.UpgradeBeaconProxyV1Deployer, '', 'deploy', [web3.eth.abi.encodeFunctionCall({ @@ -7321,7 +6967,7 @@ async function test(testingContext) { const KeyRingUpgradeBeaconProxyV1 = await tester.runTest( `KeyRingUpgradeBeaconProxyV1 contract deployment (direct)`, - KeyRingUpgradeBeaconProxyV1Deployer, + tester.KeyRingUpgradeBeaconProxyV1Deployer, '', 'deploy', [web3.eth.abi.encodeFunctionCall({ @@ -7386,12 +7032,12 @@ async function test(testingContext) { */ await testKeyRegistryV2( - tester, DharmaKeyRegistryV2Coverage, DharmaKeyRegistryV2.options.address + tester, DharmaKeyRegistryV2Coverage, tester.DharmaKeyRegistryV2.options.address ) const DharmaAccountRecoveryManagerV2Coverage = await tester.runTest( `DharmaAccountRecoveryManagerV2 contract deployment`, - DharmaAccountRecoveryManagerV2Deployer, + tester.DharmaAccountRecoveryManagerV2Deployer, '', 'deploy' ) @@ -7409,7 +7055,7 @@ async function test(testingContext) { const MockDharmaKeyRingFactory = await tester.runTest( `MockDharmaKeyRingFactory contract deployment`, - MockDharmaKeyRingFactoryDeployer, + tester.MockDharmaKeyRingFactoryDeployer, '', 'deploy', [] @@ -7462,22 +7108,22 @@ async function test(testingContext) { await tester.runTest( 'Dharma Upgrade Beacon Controller can upgrade to AdharmaSmartWalletImplementation', - DharmaUpgradeBeaconController, + tester.DharmaUpgradeBeaconController, 'upgrade', 'send', [ - DharmaUpgradeBeacon.options.address, + tester.DharmaUpgradeBeacon.options.address, AdharmaSmartWalletImplementation.options.address ] ) await tester.runTest( 'Dharma Key Ring Upgrade Beacon Controller can upgrade to AdharmaKeyRingImplementation', - DharmaKeyRingUpgradeBeaconController, + tester.DharmaKeyRingUpgradeBeaconController, 'upgrade', 'send', [ - DharmaKeyRingUpgradeBeacon.options.address, + tester.DharmaKeyRingUpgradeBeacon.options.address, AdharmaKeyRingImplementation.options.address ] ) @@ -7674,7 +7320,7 @@ async function test(testingContext) { await tester.runTest( `TimelockEdgecaseTester contract deployment edge case 1`, - TimelockEdgecaseTesterDeployer, + tester.TimelockEdgecaseTesterDeployer, '', 'deploy', [0], @@ -7683,7 +7329,7 @@ async function test(testingContext) { await tester.runTest( `TimelockEdgecaseTester contract deployment edge case 2`, - TimelockEdgecaseTesterDeployer, + tester.TimelockEdgecaseTesterDeployer, '', 'deploy', [1], @@ -7692,7 +7338,7 @@ async function test(testingContext) { await tester.runTest( `TimelockEdgecaseTester contract deployment edge case 3`, - TimelockEdgecaseTesterDeployer, + tester.TimelockEdgecaseTesterDeployer, '', 'deploy', [2], @@ -7701,7 +7347,7 @@ async function test(testingContext) { const DharmaUpgradeMultisig = await tester.runTest( `DharmaUpgradeMultisig contract deployment`, - DharmaUpgradeMultisigDeployer, + tester.DharmaUpgradeMultisigDeployer, '', 'deploy', [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] @@ -7709,7 +7355,7 @@ async function test(testingContext) { const DharmaAccountRecoveryMultisig = await tester.runTest( `DharmaAccountRecoveryMultisig contract deployment`, - DharmaAccountRecoveryMultisigDeployer, + tester.DharmaAccountRecoveryMultisigDeployer, '', 'deploy', [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour]] @@ -7717,7 +7363,7 @@ async function test(testingContext) { const DharmaAccountRecoveryOperatorMultisig = await tester.runTest( `DharmaAccountRecoveryOperatorMultisig contract deployment`, - DharmaAccountRecoveryOperatorMultisigDeployer, + tester.DharmaAccountRecoveryOperatorMultisigDeployer, '', 'deploy', [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour]] @@ -7725,7 +7371,7 @@ async function test(testingContext) { const DharmaKeyRegistryMultisig = await tester.runTest( `DharmaKeyRegistryMultisig contract deployment`, - DharmaKeyRegistryMultisigDeployer, + tester.DharmaKeyRegistryMultisigDeployer, '', 'deploy', [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] @@ -8495,7 +8141,7 @@ async function test(testingContext) { const DharmaEscapeHatchRegistry = await tester.runTest( `DharmaEscapeHatchRegistry contract deployment`, - DharmaEscapeHatchRegistryDeployer, + tester.DharmaEscapeHatchRegistryDeployer, '', 'deploy' ) @@ -8762,13 +8408,13 @@ async function test(testingContext) { await tester.runTest( `DharmaAccountRecoveryManagerV2 owner can start ownership transfer to multisig`, - DharmaAccountRecoveryManagerV2, + tester.DharmaAccountRecoveryManagerV2, 'transferOwnership', 'send', [DharmaAccountRecoveryMultisig.options.address] ) - rawData = DharmaAccountRecoveryManagerV2.methods.acceptOwnership().encodeABI() + rawData = tester.DharmaAccountRecoveryManagerV2.methods.acceptOwnership().encodeABI() await tester.runTest( `DharmaAccountRecoveryMultisig can get a hash`, DharmaAccountRecoveryMultisig, @@ -8797,7 +8443,7 @@ async function test(testingContext) { await tester.runTest( `DharmaAccountRecoveryManagerV2 owner is now set to multisig`, - DharmaAccountRecoveryManagerV2, + tester.DharmaAccountRecoveryManagerV2, 'owner', 'call', [], @@ -8810,7 +8456,7 @@ async function test(testingContext) { // TODO: test account recovery using the multisig? // transfer ownership back - rawData = DharmaAccountRecoveryManagerV2.methods.transferOwnership(tester.address).encodeABI() + rawData = tester.DharmaAccountRecoveryManagerV2.methods.transferOwnership(tester.address).encodeABI() await tester.runTest( `DharmaAccountRecoveryMultisig can get a hash`, DharmaAccountRecoveryMultisig, @@ -8838,13 +8484,13 @@ async function test(testingContext) { await tester.runTest( `DharmaAccountRecoveryManagerV2 EOA can accept ownership transfer from multisig`, - DharmaAccountRecoveryManagerV2, + tester.DharmaAccountRecoveryManagerV2, 'acceptOwnership' ) await tester.runTest( `DharmaAccountRecoveryManagerV2 owner is now set to EOA`, - DharmaAccountRecoveryManagerV2, + tester.DharmaAccountRecoveryManagerV2, 'owner', 'call', [], @@ -8856,13 +8502,13 @@ async function test(testingContext) { await tester.runTest( `DharmaKeyRegistryV2 owner can start ownership transfer to multisig`, - DharmaKeyRegistryV2, + tester.DharmaKeyRegistryV2, 'transferOwnership', 'send', [DharmaKeyRegistryMultisig.options.address] ) - rawData = DharmaKeyRegistryV2.methods.acceptOwnership().encodeABI() + rawData = tester.DharmaKeyRegistryV2.methods.acceptOwnership().encodeABI() await tester.runTest( `DharmaKeyRegistryMultisig can get a hash`, DharmaKeyRegistryMultisig, @@ -8891,7 +8537,7 @@ async function test(testingContext) { await tester.runTest( `DharmaKeyRegistryV2 owner is now set to multisig`, - DharmaKeyRegistryV2, + tester.DharmaKeyRegistryV2, 'owner', 'call', [], @@ -8904,7 +8550,7 @@ async function test(testingContext) { // TODO: test setting a new key using the multisig? // transfer ownership back - rawData = DharmaKeyRegistryV2.methods.transferOwnership(tester.address).encodeABI() + rawData = tester.DharmaKeyRegistryV2.methods.transferOwnership(tester.address).encodeABI() await tester.runTest( `DharmaKeyRegistryMultisig can get a hash`, DharmaKeyRegistryMultisig, @@ -8932,13 +8578,13 @@ async function test(testingContext) { await tester.runTest( `DharmaKeyRegistryV2 EOA can accept ownership transfer from multisig`, - DharmaKeyRegistryV2, + tester.DharmaKeyRegistryV2, 'acceptOwnership' ) await tester.runTest( `DharmaKeyRegistryV2 owner is now set to EOA`, - DharmaKeyRegistryV2, + tester.DharmaKeyRegistryV2, 'owner', 'call', [], @@ -8950,7 +8596,7 @@ async function test(testingContext) { await tester.runTest( `DharmaUpgradeBeaconControllerManager owner is initially set to an EOA`, - DharmaUpgradeBeaconControllerManager, + tester.DharmaUpgradeBeaconControllerManager, 'owner', 'call', [], @@ -8962,13 +8608,13 @@ async function test(testingContext) { await tester.runTest( `DharmaUpgradeBeaconControllerManager owner can start ownership transfer to multisig`, - DharmaUpgradeBeaconControllerManager, + tester.DharmaUpgradeBeaconControllerManager, 'transferOwnership', 'send', [DharmaUpgradeMultisig.options.address] ) - rawData = DharmaUpgradeBeaconControllerManager.methods.acceptOwnership().encodeABI() + rawData = tester.DharmaUpgradeBeaconControllerManager.methods.acceptOwnership().encodeABI() await tester.runTest( `DharmaUpgradeMultisig can get a hash`, DharmaUpgradeMultisig, @@ -8997,7 +8643,7 @@ async function test(testingContext) { await tester.runTest( `DharmaUpgradeBeaconControllerManager owner is now set to multisig`, - DharmaUpgradeBeaconControllerManager, + tester.DharmaUpgradeBeaconControllerManager, 'owner', 'call', [], @@ -9010,7 +8656,7 @@ async function test(testingContext) { // TODO: test an upgrade, rollback, etc with the multisig? // transfer ownership back - rawData = DharmaUpgradeBeaconControllerManager.methods.transferOwnership(tester.address).encodeABI() + rawData = tester.DharmaUpgradeBeaconControllerManager.methods.transferOwnership(tester.address).encodeABI() await tester.runTest( `DharmaUpgradeMultisig can get a hash`, DharmaUpgradeMultisig, @@ -9038,13 +8684,13 @@ async function test(testingContext) { await tester.runTest( `DharmaUpgradeBeaconControllerManager EOA can accept ownership transfer from multisig`, - DharmaUpgradeBeaconControllerManager, + tester.DharmaUpgradeBeaconControllerManager, 'acceptOwnership' ) await tester.runTest( `DharmaUpgradeBeaconControllerManager owner is now set to EOA`, - DharmaUpgradeBeaconControllerManager, + tester.DharmaUpgradeBeaconControllerManager, 'owner', 'call', [], @@ -9057,9 +8703,9 @@ async function test(testingContext) { await testUpgradeBeaconControllerManagerPartTwo( tester, DharmaUpgradeBeaconControllerManagerCoverage, - DharmaUpgradeBeaconController, - DharmaKeyRingUpgradeBeaconController, - DharmaUpgradeBeacon.options.address, + tester.DharmaUpgradeBeaconController, + tester.DharmaKeyRingUpgradeBeaconController, + tester.DharmaUpgradeBeacon.options.address, AdharmaSmartWalletImplementation.options.address, DharmaSmartWalletImplementationV7.options.address, DharmaKeyRingImplementationV1.options.address diff --git a/scripts/test/testCoverage.js b/scripts/test/testCoverage.js index 597f059..c622a8d 100644 --- a/scripts/test/testCoverage.js +++ b/scripts/test/testCoverage.js @@ -5,10 +5,13 @@ var test = require('./test.js') // run tests async function runTests() { - await deployMockExternal.test('coverage') - await deploy.test('coverage') - await test.test('coverage') + const context = process.env.TESTING_CONTEXT; + + await deployMockExternal.test(context); + await deploy.test(context); + await test.test(context); + process.exit(0) } -runTests() +runTests() \ No newline at end of file diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index 774a11e..4b63d6b 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -4,13 +4,46 @@ const assert = require("assert"); const util = require('ethereumjs-util'); const MockCodeCheckArtifact = require('../../build/contracts/MockCodeCheck.json') + +const AdharmaSmartWalletImplementationArtifact = require('../../build/contracts/AdharmaSmartWalletImplementation.json') +const AdharmaKeyRingImplementationArtifact = require('../../build/contracts/AdharmaKeyRingImplementation.json') + +const DharmaUpgradeBeaconControllerManagerArtifact = require('../../build/contracts/DharmaUpgradeBeaconControllerManager.json') +const DharmaUpgradeBeaconControllerArtifact = require('../../build/contracts/DharmaUpgradeBeaconController.json') +const DharmaUpgradeBeaconArtifact = require('../../build/contracts/DharmaUpgradeBeacon.json') +const DharmaKeyRingUpgradeBeaconArtifact = require('../../build/contracts/DharmaKeyRingUpgradeBeacon.json') +const DharmaUpgradeBeaconEnvoyArtifact = require('../../build/contracts/DharmaUpgradeBeaconEnvoy.json') + +const DharmaAccountRecoveryManagerV2Artifact = require('../../build/contracts/DharmaAccountRecoveryManagerV2.json') +const DharmaKeyRegistryV2Artifact = require('../../build/contracts/DharmaKeyRegistryV2.json') +const DharmaSmartWalletFactoryV1Artifact = require('../../build/contracts/DharmaSmartWalletFactoryV1.json') +const DharmaSmartWalletFactoryV2Artifact = require('../../build/contracts/DharmaSmartWalletFactoryV2.json') + +const DharmaSmartWalletImplementationV6Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV6.json') +const DharmaSmartWalletImplementationV7Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV7.json') + +const DharmaKeyRingImplementationV1Artifact = require('../../build/contracts/DharmaKeyRingImplementationV1.json') +const DharmaKeyRingFactoryV1Artifact = require('../../build/contracts/DharmaKeyRingFactoryV1.json') +const DharmaKeyRingFactoryV2Artifact = require('../../build/contracts/DharmaKeyRingFactoryV2.json') +const DharmaKeyRingFactoryV3Artifact = require('../../build/contracts/DharmaKeyRingFactoryV3.json') + +const UpgradeBeaconProxyV1Artifact = require('../../build/contracts/UpgradeBeaconProxyV1.json') +const KeyRingUpgradeBeaconProxyV1Artifact = require('../../build/contracts/KeyRingUpgradeBeaconProxyV1.json') + +const DharmaUpgradeMultisigArtifact = require('../../build/contracts/DharmaUpgradeMultisig.json') +const DharmaAccountRecoveryMultisigArtifact = require('../../build/contracts/DharmaAccountRecoveryMultisig.json') +const DharmaAccountRecoveryOperatorMultisigArtifact = require('../../build/contracts/DharmaAccountRecoveryOperatorMultisig.json') +const DharmaKeyRegistryMultisigArtifact = require('../../build/contracts/DharmaKeyRegistryMultisig.json') + +const DharmaEscapeHatchRegistryArtifact = require('../../build/contracts/DharmaEscapeHatchRegistry.json') + const UpgradeBeaconImplementationCheckArtifact = require('../../build/contracts/UpgradeBeaconImplementationCheck.json') +const BadBeaconArtifact = require('../../build/contracts/BadBeacon.json') +const BadBeaconTwoArtifact = require('../../build/contracts/BadBeaconTwo.json') +const TimelockEdgecaseTesterArtifact = require('../../build/contracts/TimelockEdgecaseTester.json') -const SCALING_FACTOR = web3.utils.toBN("1000000000000000000"); -const ZERO = web3.utils.toBN("0"); -const ONE = web3.utils.toBN("1"); -const NINE = web3.utils.toBN("9"); -const TEN = web3.utils.toBN("10"); +const MockDharmaKeyRingFactoryArtifact = require('../../build/contracts/MockDharmaKeyRingFactory.json') +const IERC20Artifact = require('../../build/contracts/IERC20.json') class Tester { constructor(testingContext) { @@ -108,6 +141,8 @@ class Tester { ) } ) + + await this.setupDeployedContracst(); } async setupNewDefaultAddress(newPrivateKey) { @@ -849,6 +884,328 @@ class Tester { } ); } + + async setupDeployedContracst() { + this.DharmaUpgradeBeaconController = new web3.eth.Contract( + DharmaUpgradeBeaconControllerArtifact.abi, + constants.UPGRADE_BEACON_CONTROLLER_ADDRESS + ) + this.DharmaUpgradeBeacon = new web3.eth.Contract( + DharmaUpgradeBeaconArtifact.abi, + constants.UPGRADE_BEACON_ADDRESS + ) + this.DharmaKeyRingUpgradeBeaconController = new web3.eth.Contract( + DharmaUpgradeBeaconControllerArtifact.abi, + constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS + ) + + this.DharmaKeyRingUpgradeBeacon = new web3.eth.Contract( + DharmaKeyRingUpgradeBeaconArtifact.abi, + constants.KEY_RING_UPGRADE_BEACON_ADDRESS + ) + + this.DharmaAccountRecoveryManagerV2 = new web3.eth.Contract( + DharmaAccountRecoveryManagerV2Artifact.abi, + constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS + ) + + /* + const DharmaKeyRegistryV1 = new web3.eth.Contract( + DharmaKeyRegistryV1Artifact.abi, + constants.KEY_REGISTRY_ADDRESS + ) + */ + + this.DharmaKeyRegistryV2 = new web3.eth.Contract( + DharmaKeyRegistryV2Artifact.abi, + constants.KEY_REGISTRY_V2_ADDRESS + ) + + this.DharmaUpgradeBeaconControllerManager = new web3.eth.Contract( + DharmaUpgradeBeaconControllerManagerArtifact.abi, + constants.UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS + ) + + this.DharmaSmartWalletFactoryV1OnChain = new web3.eth.Contract( + DharmaSmartWalletFactoryV1Artifact.abi, + constants.FACTORY_ADDRESS + ) + + this.Comptroller = new web3.eth.Contract( + constants.COMPTROLLER_ABI, + constants.COMPTROLLER_MAINNET_ADDRESS + ) + + this.CSAI_BORROW = new web3.eth.Contract( + [{ + "constant": false, + "inputs": [{"name": "borrowAmount", "type": "uint256"}], + "name": "borrow", + "outputs": [{"name": "", "type": "uint256"}], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }], + constants.CSAI_MAINNET_ADDRESS + ) + + this.FIAT_TOKEN = new web3.eth.Contract( + [ + { + "constant": true, "inputs": [], "name": "blacklister", + "outputs": [{"name": "", "type": "address"}], "payable": false, + "stateMutability": "view", "type": "function" + }, { + "constant": false, "inputs": [{"name": "_account", "type": "address"}], + "name": "unBlacklist", "outputs": [], "payable": false, + "stateMutability": "nonpayable", "type": "function" + }, { + "constant": false, "inputs": [{"name": "_account", "type": "address"}], + "name": "blacklist", "outputs": [], "payable": false, + "stateMutability": "nonpayable", "type": "function" + }, { + "constant": true, "inputs": [{"name": "_account", "type": "address"}], + "name": "isBlacklisted", "outputs": [{"name": "", "type": "bool"}], + "payable": false, "stateMutability": "view", "type": "function" + }, { + "constant": false, "inputs": [], + "name": "pause", "outputs": [], "payable": false, + "stateMutability": "nonpayable", "type": "function" + }, { + "constant": false, "inputs": [], + "name": "unpause", "outputs": [], "payable": false, + "stateMutability": "nonpayable", "type": "function" + }, { + "constant": true, "inputs": [], "name": "pauser", + "outputs": [{"name": "", "type": "address"}], "payable": false, + "stateMutability": "view", "type": "function" + } + ], + constants.USDC_MAINNET_ADDRESS + ) + + this.SAI = new web3.eth.Contract( + IERC20Artifact.abi, constants.SAI_MAINNET_ADDRESS + ) + + this.DAI = new web3.eth.Contract( + IERC20Artifact.abi, constants.DAI_MAINNET_ADDRESS + ) + + this.USDC = new web3.eth.Contract( + IERC20Artifact.abi, constants.USDC_MAINNET_ADDRESS + ) + + this.CSAI = new web3.eth.Contract( + IERC20Artifact.abi, constants.CSAI_MAINNET_ADDRESS + ) + + this.CDAI = new web3.eth.Contract( + IERC20Artifact.abi, constants.CDAI_MAINNET_ADDRESS + ) + + this.CUSDC = new web3.eth.Contract( + IERC20Artifact.abi, constants.CUSDC_MAINNET_ADDRESS + ) + + this.BadBeaconDeployer = new web3.eth.Contract(BadBeaconArtifact.abi) + this.BadBeaconDeployer.options.data = BadBeaconArtifact.bytecode + + this.BadBeaconTwoDeployer = new web3.eth.Contract(BadBeaconTwoArtifact.abi) + this.BadBeaconTwoDeployer.options.data = BadBeaconTwoArtifact.bytecode + + + this.AdharmaSmartWalletImplementationDeployer = new web3.eth.Contract( + AdharmaSmartWalletImplementationArtifact.abi + ) + this.AdharmaSmartWalletImplementationDeployer.options.data = ( + AdharmaSmartWalletImplementationArtifact.bytecode + ) + + this.DharmaSmartWalletImplementationV6Deployer = new web3.eth.Contract( + DharmaSmartWalletImplementationV6Artifact.abi + ) + this.DharmaSmartWalletImplementationV6Deployer.options.data = ( + DharmaSmartWalletImplementationV6Artifact.bytecode + ) + + this.DharmaSmartWalletImplementationV7Deployer = new web3.eth.Contract( + DharmaSmartWalletImplementationV7Artifact.abi + ) + this.DharmaSmartWalletImplementationV7Deployer.options.data = ( + DharmaSmartWalletImplementationV7Artifact.bytecode + ) + + this.AdharmaKeyRingImplementationDeployer = new web3.eth.Contract( + AdharmaKeyRingImplementationArtifact.abi + ) + this.AdharmaKeyRingImplementationDeployer.options.data = ( + AdharmaKeyRingImplementationArtifact.bytecode + ) + + this.DharmaKeyRingImplementationV1Deployer = new web3.eth.Contract( + DharmaKeyRingImplementationV1Artifact.abi + ) + this.DharmaKeyRingImplementationV1Deployer.options.data = ( + DharmaKeyRingImplementationV1Artifact.bytecode + ) + + this.UpgradeBeaconImplementationCheckDeployer = new web3.eth.Contract( + UpgradeBeaconImplementationCheckArtifact.abi + ) + this.UpgradeBeaconImplementationCheckDeployer.options.data = ( + UpgradeBeaconImplementationCheckArtifact.bytecode + ) + + this.TimelockEdgecaseTesterDeployer = new web3.eth.Contract( + TimelockEdgecaseTesterArtifact.abi + ) + this.TimelockEdgecaseTesterDeployer.options.data = ( + TimelockEdgecaseTesterArtifact.bytecode + ) + + this.DharmaUpgradeBeaconControllerDeployer = new web3.eth.Contract( + DharmaUpgradeBeaconControllerArtifact.abi + ) + this.DharmaUpgradeBeaconControllerDeployer.options.data = ( + DharmaUpgradeBeaconControllerArtifact.bytecode + ) + + this.DharmaUpgradeBeaconDeployer = new web3.eth.Contract( + DharmaUpgradeBeaconArtifact.abi + ) + this.DharmaUpgradeBeaconDeployer.options.data = ( + DharmaUpgradeBeaconArtifact.bytecode + ) + + this.DharmaKeyRingUpgradeBeaconDeployer = new web3.eth.Contract( + DharmaKeyRingUpgradeBeaconArtifact.abi + ) + this.DharmaKeyRingUpgradeBeaconDeployer.options.data = ( + DharmaKeyRingUpgradeBeaconArtifact.bytecode + ) + + this.DharmaUpgradeBeaconEnvoyDeployer = new web3.eth.Contract( + DharmaUpgradeBeaconEnvoyArtifact.abi + ) + this.DharmaUpgradeBeaconEnvoyDeployer.options.data = ( + DharmaUpgradeBeaconEnvoyArtifact.bytecode + ) + + this.DharmaUpgradeBeaconControllerManagerDeployer = new web3.eth.Contract( + DharmaUpgradeBeaconControllerManagerArtifact.abi + ) + this.DharmaUpgradeBeaconControllerManagerDeployer.options.data = ( + DharmaUpgradeBeaconControllerManagerArtifact.bytecode + ) + + this.UpgradeBeaconProxyV1Deployer = new web3.eth.Contract( + UpgradeBeaconProxyV1Artifact.abi + ) + this.UpgradeBeaconProxyV1Deployer.options.data = ( + UpgradeBeaconProxyV1Artifact.bytecode + ) + + this.KeyRingUpgradeBeaconProxyV1Deployer = new web3.eth.Contract( + KeyRingUpgradeBeaconProxyV1Artifact.abi + ) + this.KeyRingUpgradeBeaconProxyV1Deployer.options.data = ( + KeyRingUpgradeBeaconProxyV1Artifact.bytecode + ) + + this.DharmaKeyRegistryV2Deployer = new web3.eth.Contract( + DharmaKeyRegistryV2Artifact.abi + ) + this.DharmaKeyRegistryV2Deployer.options.data = ( + DharmaKeyRegistryV2Artifact.bytecode + ) + + this.DharmaSmartWalletFactoryV1Deployer = new web3.eth.Contract( + DharmaSmartWalletFactoryV1Artifact.abi + ) + this.DharmaSmartWalletFactoryV1Deployer.options.data = ( + DharmaSmartWalletFactoryV1Artifact.bytecode + ) + + this.DharmaSmartWalletFactoryV2Deployer = new web3.eth.Contract( + DharmaSmartWalletFactoryV2Artifact.abi + ) + this.DharmaSmartWalletFactoryV2Deployer.options.data = ( + DharmaSmartWalletFactoryV2Artifact.bytecode + ) + + this.DharmaKeyRingFactoryV1Deployer = new web3.eth.Contract( + DharmaKeyRingFactoryV1Artifact.abi + ) + this.DharmaKeyRingFactoryV1Deployer.options.data = ( + DharmaKeyRingFactoryV1Artifact.bytecode + ) + + this.DharmaKeyRingFactoryV2Deployer = new web3.eth.Contract( + DharmaKeyRingFactoryV2Artifact.abi + ) + this.DharmaKeyRingFactoryV2Deployer.options.data = ( + DharmaKeyRingFactoryV2Artifact.bytecode + ) + + this.DharmaKeyRingFactoryV3Deployer = new web3.eth.Contract( + DharmaKeyRingFactoryV3Artifact.abi + ) + this.DharmaKeyRingFactoryV3Deployer.options.data = ( + DharmaKeyRingFactoryV3Artifact.bytecode + ) + + this.MockDharmaKeyRingFactoryDeployer = new web3.eth.Contract( + MockDharmaKeyRingFactoryArtifact.abi + ) + this.MockDharmaKeyRingFactoryDeployer.options.data = ( + MockDharmaKeyRingFactoryArtifact.bytecode + ) + + this.DharmaAccountRecoveryManagerV2Deployer = new web3.eth.Contract( + DharmaAccountRecoveryManagerV2Artifact.abi + ) + this.DharmaAccountRecoveryManagerV2Deployer.options.data = ( + DharmaAccountRecoveryManagerV2Artifact.bytecode + ) + + this.DharmaUpgradeMultisigDeployer = new web3.eth.Contract( + DharmaUpgradeMultisigArtifact.abi + ) + this.DharmaUpgradeMultisigDeployer.options.data = ( + DharmaUpgradeMultisigArtifact.bytecode + ) + + this.DharmaAccountRecoveryMultisigDeployer = new web3.eth.Contract( + DharmaAccountRecoveryMultisigArtifact.abi + ) + this.DharmaAccountRecoveryMultisigDeployer.options.data = ( + DharmaAccountRecoveryMultisigArtifact.bytecode + ) + + this.DharmaAccountRecoveryOperatorMultisigDeployer = new web3.eth.Contract( + DharmaAccountRecoveryOperatorMultisigArtifact.abi + ) + this.DharmaAccountRecoveryOperatorMultisigDeployer.options.data = ( + DharmaAccountRecoveryOperatorMultisigArtifact.bytecode + ) + + this.DharmaKeyRegistryMultisigDeployer = new web3.eth.Contract( + DharmaKeyRegistryMultisigArtifact.abi + ) + this.DharmaKeyRegistryMultisigDeployer.options.data = ( + DharmaKeyRegistryMultisigArtifact.bytecode + ) + + this.DharmaEscapeHatchRegistryDeployer = new web3.eth.Contract( + DharmaEscapeHatchRegistryArtifact.abi + ) + this.DharmaEscapeHatchRegistryDeployer.options.data = ( + DharmaEscapeHatchRegistryArtifact.bytecode + ) + + + } } function swapMetadataHash(bytecode, newMetadataHashes) { diff --git a/scripts/test/web3.js b/scripts/test/web3.js index d91debb..0522704 100644 --- a/scripts/test/web3.js +++ b/scripts/test/web3.js @@ -1,9 +1,11 @@ +const context = process.env.TESTING_CONTEXT; + const connectionConfig = require('../../truffle-config.js'); -const connection = connectionConfig.networks['coverage']; +const connection = connectionConfig.networks[context]; const web3 = connection.provider; module.exports = { web3, -}; +}; \ No newline at end of file From 486d4d4700ef4b726a10e24fecd7bd851d2a43d5 Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Fri, 7 Feb 2020 18:55:54 -0800 Subject: [PATCH 28/47] add prettier --- .prettierrc | 5 + package.json | 79 +- .../testAccountRecoveryManager.js | 1744 ++++++++--------- yarn.lock | 745 ++++++- 4 files changed, 1657 insertions(+), 916 deletions(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..7007c8a --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "tabWidth": 4, + "semi": true, + "singleQuote": false +} diff --git a/package.json b/package.json index 7ab28d7..d69fa78 100644 --- a/package.json +++ b/package.json @@ -1,31 +1,50 @@ { - "name": "dharma-smart-wallet", - "version": "1.4.0", - "description": "An upgradeable, meta-transaction-enabled smart wallet for earning interest on stablecoins while retaining custody of funds, with an added security backstop provided by Dharma Labs.", - "author": "Dharma Labs", - "license": "MIT", - "dependencies": { - "@openzeppelin/contracts": "2.3.0", - "ethereumjs-util": "6.1.0", - "ethlint": "1.2.5", - "ganache-cli": "6.7.0", - "ganache-cli-coverage": "https://github.com/frangio/ganache-cli/releases/download/v6.4.1-coverage/ganache-cli-coverage-6.4.1.tgz", - "js-sha256": "0.9.0", - "solhint": "2.3.0", - "solidity-coverage": "0.6.7", - "truffle": "5.1.4", - "web3": "1.2.1" - }, - "scripts": { - "all": "export TESTING_CONTEXT=development ; ./node_modules/.bin/ganache-cli --gasLimit 8000000 -i 1234 -e 10000 -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' 2>&1 > ganache-output.log & echo 'local chain started.' && ./node_modules/.bin/truffle compile && node scripts/test/ci.js && ./node_modules/.bin/solhint 'contracts/**/*.sol' && ./node_modules/.bin/solium -d .; kill -9 \"$(ps -ax | grep -m1 '[n]ode ./node_modules/.bin/ganache-cli' | awk '{print $1;}')\" && echo 'local chain stopped.'", - "build": "./node_modules/.bin/truffle compile", - "ci": "./node_modules/.bin/ganache-cli --gasLimit 8000000 -i 1234 -q & echo 'local chain started.' && ./node_modules/.bin/truffle compile && node scripts/test/ci.js && ./node_modules/.bin/solhint 'contracts/**/*.sol' && ./node_modules/.bin/solium -d .", - "coverage": "export TESTING_CONTEXT=coverage ; ./node_modules/.bin/ganache-cli-coverage --emitFreeLogs true --allowUnlimitedContractSize true --gasLimit 0xfffffffffff --port 8555 -e 10000 -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' 2>&1 > ganache-coverage-output.log & echo 'coverage chain started.' && node --max-old-space-size=8192 ./node_modules/.bin/solidity-coverage; kill -9 \"$(ps -ax | grep -m1 '[n]ode ./node_modules/.bin/ganache-cli' | awk '{print $1;}')\" && echo 'coverage chain stopped.'", - "forkCoverage": "./node_modules/.bin/ganache-cli-coverage --emitFreeLogs true --allowUnlimitedContractSize true --gasLimit 0xfffffffffff --port 8555 --fork https://mainnet.infura.io/v3/e7faf3dd07254d76859ec8c7c3259d9d@8396520 -e 10000 -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' -u '0x5dB0115f3B72d19cEa34dD697cf412Ff86dc7E1b' -u '0xf0d160DEC1749aFaF5A831668093B1431f7C8527' 2>&1 > ganache-coverage-output.log & echo 'fork coverage chain started on port 8555.' && node --max-old-space-size=8192 ./node_modules/.bin/solidity-coverage; kill -9 \"$(ps -ax | grep -m1 '[n]ode ./node_modules/.bin/ganache-cli' | awk '{print $1;}')\" && echo 'coverage chain stopped.'", - "lint": "./node_modules/.bin/solhint 'contracts/**/*.sol' && ./node_modules/.bin/solium -d .", - "start": "./node_modules/.bin/ganache-cli --gasLimit 8000000 -i 1234 -e 10000 -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' 2>&1 > ganache-output.log & echo 'local chain started.'", - "forkStart": "./node_modules/.bin/ganache-cli --port 8545 --gasLimit 8000000 --fork https://mainnet.infura.io/v3/e7faf3dd07254d76859ec8c7c3259d9d@8396520 -e 10000 -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' -u '0x5dB0115f3B72d19cEa34dD697cf412Ff86dc7E1b' -u '0xf0d160DEC1749aFaF5A831668093B1431f7C8527' 2>&1 > ganache-output.log & echo 'fork chain started on port 8545.'", - "stop": "kill -9 \"$(ps -ax | grep -m1 '[n]ode ./node_modules/.bin/ganache-cli' | awk '{print $1;}')\" && echo 'local chain stopped.'", - "test": "export TESTING_CONTEXT=development ; ./node_modules/.bin/truffle compile && node scripts/test/ci.js" - } -} \ No newline at end of file + "name": "dharma-smart-wallet", + "version": "1.4.0", + "description": "An upgradeable, meta-transaction-enabled smart wallet for earning interest on stablecoins while retaining custody of funds, with an added security backstop provided by Dharma Labs.", + "author": "Dharma Labs", + "license": "MIT", + "dependencies": { + "@openzeppelin/contracts": "2.3.0", + "ethereumjs-util": "6.1.0", + "ethlint": "1.2.5", + "ganache-cli": "6.7.0", + "ganache-cli-coverage": "https://github.com/frangio/ganache-cli/releases/download/v6.4.1-coverage/ganache-cli-coverage-6.4.1.tgz", + "js-sha256": "0.9.0", + "solhint": "2.3.0", + "solidity-coverage": "0.6.7", + "truffle": "5.1.4", + "web3": "1.2.1" + }, + "devDependencies": { + "husky": "^4.2.1", + "lint-staged": "^9.2.1", + "prettier": "1.16.4", + "pretty-quick": "^2.0.1" + }, + "scripts": { + "all": "export TESTING_CONTEXT=development ; ./node_modules/.bin/ganache-cli --gasLimit 8000000 -i 1234 -e 10000 -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' 2>&1 > ganache-output.log & echo 'local chain started.' && ./node_modules/.bin/truffle compile && node scripts/test/ci.js && ./node_modules/.bin/solhint 'contracts/**/*.sol' && ./node_modules/.bin/solium -d .; kill -9 \"$(ps -ax | grep -m1 '[n]ode ./node_modules/.bin/ganache-cli' | awk '{print $1;}')\" && echo 'local chain stopped.'", + "build": "./node_modules/.bin/truffle compile", + "ci": "./node_modules/.bin/ganache-cli --gasLimit 8000000 -i 1234 -q & echo 'local chain started.' && ./node_modules/.bin/truffle compile && node scripts/test/ci.js && ./node_modules/.bin/solhint 'contracts/**/*.sol' && ./node_modules/.bin/solium -d .", + "coverage": "export TESTING_CONTEXT=coverage ; ./node_modules/.bin/ganache-cli-coverage --emitFreeLogs true --allowUnlimitedContractSize true --gasLimit 0xfffffffffff --port 8555 -e 10000 -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' 2>&1 > ganache-coverage-output.log & echo 'coverage chain started.' && node --max-old-space-size=8192 ./node_modules/.bin/solidity-coverage; kill -9 \"$(ps -ax | grep -m1 '[n]ode ./node_modules/.bin/ganache-cli' | awk '{print $1;}')\" && echo 'coverage chain stopped.'", + "forkCoverage": "./node_modules/.bin/ganache-cli-coverage --emitFreeLogs true --allowUnlimitedContractSize true --gasLimit 0xfffffffffff --port 8555 --fork https://mainnet.infura.io/v3/e7faf3dd07254d76859ec8c7c3259d9d@8396520 -e 10000 -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' -u '0x5dB0115f3B72d19cEa34dD697cf412Ff86dc7E1b' -u '0xf0d160DEC1749aFaF5A831668093B1431f7C8527' 2>&1 > ganache-coverage-output.log & echo 'fork coverage chain started on port 8555.' && node --max-old-space-size=8192 ./node_modules/.bin/solidity-coverage; kill -9 \"$(ps -ax | grep -m1 '[n]ode ./node_modules/.bin/ganache-cli' | awk '{print $1;}')\" && echo 'coverage chain stopped.'", + "lint": "./node_modules/.bin/solhint 'contracts/**/*.sol' && ./node_modules/.bin/solium -d .", + "start": "./node_modules/.bin/ganache-cli --gasLimit 8000000 -i 1234 -e 10000 -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' 2>&1 > ganache-output.log & echo 'local chain started.'", + "forkStart": "./node_modules/.bin/ganache-cli --port 8545 --gasLimit 8000000 --fork https://mainnet.infura.io/v3/e7faf3dd07254d76859ec8c7c3259d9d@8396520 -e 10000 -u 0xb5b06a16621616875A6C2637948bF98eA57c58fa -u 0x8134d518e0CeF5388136c0De43d7E12278701Ac5 -u 0xddb108893104de4e1c6d0e47c42237db4e617acc -u 0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9 -u 0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911 -u 0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6 -u '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' -u '0x76B03EB651153a81fA1f212f2f59329B4180A46F' -u '0x035e742A7E62253C606b9028eeB65178B44F1e7E' -u '0x5dB0115f3B72d19cEa34dD697cf412Ff86dc7E1b' -u '0xf0d160DEC1749aFaF5A831668093B1431f7C8527' 2>&1 > ganache-output.log & echo 'fork chain started on port 8545.'", + "stop": "kill -9 \"$(ps -ax | grep -m1 '[n]ode ./node_modules/.bin/ganache-cli' | awk '{print $1;}')\" && echo 'local chain stopped.'", + "test": "export TESTING_CONTEXT=development ; ./node_modules/.bin/truffle compile && node scripts/test/ci.js", + "prettier": "prettier --write" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.{js,css,json,md}": [ + "prettier --debug-check", + "prettier --write", + "git add" + ] + } +} diff --git a/scripts/test/contracts/account-recovery/testAccountRecoveryManager.js b/scripts/test/contracts/account-recovery/testAccountRecoveryManager.js index cdf6aa9..b46ec7f 100644 --- a/scripts/test/contracts/account-recovery/testAccountRecoveryManager.js +++ b/scripts/test/contracts/account-recovery/testAccountRecoveryManager.js @@ -1,885 +1,873 @@ const constants = require("../../constants"); const assert = require("assert"); -async function testAccountRecoveryManager(tester, contract, smartWalletAddress) { - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot transfer ownership from a non-owner`, - contract, - 'transferOwnership', - 'send', - [tester.addressTwo], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot initiate recovery with null smart wallet`, - contract, - 'initiateAccountRecovery', - 'send', - [constants.NULL_ADDRESS, tester.addressTwo, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot initiate recovery with null new key`, - contract, - 'initiateAccountRecovery', - 'send', - [tester.address, constants.NULL_ADDRESS, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can initiate recovery timelock`, - contract, - 'initiateAccountRecovery', - 'send', - [constants.UPGRADE_BEACON_ADDRESS, tester.addressTwo, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can initiate another recovery timelock`, - contract, - 'initiateAccountRecovery', - 'send', - [smartWalletAddress, tester.addressTwo, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can initiate a third recovery timelock`, - contract, - 'initiateAccountRecovery', - 'send', - [tester.address, tester.addressTwo, 0] - ) - - await tester.runTest( - 'smart wallet account recovery cannot be cancelled with no smart wallet', - contract, - 'cancelAccountRecovery', - 'send', - [ - constants.NULL_ADDRESS, - tester.addressTwo - ], - false - ) - - await tester.runTest( - 'smart wallet account recovery cannot be cancelled with no user signing key', - contract, - 'cancelAccountRecovery', - 'send', - [ - tester.address, - constants.NULL_ADDRESS - ], - false - ) - - await tester.runTest( - 'smart wallet account recovery can be cancelled', - contract, - 'cancelAccountRecovery', - 'send', - [ - tester.address, - tester.addressTwo - ], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - 'smart wallet account recovery cannot be cancelled if it is already cancelled', - contract, - 'cancelAccountRecovery', - 'send', - [ - tester.address, - tester.addressTwo - ], - false - ) - - await tester.runTest( - 'smart wallet account recovery cannot be cancelled if no timelock exists', - contract, - 'cancelAccountRecovery', - 'send', - [ - tester.addressTwo, - tester.addressTwo - ], - false - ) - - - await tester.runTest( - 'smart wallet account recovery can be reinitiated', - contract, - 'initiateAccountRecovery', - 'send', - [ - tester.address, - tester.addressTwo, - 1 // extraTime in seconds - add one to ensure that timelock is extended - ], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot initiate recovery disablement with null smart wallet`, - contract, - 'initiateAccountRecoveryDisablement', - 'send', - [constants.NULL_ADDRESS, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can initiate recovery disablement timelock`, - contract, - 'initiateAccountRecoveryDisablement', - 'send', - [tester.address, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call recover with null new key`, - contract, - 'recover', - 'send', - [constants.NULL_ADDRESS, tester.addressTwo], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call recover with null new key`, - contract, - 'recover', - 'send', - [tester.address, constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call recover prior to timelock completion`, - contract, - 'recover', - 'send', - [constants.UPGRADE_BEACON_ADDRESS, tester.addressTwo], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery prior to timelock completion`, - contract, - 'disableAccountRecovery', - 'send', - [tester.address], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check if account recovery is disabled`, - contract, - 'accountRecoveryDisabled', - 'call', - [tester.address], - true, - value => { - assert.ok(!value) - } - ) - - // advance time by 3 days - await tester.advanceTime((60 * 60 * 24 * 3) + 5) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call recover after timelock completion`, - contract, - 'recover', - 'send', - [constants.UPGRADE_BEACON_ADDRESS, tester.addressTwo] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot recover an unowned smart wallet`, - contract, - 'recover', - 'send', - [smartWalletAddress, tester.addressTwo], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot recover an EOA`, - contract, - 'recover', - 'send', - [tester.address, tester.addressTwo], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery with null smart wallet`, - contract, - 'disableAccountRecovery', - 'send', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call disableAccountRecovery after timelock completion`, - contract, - 'disableAccountRecovery', - 'send', - [tester.address] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check if account recovery is disabled`, - contract, - 'accountRecoveryDisabled', - 'call', - [tester.address], - true, - value => { - assert.ok(value) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot recover an account that has disabled recovery`, - contract, - 'recover', - 'send', - [tester.address, tester.addressTwo], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval with no selector`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0x00000000', 0, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval to modify interval over 8 weeks`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 5443200, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 10000, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock on another function`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0xaaaaaaaa', 10000, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval with no selector`, - contract, - 'modifyTimelockInterval', - 'send', - ['0x00000000', 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval before timelock completion`, - contract, - 'modifyTimelockInterval', - 'send', - ['0xe950c085', 1000], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration with no selector`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0x00000000', 0, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to with expiration over one month`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0xe950c085', 5443200, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to modify expiration under one minute`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 30, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to modify expiration under one hour`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 3000, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 30000, 0], - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock on another function`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0xaaaaaaaa', 300000, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration with no selector`, - contract, - 'modifyTimelockExpiration', - 'send', - ['0x00000000', 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration before timelock completion`, - contract, - 'modifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 300], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can initiate recovery disablement timelock`, - contract, - 'initiateAccountRecoveryDisablement', - 'send', - [tester.addressTwo, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot cancel disablement with null address`, - contract, - 'cancelAccountRecoveryDisablement', - 'send', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can cancel recovery disablement timelock`, - contract, - 'cancelAccountRecoveryDisablement', - 'send', - [tester.addressTwo] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can re-initiate recovery disablement timelock`, - contract, - 'initiateAccountRecoveryDisablement', - 'send', - [tester.addressTwo, 1] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot shorten a timelock`, - contract, - 'initiateAccountRecoveryDisablement', - 'send', - [tester.addressTwo, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot initiate recovery with massive extraTime`, - contract, - 'initiateAccountRecovery', - 'send', - [tester.address, tester.addressTwo, constants.FULL_APPROVAL], - false - ) - - // advance time by 2 weeks - await tester.advanceTime((60 * 60 * 24 * 7 * 2) + 5) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery after timelock expiration`, - contract, - 'disableAccountRecovery', - 'send', - [tester.addressTwo], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot set a role to the null tester.address`, - contract, - 'setRole', - 'send', - [0, constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can set a role`, - contract, - 'setRole', - 'send', - [0, tester.address] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can set a role that is already set`, - contract, - 'setRole', - 'send', - [0, tester.address] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check if the caller has a role`, - contract, - 'isRole', - 'call', - [0], - true, - value => { - assert.ok(value) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check for an operator role`, - contract, - 'getOperator', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check for a recoverer role`, - contract, - 'getRecoverer', - 'call', - [], - true, - value => { - assert.strictEqual(value, constants.NULL_ADDRESS) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check for a canceller role`, - contract, - 'getCanceller', - 'call', - [], - true, - value => { - assert.strictEqual(value, constants.NULL_ADDRESS) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check for a disabler role`, - contract, - 'getDisabler', - 'call', - [], - true, - value => { - assert.strictEqual(value, constants.NULL_ADDRESS) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check for a pauser role`, - contract, - 'getPauser', - 'call', - [], - true, - value => { - assert.strictEqual(value, constants.NULL_ADDRESS) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can remove a role`, - contract, - 'removeRole', - 'send', - [0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check if the caller has a role`, - contract, - 'isRole', - 'call', - [0], - true, - value => { - assert.ok(!value) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check if a role is paused`, - contract, - 'isPaused', - 'call', - [0], - true, - value => { - assert.ok(!value) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot pause a role if not owner or pauser`, - contract, - 'pause', - 'send', - [0], - false, - receipt => {}, - tester.addressTwo - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can set a role`, - contract, - 'setRole', - 'send', - [4, tester.addressTwo] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot unpause an unpaused role`, - contract, - 'unpause', - 'send', - [0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can pause an unpaused role`, - contract, - 'pause', - 'send', - [0], - true, - receipt => {}, - tester.addressTwo - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot pause a paused role`, - contract, - 'pause', - 'send', - [0], - false, - receipt => {}, - tester.addressTwo - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can pause the pauser role`, - contract, - 'pause', - 'send', - [4] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 pauser cannot call a paused role`, - contract, - 'pause', - 'send', - [4], - false, - receipt => {}, - tester.addressTwo - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can check if a role is paused`, - contract, - 'isPaused', - 'call', - [0], - true, - value => { - assert.ok(value) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can unpause a paused role`, - contract, - 'unpause', - 'send', - [0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can get an empty timelock`, - contract, - 'getTimelock', - 'call', - ['0x01020304', '0x'], - true, - value => { - assert.ok(!value.exists) - assert.ok(!value.completed) - assert.ok(!value.expired) - assert.strictEqual(value.completionTime, '0') - assert.strictEqual(value.expirationTime, '0') - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can get an empty default timelock interval`, - contract, - 'getDefaultTimelockInterval', - 'call', - ['0x01020304'], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can get an empty default timelock expiration`, - contract, - 'getDefaultTimelockExpiration', - 'call', - ['0x01020304'], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval with no selector`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0x00000000', 0, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval to modify interval over 8 weeks`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 5443200, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot create timelock with excessive duration`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', constants.FULL_APPROVAL, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 10000, 5] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot shorten existing initiateModifyTimelockInterval timelock`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 10000, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to change a duration`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 10001, 5] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock on another function`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0xaaaaaaaa', 10000, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval with no selector`, - contract, - 'modifyTimelockInterval', - 'send', - ['0x00000000', 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval before timelock completion`, - contract, - 'modifyTimelockInterval', - 'send', - ['0xe950c085', 1000], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration with no selector`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0x00000000', 0, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to with expiration over one month`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0xe950c085', 5443200, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to modify expiration under one minute`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 30, 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 300000, 0], - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock on another function`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0xe950c085', 30, 0] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration with no selector`, - contract, - 'modifyTimelockExpiration', - 'send', - ['0x00000000', 0], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration before timelock completion`, - contract, - 'modifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 300], - false - ) - - // advance time by 2 weeks - await tester.advanceTime((60 * 60 * 24 * 7 * 2) + 5) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call modifyTimelockInterval`, - contract, - 'modifyTimelockInterval', - 'send', - ['0xaaaaaaaa', 10000] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 can call modifyTimelockExpiration`, - contract, - 'modifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 300000], - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration if expiration is too short`, - contract, - 'modifyTimelockExpiration', - 'send', - ['0xe950c085', 30], - false - ) +async function testAccountRecoveryManager( + tester, + contract, + smartWalletAddress +) { + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot transfer ownership from a non-owner`, + contract, + "transferOwnership", + "send", + [tester.addressTwo], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot initiate recovery with null smart wallet`, + contract, + "initiateAccountRecovery", + "send", + [constants.NULL_ADDRESS, tester.addressTwo, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot initiate recovery with null new key`, + contract, + "initiateAccountRecovery", + "send", + [tester.address, constants.NULL_ADDRESS, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can initiate recovery timelock`, + contract, + "initiateAccountRecovery", + "send", + [constants.UPGRADE_BEACON_ADDRESS, tester.addressTwo, 0] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can initiate another recovery timelock`, + contract, + "initiateAccountRecovery", + "send", + [smartWalletAddress, tester.addressTwo, 0] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can initiate a third recovery timelock`, + contract, + "initiateAccountRecovery", + "send", + [tester.address, tester.addressTwo, 0] + ); + + await tester.runTest( + "smart wallet account recovery cannot be cancelled with no smart wallet", + contract, + "cancelAccountRecovery", + "send", + [constants.NULL_ADDRESS, tester.addressTwo], + false + ); + + await tester.runTest( + "smart wallet account recovery cannot be cancelled with no user signing key", + contract, + "cancelAccountRecovery", + "send", + [tester.address, constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + "smart wallet account recovery can be cancelled", + contract, + "cancelAccountRecovery", + "send", + [tester.address, tester.addressTwo], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ); + + await tester.runTest( + "smart wallet account recovery cannot be cancelled if it is already cancelled", + contract, + "cancelAccountRecovery", + "send", + [tester.address, tester.addressTwo], + false + ); + + await tester.runTest( + "smart wallet account recovery cannot be cancelled if no timelock exists", + contract, + "cancelAccountRecovery", + "send", + [tester.addressTwo, tester.addressTwo], + false + ); + + await tester.runTest( + "smart wallet account recovery can be reinitiated", + contract, + "initiateAccountRecovery", + "send", + [ + tester.address, + tester.addressTwo, + 1 // extraTime in seconds - add one to ensure that timelock is extended + ], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot initiate recovery disablement with null smart wallet`, + contract, + "initiateAccountRecoveryDisablement", + "send", + [constants.NULL_ADDRESS, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can initiate recovery disablement timelock`, + contract, + "initiateAccountRecoveryDisablement", + "send", + [tester.address, 0] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call recover with null new key`, + contract, + "recover", + "send", + [constants.NULL_ADDRESS, tester.addressTwo], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call recover with null new key`, + contract, + "recover", + "send", + [tester.address, constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call recover prior to timelock completion`, + contract, + "recover", + "send", + [constants.UPGRADE_BEACON_ADDRESS, tester.addressTwo], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery prior to timelock completion`, + contract, + "disableAccountRecovery", + "send", + [tester.address], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check if account recovery is disabled`, + contract, + "accountRecoveryDisabled", + "call", + [tester.address], + true, + value => { + assert.ok(!value); + } + ); + + // advance time by 3 days + await tester.advanceTime(60 * 60 * 24 * 3 + 5); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call recover after timelock completion`, + contract, + "recover", + "send", + [constants.UPGRADE_BEACON_ADDRESS, tester.addressTwo] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot recover an unowned smart wallet`, + contract, + "recover", + "send", + [smartWalletAddress, tester.addressTwo], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot recover an EOA`, + contract, + "recover", + "send", + [tester.address, tester.addressTwo], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery with null smart wallet`, + contract, + "disableAccountRecovery", + "send", + [constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call disableAccountRecovery after timelock completion`, + contract, + "disableAccountRecovery", + "send", + [tester.address] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check if account recovery is disabled`, + contract, + "accountRecoveryDisabled", + "call", + [tester.address], + true, + value => { + assert.ok(value); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot recover an account that has disabled recovery`, + contract, + "recover", + "send", + [tester.address, tester.addressTwo], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval with no selector`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0x00000000", 0, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval to modify interval over 8 weeks`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0xe950c085", 5443200, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0xe950c085", 10000, 0] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock on another function`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0xaaaaaaaa", 10000, 0] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval with no selector`, + contract, + "modifyTimelockInterval", + "send", + ["0x00000000", 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval before timelock completion`, + contract, + "modifyTimelockInterval", + "send", + ["0xe950c085", 1000], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration with no selector`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0x00000000", 0, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to with expiration over one month`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0xe950c085", 5443200, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to modify expiration under one minute`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0xd7ce3c6f", 30, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to modify expiration under one hour`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0xd7ce3c6f", 3000, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0xd7ce3c6f", 30000, 0] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock on another function`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0xaaaaaaaa", 300000, 0] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration with no selector`, + contract, + "modifyTimelockExpiration", + "send", + ["0x00000000", 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration before timelock completion`, + contract, + "modifyTimelockExpiration", + "send", + ["0xd7ce3c6f", 300], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can initiate recovery disablement timelock`, + contract, + "initiateAccountRecoveryDisablement", + "send", + [tester.addressTwo, 0] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot cancel disablement with null address`, + contract, + "cancelAccountRecoveryDisablement", + "send", + [constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can cancel recovery disablement timelock`, + contract, + "cancelAccountRecoveryDisablement", + "send", + [tester.addressTwo] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can re-initiate recovery disablement timelock`, + contract, + "initiateAccountRecoveryDisablement", + "send", + [tester.addressTwo, 1] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot shorten a timelock`, + contract, + "initiateAccountRecoveryDisablement", + "send", + [tester.addressTwo, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot initiate recovery with massive extraTime`, + contract, + "initiateAccountRecovery", + "send", + [tester.address, tester.addressTwo, constants.FULL_APPROVAL], + false + ); + + // advance time by 2 weeks + await tester.advanceTime(60 * 60 * 24 * 7 * 2 + 5); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call disableAccountRecovery after timelock expiration`, + contract, + "disableAccountRecovery", + "send", + [tester.addressTwo], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot set a role to the null tester.address`, + contract, + "setRole", + "send", + [0, constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can set a role`, + contract, + "setRole", + "send", + [0, tester.address] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can set a role that is already set`, + contract, + "setRole", + "send", + [0, tester.address] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check if the caller has a role`, + contract, + "isRole", + "call", + [0], + true, + value => { + assert.ok(value); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check for an operator role`, + contract, + "getOperator", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.address); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check for a recoverer role`, + contract, + "getRecoverer", + "call", + [], + true, + value => { + assert.strictEqual(value, constants.NULL_ADDRESS); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check for a canceller role`, + contract, + "getCanceller", + "call", + [], + true, + value => { + assert.strictEqual(value, constants.NULL_ADDRESS); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check for a disabler role`, + contract, + "getDisabler", + "call", + [], + true, + value => { + assert.strictEqual(value, constants.NULL_ADDRESS); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check for a pauser role`, + contract, + "getPauser", + "call", + [], + true, + value => { + assert.strictEqual(value, constants.NULL_ADDRESS); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can remove a role`, + contract, + "removeRole", + "send", + [0] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check if the caller has a role`, + contract, + "isRole", + "call", + [0], + true, + value => { + assert.ok(!value); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check if a role is paused`, + contract, + "isPaused", + "call", + [0], + true, + value => { + assert.ok(!value); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot pause a role if not owner or pauser`, + contract, + "pause", + "send", + [0], + false, + receipt => {}, + tester.addressTwo + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can set a role`, + contract, + "setRole", + "send", + [4, tester.addressTwo] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot unpause an unpaused role`, + contract, + "unpause", + "send", + [0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can pause an unpaused role`, + contract, + "pause", + "send", + [0], + true, + receipt => {}, + tester.addressTwo + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot pause a paused role`, + contract, + "pause", + "send", + [0], + false, + receipt => {}, + tester.addressTwo + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can pause the pauser role`, + contract, + "pause", + "send", + [4] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 pauser cannot call a paused role`, + contract, + "pause", + "send", + [4], + false, + receipt => {}, + tester.addressTwo + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can check if a role is paused`, + contract, + "isPaused", + "call", + [0], + true, + value => { + assert.ok(value); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can unpause a paused role`, + contract, + "unpause", + "send", + [0] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can get an empty timelock`, + contract, + "getTimelock", + "call", + ["0x01020304", "0x"], + true, + value => { + assert.ok(!value.exists); + assert.ok(!value.completed); + assert.ok(!value.expired); + assert.strictEqual(value.completionTime, "0"); + assert.strictEqual(value.expirationTime, "0"); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can get an empty default timelock interval`, + contract, + "getDefaultTimelockInterval", + "call", + ["0x01020304"], + true, + value => { + assert.strictEqual(value, "0"); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can get an empty default timelock expiration`, + contract, + "getDefaultTimelockExpiration", + "call", + ["0x01020304"], + true, + value => { + assert.strictEqual(value, "0"); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval with no selector`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0x00000000", 0, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockInterval to modify interval over 8 weeks`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0xe950c085", 5443200, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot create timelock with excessive duration`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0xe950c085", constants.FULL_APPROVAL, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0xe950c085", 10000, 5] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot shorten existing initiateModifyTimelockInterval timelock`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0xe950c085", 10000, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to change a duration`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0xe950c085", 10001, 5] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockInterval to set a timelock on another function`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0xaaaaaaaa", 10000, 0] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval with no selector`, + contract, + "modifyTimelockInterval", + "send", + ["0x00000000", 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockInterval before timelock completion`, + contract, + "modifyTimelockInterval", + "send", + ["0xe950c085", 1000], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration with no selector`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0x00000000", 0, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to with expiration over one month`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0xe950c085", 5443200, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call initiateModifyTimelockExpiration to modify expiration under one minute`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0xd7ce3c6f", 30, 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0xd7ce3c6f", 300000, 0] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call initiateModifyTimelockExpiration to set a timelock on another function`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0xe950c085", 30, 0] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration with no selector`, + contract, + "modifyTimelockExpiration", + "send", + ["0x00000000", 0], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration before timelock completion`, + contract, + "modifyTimelockExpiration", + "send", + ["0xd7ce3c6f", 300], + false + ); + + // advance time by 2 weeks + await tester.advanceTime(60 * 60 * 24 * 7 * 2 + 5); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call modifyTimelockInterval`, + contract, + "modifyTimelockInterval", + "send", + ["0xaaaaaaaa", 10000] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 can call modifyTimelockExpiration`, + contract, + "modifyTimelockExpiration", + "send", + ["0xd7ce3c6f", 300000] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 cannot call modifyTimelockExpiration if expiration is too short`, + contract, + "modifyTimelockExpiration", + "send", + ["0xe950c085", 30], + false + ); } module.exports = { testAccountRecoveryManager -}; \ No newline at end of file +}; diff --git a/yarn.lock b/yarn.lock index 479ab1c..da1caff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25,11 +25,46 @@ dependencies: regenerator-runtime "^0.13.2" +"@babel/runtime@^7.6.3": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.4.tgz#d79f5a2040f7caa24d53e563aad49cbc05581308" + integrity sha512-neAp3zt80trRVBI1x0azq6c57aNBqYZH8KhMm3TaB7wEI5Q4A2SHfBHE8w9gOhI/lrqxtEbXZgQIrHP+wvSGwQ== + dependencies: + regenerator-runtime "^0.13.2" + +"@nodelib/fs.scandir@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" + integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== + dependencies: + "@nodelib/fs.stat" "2.0.3" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" + integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" + integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== + dependencies: + "@nodelib/fs.scandir" "2.1.3" + fastq "^1.6.0" + "@openzeppelin/contracts@2.3.0": version "2.3.0" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-2.3.0.tgz#043961a6e37b87e0eb80647c7528a7c62c41361f" integrity sha512-lf8C3oULQAnsu3OTRP4tP5/ddfil6l65Lg3JQCwAIgc99vZ1jz5qeBoETGGGmczxt+bIyMI06WPP2apC74EZag== +"@samverschueren/stream-to-observable@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" + integrity sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg== + dependencies: + any-observable "^0.3.0" + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -49,6 +84,30 @@ dependencies: "@types/node" "*" +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + +"@types/events@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" + integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== + +"@types/glob@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" + integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== + dependencies: + "@types/events" "*" + "@types/minimatch" "*" + "@types/node" "*" + +"@types/minimatch@*", "@types/minimatch@^3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + "@types/node@*": version "12.7.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.1.tgz#3b5c3a26393c19b400844ac422bd0f631a94d69d" @@ -59,6 +118,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.15.tgz#e8f7729b631be1b02ae130ff0b61f3e018000640" integrity sha512-CBR5avlLcu0YCILJiDIXeU2pTw7UK/NIxfC63m7d7CVamho1qDEzXKkOtEauQRPMy6MI8mLozth+JJkas7HY6g== +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + JSONStream@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" @@ -121,6 +185,14 @@ agentkeepalive@^3.4.1: dependencies: humanize-ms "^1.2.1" +aggregate-error@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0" + integrity sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + ajv@^5.2.2: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" @@ -160,6 +232,11 @@ ansi-colors@^1.0.1: dependencies: ansi-wrap "^0.1.0" +ansi-escapes@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + ansi-escapes@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.2.1.tgz#4dccdb846c3eee10f6d64dea66273eab90c37228" @@ -201,6 +278,14 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + ansi-wrap@0.1.0, ansi-wrap@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" @@ -211,6 +296,11 @@ antlr4@4.7.1: resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.7.1.tgz#69984014f096e9e775f53dd9744bf994d8959773" integrity sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ== +any-observable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" + integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog== + any-promise@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" @@ -305,6 +395,11 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= +array-differ@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b" + integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg== + array-each@^1.0.0, array-each@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" @@ -344,6 +439,11 @@ array-sort@^1.0.0: get-value "^2.0.6" kind-of "^5.0.2" +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" @@ -354,6 +454,11 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= +arrify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" + integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== + asn1.js@^4.0.0: version "4.10.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" @@ -587,6 +692,13 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" +braces@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + brorand@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" @@ -816,7 +928,7 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chalk@^1.1.1: +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= @@ -827,7 +939,7 @@ chalk@^1.1.1: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -836,6 +948,14 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -909,11 +1029,23 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + cli-boxes@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d" integrity sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w== +cli-cursor@^2.0.0, cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" @@ -928,6 +1060,14 @@ cli-table@^0.3.1: dependencies: colors "1.0.3" +cli-truncate@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + integrity sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ= + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" @@ -1025,11 +1165,23 @@ color-convert@^1.9.0: dependencies: color-name "1.1.3" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + color-support@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" @@ -1067,7 +1219,7 @@ commander@2.18.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" integrity sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ== -commander@^2.9.0, commander@~2.20.3: +commander@^2.20.0, commander@^2.9.0, commander@~2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -1084,6 +1236,11 @@ commander@~2.8.1: dependencies: graceful-readlink ">= 1.0.0" +compare-versions@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.5.1.tgz#26e1f5cf0d48a77eced5046b9f67b6b61075a393" + integrity sha512-9fGPIB7C6AyM18CJJBHt5EnCZDG3oiTJYy0NjfIAGjKpzv0tkxWko7TNQHF5ymqm7IH03tqmeuBxtvD+Izh6mg== + component-emitter@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" @@ -1193,7 +1350,7 @@ cors@^2.8.1: object-assign "^4" vary "^1" -cosmiconfig@^5.0.7: +cosmiconfig@^5.0.7, cosmiconfig@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== @@ -1203,6 +1360,17 @@ cosmiconfig@^5.0.7: js-yaml "^3.13.1" parse-json "^4.0.0" +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + create-ecdh@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" @@ -1254,6 +1422,15 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" + integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypto-browserify@3.12.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -1296,6 +1473,11 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +date-fns@^1.27.2: + version "1.30.1" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" + integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== + death@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" @@ -1399,6 +1581,11 @@ decompress@^4.0.0: pify "^2.3.0" strip-dirs "^2.0.0" +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -1455,6 +1642,20 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +del@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/del/-/del-5.1.0.tgz#d9487c94e367410e6eff2925ee58c0c84a75b3a7" + integrity sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA== + dependencies: + globby "^10.0.1" + graceful-fs "^4.2.2" + is-glob "^4.0.1" + is-path-cwd "^2.2.0" + is-path-inside "^3.0.1" + p-map "^3.0.0" + rimraf "^3.0.0" + slash "^3.0.0" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1512,6 +1713,13 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + doctrine@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" @@ -1576,6 +1784,11 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +elegant-spinner@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= + elliptic@6.3.3: version "6.3.3" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.3.tgz#5482d9646d54bcb89fd7d994fc9e2e9568876e3f" @@ -2018,6 +2231,21 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^2.0.3, execa@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-2.1.0.tgz#e5d3ecd837d2a60ec50f3da78fd39767747bbe99" + integrity sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^3.0.0" + onetime "^5.1.0" + p-finally "^2.0.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" @@ -2173,6 +2401,17 @@ fast-diff@^1.1.2, fast-diff@^1.2.0: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== +fast-glob@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.1.1.tgz#87ee30e9e9f3eb40d6f254a7997655da753d7c82" + integrity sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" @@ -2183,6 +2422,13 @@ fast-levenshtein@~2.0.4: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fastq@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.0.tgz#4ec8a38f4ac25f21492673adb7eae9cfef47d1c2" + integrity sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA== + dependencies: + reusify "^1.0.0" + fd-slicer@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" @@ -2195,6 +2441,21 @@ figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== +figures@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + figures@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.0.0.tgz#756275c964646163cc6f9197c7a0295dbfd04de9" @@ -2255,6 +2516,13 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + finalhandler@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" @@ -2268,7 +2536,7 @@ finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" -find-up@4.1.0: +find-up@4.1.0, find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -2298,6 +2566,13 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" +find-versions@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.2.0.tgz#10297f98030a786829681690545ef659ed1d254e" + integrity sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww== + dependencies: + semver-regex "^2.0.0" + findup-sync@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" @@ -2529,6 +2804,11 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== + get-stdin@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-7.0.0.tgz#8d5de98f15171a125c5e516643c7a6d0ea8a96f6" @@ -2554,7 +2834,7 @@ get-stream@^4.0.0, get-stream@^4.1.0: dependencies: pump "^3.0.0" -get-stream@^5.1.0: +get-stream@^5.0.0, get-stream@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== @@ -2596,6 +2876,13 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" +glob-parent@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2" + integrity sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw== + dependencies: + is-glob "^4.0.1" + glob-stream@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" @@ -2699,6 +2986,20 @@ globals@^11.7.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +globby@^10.0.1: + version "10.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" + integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.0.3" + glob "^7.1.3" + ignore "^5.1.1" + merge2 "^1.2.3" + slash "^3.0.0" + glogg@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f" @@ -2748,6 +3049,11 @@ graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.1 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.1.tgz#1c1f0c364882c868f5bff6512146328336a11b1d" integrity sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw== +graceful-fs@^4.2.2: + version "4.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" + integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== + "graceful-readlink@>= 1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" @@ -2850,6 +3156,11 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + has-symbol-support-x@^1.4.1: version "1.4.2" resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" @@ -3036,6 +3347,22 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" +husky@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/husky/-/husky-4.2.1.tgz#b09f1bd9129e6c323cc515dc17081d0615e2d7c1" + integrity sha512-Qa0lRreeIf4Tl92sSs42ER6qc3hzoyQPPorzOrFWfPEVbdi6LuvJEqWKPk905fOWIR76iBpp7ECZNIwk+a8xuQ== + dependencies: + chalk "^3.0.0" + ci-info "^2.0.0" + compare-versions "^3.5.1" + cosmiconfig "^6.0.0" + find-versions "^3.2.0" + opencollective-postinstall "^2.0.2" + pkg-dir "^4.2.0" + please-upgrade-node "^3.2.0" + slash "^3.0.0" + which-pm-runs "^1.0.0" + iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -3072,6 +3399,11 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +ignore@^5.1.1, ignore@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" + integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== + import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" @@ -3088,6 +3420,14 @@ import-fresh@^3.0.0: parent-module "^1.0.0" resolve-from "^4.0.0" +import-fresh@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -3098,6 +3438,16 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + infer-owner@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" @@ -3333,7 +3683,7 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" -is-glob@^4.0.0: +is-glob@^4.0.0, is-glob@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== @@ -3387,7 +3737,12 @@ is-number@^4.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== -is-obj@^1.0.0: +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^1.0.0, is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= @@ -3397,6 +3752,18 @@ is-object@^1.0.1: resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= +is-observable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" + integrity sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA== + dependencies: + symbol-observable "^1.1.0" + +is-path-cwd@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + is-path-inside@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" @@ -3404,6 +3771,11 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" +is-path-inside@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" + integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== + is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" @@ -3438,6 +3810,11 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + is-relative@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" @@ -3455,6 +3832,11 @@ is-stream@^1.0.0, is-stream@^1.1.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + is-symbol@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" @@ -3796,6 +4178,75 @@ liftoff@^3.1.0: rechoir "^0.6.2" resolve "^1.1.7" +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + +lint-staged@^9.2.1: + version "9.5.0" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-9.5.0.tgz#290ec605252af646d9b74d73a0fa118362b05a33" + integrity sha512-nawMob9cb/G1J98nb8v3VC/E8rcX1rryUYXVZ69aT9kde6YWX+uvNOEHY5yf2gcWcTJGiD0kqXmCnS3oD75GIA== + dependencies: + chalk "^2.4.2" + commander "^2.20.0" + cosmiconfig "^5.2.1" + debug "^4.1.1" + dedent "^0.7.0" + del "^5.0.0" + execa "^2.0.3" + listr "^0.14.3" + log-symbols "^3.0.0" + micromatch "^4.0.2" + normalize-path "^3.0.0" + please-upgrade-node "^3.1.1" + string-argv "^0.3.0" + stringify-object "^3.3.0" + +listr-silent-renderer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= + +listr-update-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz#4ea8368548a7b8aecb7e06d8c95cb45ae2ede6a2" + integrity sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA== + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^2.3.0" + strip-ansi "^3.0.1" + +listr-verbose-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz#f1132167535ea4c1261102b9f28dac7cba1e03db" + integrity sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw== + dependencies: + chalk "^2.4.1" + cli-cursor "^2.1.0" + date-fns "^1.27.2" + figures "^2.0.0" + +listr@^0.14.3: + version "0.14.3" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" + integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA== + dependencies: + "@samverschueren/stream-to-observable" "^0.3.0" + is-observable "^1.1.0" + is-promise "^2.1.0" + is-stream "^1.1.0" + listr-silent-renderer "^1.1.1" + listr-update-renderer "^0.5.0" + listr-verbose-renderer "^0.5.0" + p-map "^2.0.0" + rxjs "^6.3.3" + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -3835,6 +4286,29 @@ lodash@^4.14.2, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.2.0 resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg= + dependencies: + chalk "^1.0.0" + +log-symbols@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" + integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== + dependencies: + chalk "^2.4.2" + +log-update@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" + integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= + dependencies: + ansi-escapes "^3.0.0" + cli-cursor "^2.0.0" + wrap-ansi "^3.0.1" + lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" @@ -3960,6 +4434,16 @@ merge-descriptors@1.0.1: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.2.3, merge2@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" + integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -4003,6 +4487,14 @@ micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" @@ -4185,6 +4677,11 @@ move-concurrently@^1.0.1: rimraf "^2.5.4" run-queue "^1.0.3" +mri@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.4.tgz#7cb1dd1b9b40905f1fac053abe25b6720f44744a" + integrity sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -4200,6 +4697,17 @@ ms@^2.0.0, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +multimatch@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-4.0.0.tgz#8c3c0f6e3e8449ada0af3dd29efb491a375191b3" + integrity sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ== + dependencies: + "@types/minimatch" "^3.0.3" + array-differ "^3.0.0" + array-union "^2.1.0" + arrify "^2.0.1" + minimatch "^3.0.4" + mute-stdout@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" @@ -4440,6 +4948,13 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" +npm-run-path@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-3.1.0.tgz#7f91be317f6a466efed3c9f2980ad8a4ee8b0fa5" + integrity sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg== + dependencies: + path-key "^3.0.0" + npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" @@ -4566,6 +5081,13 @@ once@1.x, once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: dependencies: wrappy "1" +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + onetime@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" @@ -4573,6 +5095,11 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" +opencollective-postinstall@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89" + integrity sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw== + optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" @@ -4668,6 +5195,11 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= +p-finally@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" + integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== + p-is-promise@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" @@ -4708,6 +5240,18 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-map@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" + integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== + dependencies: + aggregate-error "^3.0.0" + p-timeout@^1.1.1: version "1.2.1" resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" @@ -4838,6 +5382,16 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" +parse-json@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f" + integrity sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + lines-and-columns "^1.1.6" + parse-node-version@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" @@ -4895,6 +5449,11 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + path-parse@^1.0.5, path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -4926,6 +5485,11 @@ path-type@^1.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + pbkdf2@^3.0.3: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" @@ -4952,6 +5516,11 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +picomatch@^2.0.5: + version "2.2.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a" + integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA== + pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -4974,6 +5543,20 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +please-upgrade-node@^3.1.1, please-upgrade-node@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" + integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== + dependencies: + semver-compare "^1.0.0" + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -4999,6 +5582,11 @@ preserve@^0.2.0: resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= +prettier@1.16.4: + version "1.16.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.4.tgz#73e37e73e018ad2db9c76742e2647e21790c9717" + integrity sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g== + prettier@^1.14.3: version "1.18.2" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" @@ -5009,6 +5597,18 @@ pretty-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= +pretty-quick@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pretty-quick/-/pretty-quick-2.0.1.tgz#417ee605ade98ecc686e72f63b5d28a2c35b43e9" + integrity sha512-y7bJt77XadjUr+P1uKqZxFWLddvj3SKY6EU4BuQtMxmmEFSMpbN132pUWdSG1g1mtUfO0noBvn7wBf0BVeomHg== + dependencies: + chalk "^2.4.2" + execa "^2.1.0" + find-up "^4.1.0" + ignore "^5.1.4" + mri "^1.1.4" + multimatch "^4.0.0" + process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -5470,6 +6070,14 @@ responselike@^1.0.2: dependencies: lowercase-keys "^1.0.0" +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + restore-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" @@ -5488,6 +6096,11 @@ retry@^0.10.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= +reusify@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + rimraf@2.6.3, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" @@ -5495,6 +6108,13 @@ rimraf@2.6.3, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: dependencies: glob "^7.1.3" +rimraf@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.1.tgz#48d3d4cb46c80d388ab26cd61b1b466ae9ae225a" + integrity sha512-IQ4ikL8SjBiEDZfk+DFVwqRK8md24RWMEJkdSlgNLkyyAImcjf8SWvU1qFMDOb4igBClbTQ/ugPqXcRwdFTxZw== + dependencies: + glob "^7.1.3" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -5518,6 +6138,11 @@ run-async@^2.2.0: dependencies: is-promise "^2.1.0" +run-parallel@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" + integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== + run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" @@ -5525,6 +6150,13 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" +rxjs@^6.3.3: + version "6.5.4" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" + integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q== + dependencies: + tslib "^1.9.0" + rxjs@^6.4.0: version "6.5.2" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.2.tgz#2e35ce815cd46d84d02a209fb4e5921e051dbec7" @@ -5595,6 +6227,11 @@ seek-bzip@^1.0.5: dependencies: commander "~2.8.1" +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" @@ -5609,6 +6246,11 @@ semver-greatest-satisfied-range@^1.1.0: dependencies: sver-compat "^1.5.0" +semver-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338" + integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== + semver-utils@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/semver-utils/-/semver-utils-1.1.4.tgz#cf0405e669a57488913909fc1c3f29bf2a4871e2" @@ -5721,11 +6363,23 @@ shebang-command@^1.2.0: dependencies: shebang-regex "^1.0.0" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + shelljs@^0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.3.tgz#a7f3319520ebf09ee81275b2368adb286659b097" @@ -5759,6 +6413,16 @@ sisteransi@^1.0.3: resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.3.tgz#98168d62b79e3a5e758e27ae63c4a053d748f4eb" integrity sha512-SbEG75TzH8G7eVXFSN5f9EExILKfly7SUvVY5DhhYLvfhKqhDFY0OzevWa/zwak0RLRfWS5AvfMWpd9gJvr5Yg== +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= + slice-ansi@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" @@ -6052,6 +6716,11 @@ strict-uri-encode@^1.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= +string-argv@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" + integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== + string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -6103,6 +6772,15 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +stringify-object@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" @@ -6143,6 +6821,11 @@ strip-eof@^1.0.0: resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + strip-hex-prefix@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" @@ -6188,6 +6871,13 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" +supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + sver-compat@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8" @@ -6214,6 +6904,11 @@ swarm-js@0.1.39: tar "^4.0.2" xhr-request-promise "^0.1.2" +symbol-observable@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + table@^5.2.3: version "5.4.5" resolved "https://registry.yarnpkg.com/table/-/table-5.4.5.tgz#c8f4ea2d8fee08c0027fac27b0ec0a4fe01dfa42" @@ -6333,6 +7028,13 @@ to-regex-range@^2.1.0: is-number "^3.0.0" repeat-string "^1.6.1" +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" @@ -7004,6 +7706,11 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= +which-pm-runs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" + integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= + which@^1.1.1, which@^1.2.14, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -7011,6 +7718,13 @@ which@^1.1.1, which@^1.2.14, which@^1.2.9, which@^1.3.1: dependencies: isexe "^2.0.0" +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" @@ -7043,6 +7757,14 @@ wrap-ansi@^2.0.0: string-width "^1.0.1" strip-ansi "^3.0.1" +wrap-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" + integrity sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo= + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" @@ -7159,6 +7881,13 @@ yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== +yaml@^1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.7.2.tgz#f26aabf738590ab61efaca502358e48dc9f348b2" + integrity sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw== + dependencies: + "@babel/runtime" "^7.6.3" + yargs-parser@^13.1.0: version "13.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" From 5b53bfb5480a4ec4c7a3e66729e2261a42c81aed Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Fri, 7 Feb 2020 18:57:05 -0800 Subject: [PATCH 29/47] add prettier --- scripts/test/ci.js | 18 +- scripts/test/constants.js | 1256 +- .../testIndestructibleRegistry.js | 147 +- ...stDharmaAccountRecoveryMultisigDeployer.js | 83 +- ...AccountRecoveryOperatorMultisigDeployer.js | 73 +- .../testDharmaKeyRegistryMultisigDeployer.js | 84 +- .../testDharmaUpgradeMultisigDeployer.js | 84 +- .../contracts/registries/testKeyRegistryV2.js | 614 +- .../upgradeability/testPerformingUpgrade.js | 317 +- .../testUpgradeBeaconController.js | 390 +- .../testUpgradeBeaconControllerManager.js | 1796 +- scripts/test/deploy.js | 2232 +- scripts/test/deployMockExternal.js | 10407 +++++---- scripts/test/test.js | 17532 ++++++++-------- scripts/test/testCoverage.js | 18 +- scripts/test/testHelpers.js | 578 +- scripts/test/web3.js | 6 +- 17 files changed, 17849 insertions(+), 17786 deletions(-) diff --git a/scripts/test/ci.js b/scripts/test/ci.js index ec8fbf6..39d8852 100644 --- a/scripts/test/ci.js +++ b/scripts/test/ci.js @@ -1,16 +1,16 @@ // import tests -const deployMockExternal = require('./deployMockExternal.js'); -const deploy = require('./deploy'); -const test = require('./test'); +const deployMockExternal = require("./deployMockExternal.js"); +const deploy = require("./deploy"); +const test = require("./test"); // run tests async function runTests() { - const context = process.env.TESTING_CONTEXT; + const context = process.env.TESTING_CONTEXT; - await deployMockExternal.test(context); - await deploy.test(context); - await test.test(context); - process.exit(0) + await deployMockExternal.test(context); + await deploy.test(context); + await test.test(context); + process.exit(0); } -runTests(); \ No newline at end of file +runTests(); diff --git a/scripts/test/constants.js b/scripts/test/constants.js index 81a68b0..187882c 100644 --- a/scripts/test/constants.js +++ b/scripts/test/constants.js @@ -1,672 +1,598 @@ module.exports = Object.freeze({ - NULL_ADDRESS: '0x0000000000000000000000000000000000000000', - NULL_BYTES_32: ( - '0x0000000000000000000000000000000000000000000000000000000000000000' - ), - EMPTY_HASH: ( - '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' - ), - FULL_APPROVAL: ( - '115792089237316195423570985008687907853269984665640564039457584007913129639935' - ), - KEYLESS_CREATE2_DEPLOYER_ADDRESS: ( - '0x4c8D290a1B368ac4728d83a9e8321fC3af2b39b1' - ), - KEYLESS_CREATE2_DEPLOYMENT_TRANSACTION: ( - '0xf87e8085174876e800830186a08080ad601f80600e600039806000f350fe600036818237' + - '80368234f58015156014578182fd5b80825250506014600cf31ba022222222222222222222' + - '22222222222222222222222222222222222222222222a02222222222222222222222222222' + - '222222222222222222222222222222222222' - ), - KEYLESS_CREATE2_ADDRESS: ( - '0x7A0D94F55792C434d74a40883C6ed8545E406D12' - ), - KEYLESS_CREATE2_RUNTIME_HASH: ( - '0x60003681823780368234f58015156014578182fd5b80825250506014600cf3' - ), - INEFFICIENT_IMMUTABLE_CREATE2_FACTORY_ADDRESS: ( - '0xcfA3A7637547094fF06246817a35B8333C315196' - ), - IMMUTABLE_CREATE2_FACTORY_ADDRESS: ( - '0x0000000000FFe8B47B3e2130213B802212439497' - ), - IMMUTABLE_CREATE2_FACTORY_SALT: ( - '0x0000000000000000000000000000000000000000f4b0218f13a6440a6f020000' - ), - IMMUTABLE_CREATE2_FACTORY_CREATION_CODE: ( - '0x608060405234801561001057600080fd5b50610833806100206000396000f3fe60806040' + - '526004361061003f5760003560e01c806308508b8f1461004457806364e030871461009857' + - '806385cf97ab14610138578063a49a7c90146101bc575b600080fd5b348015610050576000' + - '80fd5b506100846004803603602081101561006757600080fd5b503573ffffffffffffffff' + - 'ffffffffffffffffffffffff166101ec565b604080519115158252519081900360200190f3' + - '5b61010f600480360360408110156100ae57600080fd5b8135919081019060408101602082' + - '01356401000000008111156100d057600080fd5b8201836020820111156100e257600080fd' + - '5b8035906020019184600183028401116401000000008311171561010457600080fd5b5090' + - '92509050610217565b6040805173ffffffffffffffffffffffffffffffffffffffff909216' + - '8252519081900360200190f35b34801561014457600080fd5b5061010f6004803603604081' + - '101561015b57600080fd5b8135919081019060408101602082013564010000000081111561' + - '017d57600080fd5b82018360208201111561018f57600080fd5b8035906020019184600183' + - '02840111640100000000831117156101b157600080fd5b509092509050610592565b348015' + - '6101c857600080fd5b5061010f600480360360408110156101df57600080fd5b5080359060' + - '20013561069e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020' + - '819052604090205460ff1690565b600083606081901c33148061024c57507fffffffffffff' + - 'ffffffffffffffffffffffffffff0000000000000000000000008116155b6102a157604051' + - '7f08c379a00000000000000000000000000000000000000000000000000000000081526004' + - '01808060200182810382526045815260200180610774604591396060019150506040518091' + - '0390fd5b606084848080601f01602080910402602001604051908101604052809392919081' + - '81526020018383808284376000920182905250604051855195965090943094508b93508692' + - '506020918201918291908401908083835b6020831061033557805182527fffffffffffffff' + - 'ffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161' + - '02f8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffff' + - 'ffffffffffffffffffffffff018019909216911617905260408051929094018281037fffff' + - 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001835280855282' + - '51928201929092207fff000000000000000000000000000000000000000000000000000000' + - '000000008383015260609890981b7fffffffffffffffffffffffffffffffffffffffff0000' + - '00000000000000000000166021830152603582019690965260558082019790975282518082' + - '03909701875260750182525084519484019490942073ffffffffffffffffffffffffffffff' + - 'ffffffffff81166000908152938490529390922054929350505060ff16156104a757604051' + - '7f08c379a00000000000000000000000000000000000000000000000000000000081526004' + - '0180806020018281038252603f815260200180610735603f91396040019150506040518091' + - '0390fd5b81602001825188818334f5955050508073ffffffffffffffffffffffffffffffff' + - 'ffffffff168473ffffffffffffffffffffffffffffffffffffffff161461053a576040517f' + - '08c379a0000000000000000000000000000000000000000000000000000000008152600401' + - '8080602001828103825260468152602001806107b960469139606001915050604051809103' + - '90fd5b50505073ffffffffffffffffffffffffffffffffffffffff81166000908152602081' + - '90526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff' + - 'ffffff001660011790559392505050565b6000308484846040516020018083838082843760' + - '408051919093018181037fffffffffffffffffffffffffffffffffffffffffffffffffffff' + - 'ffffffffffe001825280845281516020928301207fff000000000000000000000000000000' + - '000000000000000000000000000000008383015260609990991b7fffffffffffffffffffff' + - 'ffffffffffffffffffff000000000000000000000000166021820152603581019790975260' + - '558088019890985282518088039098018852607590960182525085519585019590952073ff' + - 'ffffffffffffffffffffffffffffffffffffff811660009081529485905294909320549394' + - '50505060ff909116159050610697575060005b9392505050565b604080517fff0000000000' + - '00000000000000000000000000000000000000000000000000006020808301919091523060' + - '601b6021830152603582018590526055808301859052835180840390910181526075909201' + - '835281519181019190912073ffffffffffffffffffffffffffffffffffffffff8116600090' + - '8152918290529190205460ff161561072e575060005b9291505056fe496e76616c69642063' + - '6f6e7472616374206372656174696f6e202d20636f6e74726163742068617320616c726561' + - '6479206265656e206465706c6f7965642e496e76616c69642073616c74202d206669727374' + - '203230206279746573206f66207468652073616c74206d757374206d617463682063616c6c' + - '696e6720616464726573732e4661696c656420746f206465706c6f7920636f6e7472616374' + - '207573696e672070726f76696465642073616c7420616e6420696e697469616c697a617469' + - '6f6e20636f64652ea265627a7a723058202bdc55310d97c4088f18acf04253db593f091405' + - '9f0c781a9df3624dcef0d1cf64736f6c634300050a0032' - ), - IMMUTABLE_CREATE2_FACTORY_RUNTIME_HASH: ( - '0x767db8f19b71e367540fa372e8e81e4dcb7ca8feede0ae58a0c0bd08b7320dee' - ), - ETH_WHALE_ADDRESS: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe', - SAI_WHALE_ADDRESS: '0x76B03EB651153a81fA1f212f2f59329B4180A46F', - DAI_WHALE_ADDRESS: '0x8134d518e0CeF5388136c0De43d7E12278701Ac5', - USDC_WHALE_ADDRESS: '0x035e742A7E62253C606b9028eeB65178B44F1e7E', - SAI_MAINNET_ADDRESS: '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359', - DAI_MAINNET_ADDRESS: '0x6B175474E89094C44Da98b954EedeAC495271d0F', - USDC_MAINNET_ADDRESS: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - CSAI_MAINNET_ADDRESS: '0xF5DCe57282A584D2746FaF1593d3121Fcac444dC', - CDAI_MAINNET_ADDRESS: '0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643', - CUSDC_MAINNET_ADDRESS: '0x39AA39c021dfbaE8faC545936693aC917d5E7563', - CETH_MAINNET_ADDRESS: '0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5', - DAI_MIGRATOR_MAINNET_ADDRESS: '0xc73e0383F3Aff3215E6f04B0331D58CeCf0Ab849', - MOCK_USDC_BLACKLISTED_ADDRESS: '0x6000000000000000000000000000000000000006', - COMPTROLLER_MAINNET_ADDRESS: ( - '0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B' - ), - UPGRADE_BEACON_ENVOY_ADDRESS: ( - '0x000000000067503c398F4c9652530DBC4eA95C02' - ), - UPGRADE_BEACON_ENVOY_SALT: ( - '0x00000000000000000000000000000000000000003b4cf3f5b304150b79010000' - ), - UPGRADE_BEACON_ENVOY_CREATION_CODE: ( - '0x608060405234801561001057600080fd5b5061020d806100206000396000f3fe608060' + - '405234801561001057600080fd5b506004361061002b5760003560e01c806315ac72ca14' + - '610030575b600080fd5b6100566004803603602081101561004657600080fd5b50356001' + - '600160a01b0316610072565b604080516001600160a01b03909216825251908190036020' + - '0190f35b60405160009081906060906001600160a01b0385169083818181855afa915050' + - '3d80600081146100be576040519150601f19603f3d011682016040523d82523d60006020' + - '84013e6100c3565b606091505b50915091508181906101535760405162461bcd60e51b81' + - '526004018080602001828103825283818151815260200191508051906020019080838360' + - '005b83811015610118578181015183820152602001610100565b50505050905090810190' + - '601f1680156101455780820380516001836020036101000a031916815260200191505b50' + - '9250505060405180910390fd5b5080516020146101945760405162461bcd60e51b815260' + - '04018080602001828103825260258152602001806101b460259139604001915050604051' + - '80910390fd5b8080602001905160208110156101a957600080fd5b505194935050505056' + - 'fe52657475726e2064617461206d7573742062652065786163746c792033322062797465' + - '732ea265627a7a72315820107734a2fcd1d762a5f847530eab7552a2346f80ce0afa3765' + - '70475d354bab3264736f6c634300050b0032' - ), - UPGRADE_BEACON_ENVOY_RUNTIME_CODE: ( - '0x608060405234801561001057600080fd5b506004361061002b5760003560e01c806315' + - 'ac72ca14610030575b600080fd5b6100566004803603602081101561004657600080fd5b' + - '50356001600160a01b0316610072565b604080516001600160a01b039092168252519081' + - '900360200190f35b60405160009081906060906001600160a01b0385169083818181855a' + - 'fa9150503d80600081146100be576040519150601f19603f3d011682016040523d82523d' + - '6000602084013e6100c3565b606091505b50915091508181906101535760405162461bcd' + - '60e51b815260040180806020018281038252838181518152602001915080519060200190' + - '80838360005b83811015610118578181015183820152602001610100565b505050509050' + - '90810190601f1680156101455780820380516001836020036101000a0319168152602001' + - '91505b509250505060405180910390fd5b5080516020146101945760405162461bcd60e5' + - '1b81526004018080602001828103825260258152602001806101b4602591396040019150' + - '5060405180910390fd5b8080602001905160208110156101a957600080fd5b5051949350' + - '50505056fe52657475726e2064617461206d7573742062652065786163746c7920333220' + - '62797465732ea265627a7a72315820107734a2fcd1d762a5f847530eab7552a2346f80ce' + - '0afa376570475d354bab3264736f6c634300050b0032' - ), - UPGRADE_BEACON_CONTROLLER_ADDRESS: ( - '0x00000000002226C940b74d674B85E4bE05539663' - ), - UPGRADE_BEACON_CONTROLLER_SALT: ( - '0x00000000000000000000000000000000000000002401b098eebfab0f53080000' - ), - UPGRADE_BEACON_CONTROLLER_METADATA: ( - ['20446861726d6155706772616465426561636f6e436f6e74726f6c6c65722020'] - ), - KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS: ( - '0x00000000011dF015e8aD00D7B2486a88C2Eb8210' - ), - KEY_RING_UPGRADE_BEACON_CONTROLLER_SALT: ( - '0x00000000000000000000000000000000000000003080ac79bc49c20d5a000000' - ), - KEY_RING_UPGRADE_BEACON_CONTROLLER_METADATA: ( - ['20446861726d614b657952696e67426561636f6e436f6e74726f6c6c65722020'] - ), - DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_ADDRESS: ( - '0x00000000001E980d286bE7f5f978f4Cc33128202' - ), - DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_SALT : ( - '0x00000000000000000000000000000000000000003fcbb8f03bf3de073e010000' - ), - DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA : ( - ['446861726d6144616955706772616465426561636f6e436f6e74726f6c6c6572'] - ), - DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_ADDRESS: ( - '0x0000000000796dC3aA12EB9FE3B6e8F4D92cc966' - ), - DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_SALT : ( - '0x00000000000000000000000000000000000000000fc2eed291fd750bd0020000' - ), - DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA : ( - ['446861726d615553444355706772616465426561636f6e436f6e74726f6c6c72'] - ), - UPGRADE_BEACON_ADDRESS: ( - '0x000000000026750c571ce882B17016557279ADaa' - ), - UPGRADE_BEACON_SALT: ( - '0x000000000000000000000000000000000000000078c916fd79282f00051f0000' - ), - UPGRADE_BEACON_METADATA: ( - ['202020202020446861726d6155706772616465426561636f6e20202020202020'] - ), - KEY_RING_UPGRADE_BEACON_ADDRESS: ( - '0x0000000000BDA2152794ac8c76B2dc86cbA57cad' - ), - KEY_RING_UPGRADE_BEACON_SALT: ( - '0x0000000000000000000000000000000000000000ca2bc7ce5bd506089c100000' - ), - KEY_RING_UPGRADE_BEACON_METADATA: ( - ['202020446861726d614b657952696e6755706772616465426561636f6e202020'] - ), - DHARMA_DAI_UPGRADE_BEACON_ADDRESS: ( - '0x0000000000ccCf289727C20269911159a7bf9eBd' - ), - DHARMA_DAI_UPGRADE_BEACON_SALT: ( - '0x000000000000000000000000000000000000000030229e8953db57001f000000' - ), - DHARMA_DAI_UPGRADE_BEACON_METADATA : ( - ['2020202020446861726d6144616955706772616465426561636f6e2020202020'] - ), - DHARMA_USDC_UPGRADE_BEACON_ADDRESS: ( - '0x00000000000274bE4365Aa18CfDC9A22A947f67D' - ), - DHARMA_USDC_UPGRADE_BEACON_SALT: ( - '0x00000000000000000000000000000000000000004961b57384658b027f080000' - ), - DHARMA_USDC_UPGRADE_BEACON_METADATA : ( - ['20202020446861726d615553444355706772616465426561636f6e2020202020'] - ), - DHARMA_DAI_ADDRESS: ( - '0x00000000001876eB1444c986fD502e618c587430' - ), - DHARMA_DAI_SALT: ( - '0x00000000000000000000000000000000000000004ed68ad580a29b000c0a0000' - ), - DHARMA_DAI_METADATA : ( - ['20202020202020446861726d6120446169202864446169292020202020202020'] - ), - DHARMA_DAI_IMPLEMENTATION_V1_ADDRESS: ( - '0x00000000580090B7b5B593AB408000b1AbB5f78d' - ), - DHARMA_DAI_IMPLEMENTATION_V1_SALT: ( - '0x0000000000000000000000000000000000000000e576fa39d46b480fd5010000' - ), - DHARMA_DAI_IMPLEMENTATION_V1_METADATA : ( - ['2020446861726d612044616920496d706c656d656e746174696f6e2056312020'] - ), - DHARMA_USDC_IMPLEMENTATION_V1_ADDRESS: ( - '0x00000000de26576A3700bb87d61BFbEE335C8b56' - ), - DHARMA_USDC_IMPLEMENTATION_V1_SALT: ( - '0x00000000000000000000000000000000000000002e6250385076920b57000000' - ), - DHARMA_USDC_IMPLEMENTATION_V1_METADATA : ( - ['446861726d612055534420436f696e20496d706c656d656e746174696f6e2031'] - ), - DHARMA_USDC_ADDRESS: ( - '0x00000000008943c65cAf789FFFCF953bE156f6f8' - ), - DHARMA_USDC_SALT: ( - '0x0000000000000000000000000000000000000000f1507216069e1c0f60090000' - ), - DHARMA_USDC_METADATA : ( - ['20202020446861726d612055534420436f696e20286455534443292020202020'] - ), - KEY_REGISTRY_ADDRESS: ( - '0x000000005D7065eB9716a410070Ee62d51092C98' - ), - KEY_REGISTRY_SALT: ( - '0x00000000000000000000000000000000000000003dafd25120eca50e14000000' - ), - KEY_REGISTRY_METADATA: ( - ['202020202020446861726d614b65795265676973747279563120202020202020'] - ), - KEY_REGISTRY_V2_ADDRESS: ( - '0x000000000D38df53b45C5733c7b34000dE0BDF52' - ), - KEY_REGISTRY_V2_SALT: ( - '0x0000000000000000000000000000000000000000035383a4848e750d83000000' - ), - KEY_REGISTRY_V2_METADATA: ( - ['202020202020446861726d614b65795265676973747279563220202020202020'] - ), - ACCOUNT_RECOVERY_MANAGER_ADDRESS: ( - '0x00000000004cDa75701EeA02D1F2F9BDcE54C10D' - ), - ACCOUNT_RECOVERY_MANAGER_SALT: ( - '0x000000000000000000000000000000000000000000f9460080747d0837020000' - ), - ACCOUNT_RECOVERY_MANAGER_METADATA: ( - ['2020446861726d614163636f756e745265636f766572794d616e616765722020'] - ), - ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS: ( - '0x0000000000DfEd903aD76996FC07BF89C0127B1E' - ), - ACCOUNT_RECOVERY_MANAGER_V2_SALT: ( - '0x000000000000000000000000000000000000000009adfe40acf37300b2020000' - ), - ACCOUNT_RECOVERY_MANAGER_V2_METADATA: ( - ['20446861726d614163636f756e745265636f766572794d616e61676572563220'] - ), - UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS: ( - '0x00000000008A10a98969A000D1C0AbA90F858D6a' - ), - UPGRADE_BEACON_CONTROLLER_MANAGER_SALT: ( - '0x000000000000000000000000000000000000000002661332276954010e060000' - ), - UPGRADE_BEACON_CONTROLLER_MANAGER_METADATA: ( - ['2055706772616465426561636f6e436f6e74726f6c6c65724d616e6167657220'] - ), - FACTORY_ADDRESS: ( - '0xfc00C80b0000007F73004edB00094caD80626d8D' - ), - FACTORY_SALT: ( - '0x0000000000000000000000000000000000000000e3c18f17dda93a0e08000000' - ), - FACTORY_METADATA: ( - [ - '202020446861726d61536d61727457616c6c6574466163746f72793120202020', - '20202020202055706772616465426561636f6e50726f78795631202020202020' - ] - ), - KEY_RING_FACTORY_ADDRESS: ( - '0x00DD005247B300f700cFdfF89C00e2aCC94c7b00' - ), - KEY_RING_FACTORY_SALT: ( - '0x00000000000000000000000000000000000000001429fc672990fb0320000000' - ), - KEY_RING_FACTORY_METADATA: ( - [ - '2020202020446861726d614b657952696e67466163746f727956312020202020', - '20204b657952696e6755706772616465426561636f6e50726f78795631202020' - ] - ), - REVERT_REASON_HELPER_METADATA: [ - "373389197482e319656922b5cf379766d403a45bdb1776717726e0d125834166" - ], - KEY_RING_FACTORY_V2_ADDRESS: ( - '0x2484000059004afB720000dc738434fA6200F49D' - ), - KEY_RING_FACTORY_V2_SALT: ( - '0x00000000000000000000000000000000000000008b0de996664c5e0c18000000' - ), - KEY_RING_FACTORY_V2_METADATA: ( - [ - '2020202020446861726d614b657952696e67466163746f727956322020202020', - '20204b657952696e6755706772616465426561636f6e50726f78795631202020' - ] - ), - KEY_REGISTRY_MIMIC_ADDRESS: ( - '0x00000000D1dBC357A3f3D0f1F934D0186Ba40396' - ), - KEY_REGISTRY_MIMIC_SALT: ( - '0x000000000000000000000000000000000000000033a95ffc488dbf0114000000' - ), - KEY_REGISTRY_MIMIC_METADATA: ( - ['20202020446861726d614b6579526567697374727956314d696d696320202020'] - ), - DHARMA_SMART_WALLET_IMPLEMENTATION_V1_ADDRESS: ( - '0x0000000010A653849F221A573E00f3A37C8C4082' - ), - DHARMA_SMART_WALLET_IMPLEMENTATION_V1_SALT: ( - '0x0000000000000000000000000000000000000000dfdbded845e0d00ca0000000' - ), - DHARMA_SMART_WALLET_IMPLEMENTATION_V1_METADATA: ( - ['446861726d61536d61727457616c6c6574496d706c656d656e746174696f6e31'] - ), - DHARMA_SMART_WALLET_IMPLEMENTATION_V3_METADATA: ( - ['446861726d61536d61727457616c6c6574496d706c656d656e746174696f6e33'] - ), - DHARMA_SMART_WALLET_IMPLEMENTATION_V5_METADATA: ( - ['446861726d61536d61727457616c6c6574496d706c656d656e746174696f6e35'] - ), - DHARMA_SMART_WALLET_IMPLEMENTATION_V7_METADATA: ( - ['446861726d61536d61727457616c6c6574496d706c656d656e746174696f6e37'] - ), - ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS: ( - '0x00000000009f22dA6fEB6735614563B9Af0339fB' - ), - ADHARMA_SMART_WALLET_IMPLEMENTATION_SALT: ( - '0x00000000000000000000000000000000000000003d317829ae4acc0b21020000' - ), - ADHARMA_SMART_WALLET_IMPLEMENTATION_METADATA: ( - ['41646861726d61536d61727457616c6c6574496d706c656d656e746174696f6e'] - ), - ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS: ( - '0x000000000053d1F0F8aA88b9001Bec1B49445B3c' - ), - ADHARMA_KEY_RING_IMPLEMENTATION_SALT: ( - '0x0000000000000000000000000000000000000000935331d823b26c05182f0000' - ), - ADHARMA_KEY_RING_IMPLEMENTATION_METADATA: ( - ['202041646861726d614b657952696e67496d706c656d656e746174696f6e2020'] - ), - ESCAPE_HATCH_REGISTRY_ADDRESS: ( - '0x00000000005280B515004B998a944630B6C663f8' - ), - ESCAPE_HATCH_REGISTRY_SALT: ( - '0x000000000000000000000000000000000000000082eb6220dd97c70002000000' - ), - ESCAPE_HATCH_REGISTRY_METADATA: ( - ['202020446861726d614573636170654861746368526567697374727920202020'] - ), - INDESTRUCTIBLE_REGISTRY_ADDRESS: ( - '0x0000000000f55ff05D0080fE17A63b16596Fd59f' - ), - INDESTRUCTIBLE_REGISTRY_RUNTIME_HASH: ( - '0xadca137a47625f8ad1da20be107380101474374dc6c31ad0b8c1807558ea3c29' - ), - REVERT_REASON_HELPER_ADDRESS: '0x13821c0129FB9e2CC16dE2660783Ff4E4861e92d', - INDESTRUCTIBLE_REGISTRY_CREATION_TX: ( - '0x64e030870000000000000000000000000000000000000000a4ab82b860e6cb06780400' + - '000000000000000000000000000000000000000000000000000000000000000040000000' + - '000000000000000000000000000000000000000000000000000000046b60806040523480' + - '1561001057600080fd5b5061044b806100206000396000f3fe6080604052348015610010' + - '57600080fd5b50600436106100415760003560e01c80632c82288c146100465780633215' + - '14321461008d5780636cf9ed9b146100c2575b600080fd5b610079600480360360208110' + - '1561005c57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166100' + - 'f5565b604080519115158252519081900360200190f35b6100c060048036036020811015' + - '6100a357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610120' + - '565b005b610079600480360360208110156100d857600080fd5b503573ffffffffffffff' + - 'ffffffffffffffffffffffffff166101ce565b73ffffffffffffffffffffffffffffffff' + - 'ffffffff1660009081526020819052604090205460ff1690565b610129816101df565b15' + - '61017f576040517f08c379a0000000000000000000000000000000000000000000000000' + - '00000000815260040180806020018281038252602c8152602001806103eb602c91396040' + - '0191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff1660' + - '0090815260208190526040902080547fffffffffffffffffffffffffffffffffffffffff' + - 'ffffffffffffffffffffff00166001179055565b60006101d9826101df565b9291505056' + - '5b6000813b8061024f57604080517f08c379a00000000000000000000000000000000000' + - '0000000000000000000000815260206004820152601260248201527f4e6f20636f646520' + - '6174207461726765742e0000000000000000000000000000604482015290519081900360' + - '640190fd5b60006060826040519080825280601f01601f19166020018201604052801561' + - '027e576020820181803883390190505b50905060208101915082600083873c8183018281' + - '116102fe57604080517f08c379a000000000000000000000000000000000000000000000' + - '000000000000815260206004820152601c60248201527f536166654d6174683a20616464' + - '6974696f6e206f766572666c6f772e00000000604482015290519081900360640190fd5b' + - '60016000845b838110156103dd57805160f81c915082156103c7578160fe148061032857' + - '508160f3145b8061033357508160fd145b8061033e5750816056145b8061034757508115' + - '5b1561035557600092506103d5565b605f821180156103655750608082105b1561039357' + - '81017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa101' + - '6103d5565b8160f214806103a257508160f4145b806103ad57508160ff145b156103c257' + - '60019750505050505050506103e5565b6103d5565b81605b14156103d557600192505b60' + - '0101610304565b505050505050505b91905056fe537570706c6965642074617267657420' + - '697320706f74656e7469616c6c7920646573747275637469626c652ea265627a7a723158' + - '20ba911a72b86ff753e41edde9621dd5f1c6169f5332418733e233da6d6678696564736f' + - '6c634300050b0032000000000000000000000000000000000000000000' - ), - CONTRACT_NAMES: { - '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359': 'SAI', - '0x6B175474E89094C44Da98b954EedeAC495271d0F': 'DAI', - '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': 'USDC', - '0xF5DCe57282A584D2746FaF1593d3121Fcac444dC': 'CSAI', - '0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643': 'CDAI', - '0x39AA39c021dfbaE8faC545936693aC917d5E7563': 'CUSDC', - '0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5': 'CETH', - '0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B': 'Comptroller', - '0x00000000001876eB1444c986fD502e618c587430': 'DDAI', - '0x0000000000946A7848C50C8f0AE1BB2792602Cb7': 'DUSDC' - }, - COMPTROLLER_ABI: [ - { - "constant": true, - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "getAccountLiquidity", - "outputs": [ - { - "internalType": "uint256", - "name": "err", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "shortfall", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address[]", - "name": "cTokens", - "type": "address[]" - } - ], - "name": "enterMarkets", - "outputs": [ - { - "internalType": "uint256[]", - "name": "errs", - "type": "uint256[]" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - } - ], - EVENT_DETAILS: { - // keccak256 of NewUserSigningKey(address) -> userSigningKey - '0x7083aac3cab97f1219cedd0ab328a5b138a10b0fc72dd9348f1dc50199b21fda': { - name: 'NewUserSigningKey', - abi: [ - { - type: 'address', - name: 'userSigningKey' - } - ] - }, - // ExternalError(address,string) -> source, reason - '0x5bbd5ab79029b89a22c80c7b7bfdc2f0c8e3f0d2a7330c7148cabc044250674b': { - name: 'ExternalError', - abi: [ - { - type: 'address', - name: 'source', - indexed: true - }, { - type: 'string', - name: 'reason' - } - ] - }, - // SmartWalletDeployed(address,address) -> wallet, userSigningKey - '0x6e60d84846384a1994833ed675b0a0f76bef64943304debf6e42a9706d1a7dd7': { - name: 'SmartWalletDeployed', - abi: [ - { - type: 'address', - name: 'wallet' - }, { - type: 'address', - name: 'userSigningKey' - } - ] - }, - // Approval(address,address,uint256) -> owner, spender, value - '0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925': { - name: 'Approval', - abi: [ - { - type: 'address', - name: 'owner', - indexed: true - }, { - type: 'address', - name: 'spender', - indexed: true - }, { - type: 'uint256', - name: 'value' - } - ] + NULL_ADDRESS: "0x0000000000000000000000000000000000000000", + NULL_BYTES_32: + "0x0000000000000000000000000000000000000000000000000000000000000000", + EMPTY_HASH: + "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + FULL_APPROVAL: + "115792089237316195423570985008687907853269984665640564039457584007913129639935", + KEYLESS_CREATE2_DEPLOYER_ADDRESS: + "0x4c8D290a1B368ac4728d83a9e8321fC3af2b39b1", + KEYLESS_CREATE2_DEPLOYMENT_TRANSACTION: + "0xf87e8085174876e800830186a08080ad601f80600e600039806000f350fe600036818237" + + "80368234f58015156014578182fd5b80825250506014600cf31ba022222222222222222222" + + "22222222222222222222222222222222222222222222a02222222222222222222222222222" + + "222222222222222222222222222222222222", + KEYLESS_CREATE2_ADDRESS: "0x7A0D94F55792C434d74a40883C6ed8545E406D12", + KEYLESS_CREATE2_RUNTIME_HASH: + "0x60003681823780368234f58015156014578182fd5b80825250506014600cf3", + INEFFICIENT_IMMUTABLE_CREATE2_FACTORY_ADDRESS: + "0xcfA3A7637547094fF06246817a35B8333C315196", + IMMUTABLE_CREATE2_FACTORY_ADDRESS: + "0x0000000000FFe8B47B3e2130213B802212439497", + IMMUTABLE_CREATE2_FACTORY_SALT: + "0x0000000000000000000000000000000000000000f4b0218f13a6440a6f020000", + IMMUTABLE_CREATE2_FACTORY_CREATION_CODE: + "0x608060405234801561001057600080fd5b50610833806100206000396000f3fe60806040" + + "526004361061003f5760003560e01c806308508b8f1461004457806364e030871461009857" + + "806385cf97ab14610138578063a49a7c90146101bc575b600080fd5b348015610050576000" + + "80fd5b506100846004803603602081101561006757600080fd5b503573ffffffffffffffff" + + "ffffffffffffffffffffffff166101ec565b604080519115158252519081900360200190f3" + + "5b61010f600480360360408110156100ae57600080fd5b8135919081019060408101602082" + + "01356401000000008111156100d057600080fd5b8201836020820111156100e257600080fd" + + "5b8035906020019184600183028401116401000000008311171561010457600080fd5b5090" + + "92509050610217565b6040805173ffffffffffffffffffffffffffffffffffffffff909216" + + "8252519081900360200190f35b34801561014457600080fd5b5061010f6004803603604081" + + "101561015b57600080fd5b8135919081019060408101602082013564010000000081111561" + + "017d57600080fd5b82018360208201111561018f57600080fd5b8035906020019184600183" + + "02840111640100000000831117156101b157600080fd5b509092509050610592565b348015" + + "6101c857600080fd5b5061010f600480360360408110156101df57600080fd5b5080359060" + + "20013561069e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020" + + "819052604090205460ff1690565b600083606081901c33148061024c57507fffffffffffff" + + "ffffffffffffffffffffffffffff0000000000000000000000008116155b6102a157604051" + + "7f08c379a00000000000000000000000000000000000000000000000000000000081526004" + + "01808060200182810382526045815260200180610774604591396060019150506040518091" + + "0390fd5b606084848080601f01602080910402602001604051908101604052809392919081" + + "81526020018383808284376000920182905250604051855195965090943094508b93508692" + + "506020918201918291908401908083835b6020831061033557805182527fffffffffffffff" + + "ffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161" + + "02f8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffff" + + "ffffffffffffffffffffffff018019909216911617905260408051929094018281037fffff" + + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001835280855282" + + "51928201929092207fff000000000000000000000000000000000000000000000000000000" + + "000000008383015260609890981b7fffffffffffffffffffffffffffffffffffffffff0000" + + "00000000000000000000166021830152603582019690965260558082019790975282518082" + + "03909701875260750182525084519484019490942073ffffffffffffffffffffffffffffff" + + "ffffffffff81166000908152938490529390922054929350505060ff16156104a757604051" + + "7f08c379a00000000000000000000000000000000000000000000000000000000081526004" + + "0180806020018281038252603f815260200180610735603f91396040019150506040518091" + + "0390fd5b81602001825188818334f5955050508073ffffffffffffffffffffffffffffffff" + + "ffffffff168473ffffffffffffffffffffffffffffffffffffffff161461053a576040517f" + + "08c379a0000000000000000000000000000000000000000000000000000000008152600401" + + "8080602001828103825260468152602001806107b960469139606001915050604051809103" + + "90fd5b50505073ffffffffffffffffffffffffffffffffffffffff81166000908152602081" + + "90526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + + "ffffff001660011790559392505050565b6000308484846040516020018083838082843760" + + "408051919093018181037fffffffffffffffffffffffffffffffffffffffffffffffffffff" + + "ffffffffffe001825280845281516020928301207fff000000000000000000000000000000" + + "000000000000000000000000000000008383015260609990991b7fffffffffffffffffffff" + + "ffffffffffffffffffff000000000000000000000000166021820152603581019790975260" + + "558088019890985282518088039098018852607590960182525085519585019590952073ff" + + "ffffffffffffffffffffffffffffffffffffff811660009081529485905294909320549394" + + "50505060ff909116159050610697575060005b9392505050565b604080517fff0000000000" + + "00000000000000000000000000000000000000000000000000006020808301919091523060" + + "601b6021830152603582018590526055808301859052835180840390910181526075909201" + + "835281519181019190912073ffffffffffffffffffffffffffffffffffffffff8116600090" + + "8152918290529190205460ff161561072e575060005b9291505056fe496e76616c69642063" + + "6f6e7472616374206372656174696f6e202d20636f6e74726163742068617320616c726561" + + "6479206265656e206465706c6f7965642e496e76616c69642073616c74202d206669727374" + + "203230206279746573206f66207468652073616c74206d757374206d617463682063616c6c" + + "696e6720616464726573732e4661696c656420746f206465706c6f7920636f6e7472616374" + + "207573696e672070726f76696465642073616c7420616e6420696e697469616c697a617469" + + "6f6e20636f64652ea265627a7a723058202bdc55310d97c4088f18acf04253db593f091405" + + "9f0c781a9df3624dcef0d1cf64736f6c634300050a0032", + IMMUTABLE_CREATE2_FACTORY_RUNTIME_HASH: + "0x767db8f19b71e367540fa372e8e81e4dcb7ca8feede0ae58a0c0bd08b7320dee", + ETH_WHALE_ADDRESS: "0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe", + SAI_WHALE_ADDRESS: "0x76B03EB651153a81fA1f212f2f59329B4180A46F", + DAI_WHALE_ADDRESS: "0x8134d518e0CeF5388136c0De43d7E12278701Ac5", + USDC_WHALE_ADDRESS: "0x035e742A7E62253C606b9028eeB65178B44F1e7E", + SAI_MAINNET_ADDRESS: "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359", + DAI_MAINNET_ADDRESS: "0x6B175474E89094C44Da98b954EedeAC495271d0F", + USDC_MAINNET_ADDRESS: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + CSAI_MAINNET_ADDRESS: "0xF5DCe57282A584D2746FaF1593d3121Fcac444dC", + CDAI_MAINNET_ADDRESS: "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643", + CUSDC_MAINNET_ADDRESS: "0x39AA39c021dfbaE8faC545936693aC917d5E7563", + CETH_MAINNET_ADDRESS: "0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5", + DAI_MIGRATOR_MAINNET_ADDRESS: "0xc73e0383F3Aff3215E6f04B0331D58CeCf0Ab849", + MOCK_USDC_BLACKLISTED_ADDRESS: "0x6000000000000000000000000000000000000006", + COMPTROLLER_MAINNET_ADDRESS: "0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B", + UPGRADE_BEACON_ENVOY_ADDRESS: "0x000000000067503c398F4c9652530DBC4eA95C02", + UPGRADE_BEACON_ENVOY_SALT: + "0x00000000000000000000000000000000000000003b4cf3f5b304150b79010000", + UPGRADE_BEACON_ENVOY_CREATION_CODE: + "0x608060405234801561001057600080fd5b5061020d806100206000396000f3fe608060" + + "405234801561001057600080fd5b506004361061002b5760003560e01c806315ac72ca14" + + "610030575b600080fd5b6100566004803603602081101561004657600080fd5b50356001" + + "600160a01b0316610072565b604080516001600160a01b03909216825251908190036020" + + "0190f35b60405160009081906060906001600160a01b0385169083818181855afa915050" + + "3d80600081146100be576040519150601f19603f3d011682016040523d82523d60006020" + + "84013e6100c3565b606091505b50915091508181906101535760405162461bcd60e51b81" + + "526004018080602001828103825283818151815260200191508051906020019080838360" + + "005b83811015610118578181015183820152602001610100565b50505050905090810190" + + "601f1680156101455780820380516001836020036101000a031916815260200191505b50" + + "9250505060405180910390fd5b5080516020146101945760405162461bcd60e51b815260" + + "04018080602001828103825260258152602001806101b460259139604001915050604051" + + "80910390fd5b8080602001905160208110156101a957600080fd5b505194935050505056" + + "fe52657475726e2064617461206d7573742062652065786163746c792033322062797465" + + "732ea265627a7a72315820107734a2fcd1d762a5f847530eab7552a2346f80ce0afa3765" + + "70475d354bab3264736f6c634300050b0032", + UPGRADE_BEACON_ENVOY_RUNTIME_CODE: + "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c806315" + + "ac72ca14610030575b600080fd5b6100566004803603602081101561004657600080fd5b" + + "50356001600160a01b0316610072565b604080516001600160a01b039092168252519081" + + "900360200190f35b60405160009081906060906001600160a01b0385169083818181855a" + + "fa9150503d80600081146100be576040519150601f19603f3d011682016040523d82523d" + + "6000602084013e6100c3565b606091505b50915091508181906101535760405162461bcd" + + "60e51b815260040180806020018281038252838181518152602001915080519060200190" + + "80838360005b83811015610118578181015183820152602001610100565b505050509050" + + "90810190601f1680156101455780820380516001836020036101000a0319168152602001" + + "91505b509250505060405180910390fd5b5080516020146101945760405162461bcd60e5" + + "1b81526004018080602001828103825260258152602001806101b4602591396040019150" + + "5060405180910390fd5b8080602001905160208110156101a957600080fd5b5051949350" + + "50505056fe52657475726e2064617461206d7573742062652065786163746c7920333220" + + "62797465732ea265627a7a72315820107734a2fcd1d762a5f847530eab7552a2346f80ce" + + "0afa376570475d354bab3264736f6c634300050b0032", + UPGRADE_BEACON_CONTROLLER_ADDRESS: + "0x00000000002226C940b74d674B85E4bE05539663", + UPGRADE_BEACON_CONTROLLER_SALT: + "0x00000000000000000000000000000000000000002401b098eebfab0f53080000", + UPGRADE_BEACON_CONTROLLER_METADATA: [ + "20446861726d6155706772616465426561636f6e436f6e74726f6c6c65722020" + ], + KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS: + "0x00000000011dF015e8aD00D7B2486a88C2Eb8210", + KEY_RING_UPGRADE_BEACON_CONTROLLER_SALT: + "0x00000000000000000000000000000000000000003080ac79bc49c20d5a000000", + KEY_RING_UPGRADE_BEACON_CONTROLLER_METADATA: [ + "20446861726d614b657952696e67426561636f6e436f6e74726f6c6c65722020" + ], + DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_ADDRESS: + "0x00000000001E980d286bE7f5f978f4Cc33128202", + DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_SALT: + "0x00000000000000000000000000000000000000003fcbb8f03bf3de073e010000", + DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA: [ + "446861726d6144616955706772616465426561636f6e436f6e74726f6c6c6572" + ], + DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_ADDRESS: + "0x0000000000796dC3aA12EB9FE3B6e8F4D92cc966", + DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_SALT: + "0x00000000000000000000000000000000000000000fc2eed291fd750bd0020000", + DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA: [ + "446861726d615553444355706772616465426561636f6e436f6e74726f6c6c72" + ], + UPGRADE_BEACON_ADDRESS: "0x000000000026750c571ce882B17016557279ADaa", + UPGRADE_BEACON_SALT: + "0x000000000000000000000000000000000000000078c916fd79282f00051f0000", + UPGRADE_BEACON_METADATA: [ + "202020202020446861726d6155706772616465426561636f6e20202020202020" + ], + KEY_RING_UPGRADE_BEACON_ADDRESS: + "0x0000000000BDA2152794ac8c76B2dc86cbA57cad", + KEY_RING_UPGRADE_BEACON_SALT: + "0x0000000000000000000000000000000000000000ca2bc7ce5bd506089c100000", + KEY_RING_UPGRADE_BEACON_METADATA: [ + "202020446861726d614b657952696e6755706772616465426561636f6e202020" + ], + DHARMA_DAI_UPGRADE_BEACON_ADDRESS: + "0x0000000000ccCf289727C20269911159a7bf9eBd", + DHARMA_DAI_UPGRADE_BEACON_SALT: + "0x000000000000000000000000000000000000000030229e8953db57001f000000", + DHARMA_DAI_UPGRADE_BEACON_METADATA: [ + "2020202020446861726d6144616955706772616465426561636f6e2020202020" + ], + DHARMA_USDC_UPGRADE_BEACON_ADDRESS: + "0x00000000000274bE4365Aa18CfDC9A22A947f67D", + DHARMA_USDC_UPGRADE_BEACON_SALT: + "0x00000000000000000000000000000000000000004961b57384658b027f080000", + DHARMA_USDC_UPGRADE_BEACON_METADATA: [ + "20202020446861726d615553444355706772616465426561636f6e2020202020" + ], + DHARMA_DAI_ADDRESS: "0x00000000001876eB1444c986fD502e618c587430", + DHARMA_DAI_SALT: + "0x00000000000000000000000000000000000000004ed68ad580a29b000c0a0000", + DHARMA_DAI_METADATA: [ + "20202020202020446861726d6120446169202864446169292020202020202020" + ], + DHARMA_DAI_IMPLEMENTATION_V1_ADDRESS: + "0x00000000580090B7b5B593AB408000b1AbB5f78d", + DHARMA_DAI_IMPLEMENTATION_V1_SALT: + "0x0000000000000000000000000000000000000000e576fa39d46b480fd5010000", + DHARMA_DAI_IMPLEMENTATION_V1_METADATA: [ + "2020446861726d612044616920496d706c656d656e746174696f6e2056312020" + ], + DHARMA_USDC_IMPLEMENTATION_V1_ADDRESS: + "0x00000000de26576A3700bb87d61BFbEE335C8b56", + DHARMA_USDC_IMPLEMENTATION_V1_SALT: + "0x00000000000000000000000000000000000000002e6250385076920b57000000", + DHARMA_USDC_IMPLEMENTATION_V1_METADATA: [ + "446861726d612055534420436f696e20496d706c656d656e746174696f6e2031" + ], + DHARMA_USDC_ADDRESS: "0x00000000008943c65cAf789FFFCF953bE156f6f8", + DHARMA_USDC_SALT: + "0x0000000000000000000000000000000000000000f1507216069e1c0f60090000", + DHARMA_USDC_METADATA: [ + "20202020446861726d612055534420436f696e20286455534443292020202020" + ], + KEY_REGISTRY_ADDRESS: "0x000000005D7065eB9716a410070Ee62d51092C98", + KEY_REGISTRY_SALT: + "0x00000000000000000000000000000000000000003dafd25120eca50e14000000", + KEY_REGISTRY_METADATA: [ + "202020202020446861726d614b65795265676973747279563120202020202020" + ], + KEY_REGISTRY_V2_ADDRESS: "0x000000000D38df53b45C5733c7b34000dE0BDF52", + KEY_REGISTRY_V2_SALT: + "0x0000000000000000000000000000000000000000035383a4848e750d83000000", + KEY_REGISTRY_V2_METADATA: [ + "202020202020446861726d614b65795265676973747279563220202020202020" + ], + ACCOUNT_RECOVERY_MANAGER_ADDRESS: + "0x00000000004cDa75701EeA02D1F2F9BDcE54C10D", + ACCOUNT_RECOVERY_MANAGER_SALT: + "0x000000000000000000000000000000000000000000f9460080747d0837020000", + ACCOUNT_RECOVERY_MANAGER_METADATA: [ + "2020446861726d614163636f756e745265636f766572794d616e616765722020" + ], + ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS: + "0x0000000000DfEd903aD76996FC07BF89C0127B1E", + ACCOUNT_RECOVERY_MANAGER_V2_SALT: + "0x000000000000000000000000000000000000000009adfe40acf37300b2020000", + ACCOUNT_RECOVERY_MANAGER_V2_METADATA: [ + "20446861726d614163636f756e745265636f766572794d616e61676572563220" + ], + UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS: + "0x00000000008A10a98969A000D1C0AbA90F858D6a", + UPGRADE_BEACON_CONTROLLER_MANAGER_SALT: + "0x000000000000000000000000000000000000000002661332276954010e060000", + UPGRADE_BEACON_CONTROLLER_MANAGER_METADATA: [ + "2055706772616465426561636f6e436f6e74726f6c6c65724d616e6167657220" + ], + FACTORY_ADDRESS: "0xfc00C80b0000007F73004edB00094caD80626d8D", + FACTORY_SALT: + "0x0000000000000000000000000000000000000000e3c18f17dda93a0e08000000", + FACTORY_METADATA: [ + "202020446861726d61536d61727457616c6c6574466163746f72793120202020", + "20202020202055706772616465426561636f6e50726f78795631202020202020" + ], + KEY_RING_FACTORY_ADDRESS: "0x00DD005247B300f700cFdfF89C00e2aCC94c7b00", + KEY_RING_FACTORY_SALT: + "0x00000000000000000000000000000000000000001429fc672990fb0320000000", + KEY_RING_FACTORY_METADATA: [ + "2020202020446861726d614b657952696e67466163746f727956312020202020", + "20204b657952696e6755706772616465426561636f6e50726f78795631202020" + ], + REVERT_REASON_HELPER_METADATA: [ + "373389197482e319656922b5cf379766d403a45bdb1776717726e0d125834166" + ], + KEY_RING_FACTORY_V2_ADDRESS: "0x2484000059004afB720000dc738434fA6200F49D", + KEY_RING_FACTORY_V2_SALT: + "0x00000000000000000000000000000000000000008b0de996664c5e0c18000000", + KEY_RING_FACTORY_V2_METADATA: [ + "2020202020446861726d614b657952696e67466163746f727956322020202020", + "20204b657952696e6755706772616465426561636f6e50726f78795631202020" + ], + KEY_REGISTRY_MIMIC_ADDRESS: "0x00000000D1dBC357A3f3D0f1F934D0186Ba40396", + KEY_REGISTRY_MIMIC_SALT: + "0x000000000000000000000000000000000000000033a95ffc488dbf0114000000", + KEY_REGISTRY_MIMIC_METADATA: [ + "20202020446861726d614b6579526567697374727956314d696d696320202020" + ], + DHARMA_SMART_WALLET_IMPLEMENTATION_V1_ADDRESS: + "0x0000000010A653849F221A573E00f3A37C8C4082", + DHARMA_SMART_WALLET_IMPLEMENTATION_V1_SALT: + "0x0000000000000000000000000000000000000000dfdbded845e0d00ca0000000", + DHARMA_SMART_WALLET_IMPLEMENTATION_V1_METADATA: [ + "446861726d61536d61727457616c6c6574496d706c656d656e746174696f6e31" + ], + DHARMA_SMART_WALLET_IMPLEMENTATION_V3_METADATA: [ + "446861726d61536d61727457616c6c6574496d706c656d656e746174696f6e33" + ], + DHARMA_SMART_WALLET_IMPLEMENTATION_V5_METADATA: [ + "446861726d61536d61727457616c6c6574496d706c656d656e746174696f6e35" + ], + DHARMA_SMART_WALLET_IMPLEMENTATION_V7_METADATA: [ + "446861726d61536d61727457616c6c6574496d706c656d656e746174696f6e37" + ], + ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS: + "0x00000000009f22dA6fEB6735614563B9Af0339fB", + ADHARMA_SMART_WALLET_IMPLEMENTATION_SALT: + "0x00000000000000000000000000000000000000003d317829ae4acc0b21020000", + ADHARMA_SMART_WALLET_IMPLEMENTATION_METADATA: [ + "41646861726d61536d61727457616c6c6574496d706c656d656e746174696f6e" + ], + ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS: + "0x000000000053d1F0F8aA88b9001Bec1B49445B3c", + ADHARMA_KEY_RING_IMPLEMENTATION_SALT: + "0x0000000000000000000000000000000000000000935331d823b26c05182f0000", + ADHARMA_KEY_RING_IMPLEMENTATION_METADATA: [ + "202041646861726d614b657952696e67496d706c656d656e746174696f6e2020" + ], + ESCAPE_HATCH_REGISTRY_ADDRESS: "0x00000000005280B515004B998a944630B6C663f8", + ESCAPE_HATCH_REGISTRY_SALT: + "0x000000000000000000000000000000000000000082eb6220dd97c70002000000", + ESCAPE_HATCH_REGISTRY_METADATA: [ + "202020446861726d614573636170654861746368526567697374727920202020" + ], + INDESTRUCTIBLE_REGISTRY_ADDRESS: + "0x0000000000f55ff05D0080fE17A63b16596Fd59f", + INDESTRUCTIBLE_REGISTRY_RUNTIME_HASH: + "0xadca137a47625f8ad1da20be107380101474374dc6c31ad0b8c1807558ea3c29", + REVERT_REASON_HELPER_ADDRESS: "0x13821c0129FB9e2CC16dE2660783Ff4E4861e92d", + INDESTRUCTIBLE_REGISTRY_CREATION_TX: + "0x64e030870000000000000000000000000000000000000000a4ab82b860e6cb06780400" + + "000000000000000000000000000000000000000000000000000000000000000040000000" + + "000000000000000000000000000000000000000000000000000000046b60806040523480" + + "1561001057600080fd5b5061044b806100206000396000f3fe6080604052348015610010" + + "57600080fd5b50600436106100415760003560e01c80632c82288c146100465780633215" + + "14321461008d5780636cf9ed9b146100c2575b600080fd5b610079600480360360208110" + + "1561005c57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166100" + + "f5565b604080519115158252519081900360200190f35b6100c060048036036020811015" + + "6100a357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610120" + + "565b005b610079600480360360208110156100d857600080fd5b503573ffffffffffffff" + + "ffffffffffffffffffffffffff166101ce565b73ffffffffffffffffffffffffffffffff" + + "ffffffff1660009081526020819052604090205460ff1690565b610129816101df565b15" + + "61017f576040517f08c379a0000000000000000000000000000000000000000000000000" + + "00000000815260040180806020018281038252602c8152602001806103eb602c91396040" + + "0191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff1660" + + "0090815260208190526040902080547fffffffffffffffffffffffffffffffffffffffff" + + "ffffffffffffffffffffff00166001179055565b60006101d9826101df565b9291505056" + + "5b6000813b8061024f57604080517f08c379a00000000000000000000000000000000000" + + "0000000000000000000000815260206004820152601260248201527f4e6f20636f646520" + + "6174207461726765742e0000000000000000000000000000604482015290519081900360" + + "640190fd5b60006060826040519080825280601f01601f19166020018201604052801561" + + "027e576020820181803883390190505b50905060208101915082600083873c8183018281" + + "116102fe57604080517f08c379a000000000000000000000000000000000000000000000" + + "000000000000815260206004820152601c60248201527f536166654d6174683a20616464" + + "6974696f6e206f766572666c6f772e00000000604482015290519081900360640190fd5b" + + "60016000845b838110156103dd57805160f81c915082156103c7578160fe148061032857" + + "508160f3145b8061033357508160fd145b8061033e5750816056145b8061034757508115" + + "5b1561035557600092506103d5565b605f821180156103655750608082105b1561039357" + + "81017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa101" + + "6103d5565b8160f214806103a257508160f4145b806103ad57508160ff145b156103c257" + + "60019750505050505050506103e5565b6103d5565b81605b14156103d557600192505b60" + + "0101610304565b505050505050505b91905056fe537570706c6965642074617267657420" + + "697320706f74656e7469616c6c7920646573747275637469626c652ea265627a7a723158" + + "20ba911a72b86ff753e41edde9621dd5f1c6169f5332418733e233da6d6678696564736f" + + "6c634300050b0032000000000000000000000000000000000000000000", + CONTRACT_NAMES: { + "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359": "SAI", + "0x6B175474E89094C44Da98b954EedeAC495271d0F": "DAI", + "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48": "USDC", + "0xF5DCe57282A584D2746FaF1593d3121Fcac444dC": "CSAI", + "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643": "CDAI", + "0x39AA39c021dfbaE8faC545936693aC917d5E7563": "CUSDC", + "0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5": "CETH", + "0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B": "Comptroller", + "0x00000000001876eB1444c986fD502e618c587430": "DDAI", + "0x0000000000946A7848C50C8f0AE1BB2792602Cb7": "DUSDC" }, - // Transfer(address,address,uint256) -> to, from, value - '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef': { - name: 'Transfer', - abi: [ + COMPTROLLER_ABI: [ { - type: 'address', - name: 'from', - indexed: true - }, { - type: 'address', - name: 'to', - indexed: true - }, { - type: 'uint256', - name: 'value' - } - ] - }, - // Mint(address,uint256,uint256) -> minter, mintTokens, mintAmount - '0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f': { - name: 'Mint', - abi: [ - { - type: 'address', - name: 'minter' - }, { - type: 'uint256', - name: 'mintTokens' - }, { - type: 'uint256', - name: 'mintAmount' - } - ] - }, - // Redeem(address,uint256,uint256) -> redeemer, redeemTokens, redeemAmount - '0xe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a929': { - name: 'Redeem', - abi: [ - { - type: 'address', - name: 'redeemer' - }, { - type: 'uint256', - name: 'redeemTokens' - }, { - type: 'uint256', - name: 'redeemAmount' - } - ] - }, - // MarketEntered(address,address) -> cToken, account - '0x3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a5': { - name: 'MarketEntered', - abi: [ + constant: true, + inputs: [ + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "getAccountLiquidity", + outputs: [ + { + internalType: "uint256", + name: "err", + type: "uint256" + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256" + }, + { + internalType: "uint256", + name: "shortfall", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, { - type: 'address', - name: 'cToken' - }, { - type: 'address', - name: 'account' + constant: false, + inputs: [ + { + internalType: "address[]", + name: "cTokens", + type: "address[]" + } + ], + name: "enterMarkets", + outputs: [ + { + internalType: "uint256[]", + name: "errs", + type: "uint256[]" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" } - ] - }, - // AccrueInterest(uint256,uint256,uint256) -> - // interestAccumulated, borrowIndex, totalBorrows - '0x875352fb3fadeb8c0be7cbbe8ff761b308fa7033470cd0287f02f3436fd76cb9': { - name: 'AccrueInterest', - abi: [ - { - type: 'uint256', - name: 'interestAccumulated' - }, { - type: 'uint256', - name: 'borrowIndex' - }, { - type: 'uint256', - name: 'totalBorrows' + ], + EVENT_DETAILS: { + // keccak256 of NewUserSigningKey(address) -> userSigningKey + "0x7083aac3cab97f1219cedd0ab328a5b138a10b0fc72dd9348f1dc50199b21fda": { + name: "NewUserSigningKey", + abi: [ + { + type: "address", + name: "userSigningKey" + } + ] + }, + // ExternalError(address,string) -> source, reason + "0x5bbd5ab79029b89a22c80c7b7bfdc2f0c8e3f0d2a7330c7148cabc044250674b": { + name: "ExternalError", + abi: [ + { + type: "address", + name: "source", + indexed: true + }, + { + type: "string", + name: "reason" + } + ] + }, + // SmartWalletDeployed(address,address) -> wallet, userSigningKey + "0x6e60d84846384a1994833ed675b0a0f76bef64943304debf6e42a9706d1a7dd7": { + name: "SmartWalletDeployed", + abi: [ + { + type: "address", + name: "wallet" + }, + { + type: "address", + name: "userSigningKey" + } + ] + }, + // Approval(address,address,uint256) -> owner, spender, value + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925": { + name: "Approval", + abi: [ + { + type: "address", + name: "owner", + indexed: true + }, + { + type: "address", + name: "spender", + indexed: true + }, + { + type: "uint256", + name: "value" + } + ] + }, + // Transfer(address,address,uint256) -> to, from, value + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef": { + name: "Transfer", + abi: [ + { + type: "address", + name: "from", + indexed: true + }, + { + type: "address", + name: "to", + indexed: true + }, + { + type: "uint256", + name: "value" + } + ] + }, + // Mint(address,uint256,uint256) -> minter, mintTokens, mintAmount + "0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f": { + name: "Mint", + abi: [ + { + type: "address", + name: "minter" + }, + { + type: "uint256", + name: "mintTokens" + }, + { + type: "uint256", + name: "mintAmount" + } + ] + }, + // Redeem(address,uint256,uint256) -> redeemer, redeemTokens, redeemAmount + "0xe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a929": { + name: "Redeem", + abi: [ + { + type: "address", + name: "redeemer" + }, + { + type: "uint256", + name: "redeemTokens" + }, + { + type: "uint256", + name: "redeemAmount" + } + ] + }, + // MarketEntered(address,address) -> cToken, account + "0x3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a5": { + name: "MarketEntered", + abi: [ + { + type: "address", + name: "cToken" + }, + { + type: "address", + name: "account" + } + ] + }, + // AccrueInterest(uint256,uint256,uint256) -> + // interestAccumulated, borrowIndex, totalBorrows + "0x875352fb3fadeb8c0be7cbbe8ff761b308fa7033470cd0287f02f3436fd76cb9": { + name: "AccrueInterest", + abi: [ + { + type: "uint256", + name: "interestAccumulated" + }, + { + type: "uint256", + name: "borrowIndex" + }, + { + type: "uint256", + name: "totalBorrows" + } + ] + }, + "0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0": { + name: "Failure", + abi: [ + { + type: "uint256", + name: "error" + }, + { + type: "uint256", + name: "info" + }, + { + type: "uint256", + name: "detail" + } + ] } - ] }, - '0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0': { - name: 'Failure', - abi: [ - { - type: 'uint256', - name: 'error' - }, { - type: 'uint256', - name: 'info' - }, { - type: 'uint256', - name: 'detail' - } - ] - } - }, - METADATA_IDENTIFIER: '627a7a72315820', - MOCK_OWNER_PRIVATE_KEYS: [ - '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', - '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', - '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', - '0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', - '0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc' - ] -}) + METADATA_IDENTIFIER: "627a7a72315820", + MOCK_OWNER_PRIVATE_KEYS: [ + "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + ] +}); diff --git a/scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js b/scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js index b474853..32a2090 100644 --- a/scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js +++ b/scripts/test/contracts/indestructible-registry/testIndestructibleRegistry.js @@ -1,81 +1,81 @@ const constants = require("../../constants"); const { newContractAndSwapMetadataHash } = require("../../testHelpers"); -const IndestructibleRegistryArtifact = require('../../../../build/contracts/IndestructibleRegistry.json'); +const IndestructibleRegistryArtifact = require("../../../../build/contracts/IndestructibleRegistry.json"); async function testIndestructibleRegistry(tester, contracts) { const { DharmaSmartWalletImplementationV6, DharmaSmartWalletImplementationV7, - DharmaKeyRingImplementationV1, + DharmaKeyRingImplementationV1 } = contracts; - const IndestructibleRegistryDeployer = newContractAndSwapMetadataHash( + const IndestructibleRegistryDeployer = newContractAndSwapMetadataHash( IndestructibleRegistryArtifact ); const IndestructibleRegistry = await tester.runTest( `IndestructibleRegistry contract deployment`, IndestructibleRegistryDeployer, - '', - 'deploy' - ) + "", + "deploy" + ); await tester.runTest( - 'IndestructibleRegistry can register itself as indestructible', + "IndestructibleRegistry can register itself as indestructible", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [IndestructibleRegistry.options.address] - ) + ); await tester.runTest( - 'IndestructibleRegistry can register the upgrade beacon as indestructible', + "IndestructibleRegistry can register the upgrade beacon as indestructible", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [constants.UPGRADE_BEACON_ADDRESS] - ) + ); await tester.runTest( - 'IndestructibleRegistry can register the upgrade beacon controller as indestructible', + "IndestructibleRegistry can register the upgrade beacon controller as indestructible", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [constants.UPGRADE_BEACON_CONTROLLER_ADDRESS] - ) + ); await tester.runTest( - 'IndestructibleRegistry can register the key ring upgrade beacon as indestructible', + "IndestructibleRegistry can register the key ring upgrade beacon as indestructible", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [constants.KEY_RING_UPGRADE_BEACON_ADDRESS] - ) + ); await tester.runTest( - 'IndestructibleRegistry can register the key ring upgrade beacon controller as indestructible', + "IndestructibleRegistry can register the key ring upgrade beacon controller as indestructible", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS] - ) + ); await tester.runTest( - 'IndestructibleRegistry can register the upgrade beacon envoy as indestructible', + "IndestructibleRegistry can register the upgrade beacon envoy as indestructible", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [constants.UPGRADE_BEACON_ENVOY_ADDRESS] - ) + ); await tester.runTest( - 'IndestructibleRegistry can register the account recovery manager V2 as indestructible', + "IndestructibleRegistry can register the account recovery manager V2 as indestructible", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS] - ) + ); /* await tester.runTest( @@ -88,45 +88,45 @@ async function testIndestructibleRegistry(tester, contracts) { */ await tester.runTest( - 'IndestructibleRegistry can register DharmaKeyRegistryV2 as indestructible', + "IndestructibleRegistry can register DharmaKeyRegistryV2 as indestructible", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [constants.KEY_REGISTRY_V2_ADDRESS] - ) + ); await tester.runTest( - 'IndestructibleRegistry can register DharmaEscapeHatchRegistry as indestructible', + "IndestructibleRegistry can register DharmaEscapeHatchRegistry as indestructible", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [constants.ESCAPE_HATCH_REGISTRY_ADDRESS] - ) + ); await tester.runTest( - 'WARNING: IndestructibleRegistry CANNOT register the smart wallet factory as indestructible (even though it is in fact NOT destructible)', + "WARNING: IndestructibleRegistry CANNOT register the smart wallet factory as indestructible (even though it is in fact NOT destructible)", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [constants.FACTORY_ADDRESS], false - ) + ); await tester.runTest( - 'IndestructibleRegistry can register the Adharma smart wallet implementation as indestructible', + "IndestructibleRegistry can register the Adharma smart wallet implementation as indestructible", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS] - ) + ); await tester.runTest( - 'IndestructibleRegistry can register the Adharma key ring implementation as indestructible', + "IndestructibleRegistry can register the Adharma key ring implementation as indestructible", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS] - ) + ); /* await tester.runTest( @@ -156,7 +156,7 @@ async function testIndestructibleRegistry(tester, contracts) { ) */ - if (tester.context !== 'coverage') { + if (tester.context !== "coverage") { /* await tester.runTest( 'IndestructibleRegistry can register V2 implementation as indestructible', @@ -193,28 +193,28 @@ async function testIndestructibleRegistry(tester, contracts) { */ await tester.runTest( - 'IndestructibleRegistry can register V6 implementation as indestructible', + "IndestructibleRegistry can register V6 implementation as indestructible", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [DharmaSmartWalletImplementationV6.options.address] - ) + ); await tester.runTest( - 'IndestructibleRegistry can register V7 implementation as indestructible', + "IndestructibleRegistry can register V7 implementation as indestructible", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [DharmaSmartWalletImplementationV7.options.address] - ) + ); await tester.runTest( - 'IndestructibleRegistry can register V1 key ring implementation as indestructible', + "IndestructibleRegistry can register V1 key ring implementation as indestructible", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [DharmaKeyRingImplementationV1.options.address] - ) + ); } /* @@ -228,15 +228,14 @@ async function testIndestructibleRegistry(tester, contracts) { */ await tester.runTest( - 'IndestructibleRegistry can register the upgrade beacon controller manager as indestructible', + "IndestructibleRegistry can register the upgrade beacon controller manager as indestructible", IndestructibleRegistry, - 'registerAsIndestructible', - 'send', + "registerAsIndestructible", + "send", [constants.UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS] - ) + ); } module.exports = { - testIndestructibleRegistry, -} - + testIndestructibleRegistry +}; diff --git a/scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryMultisigDeployer.js b/scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryMultisigDeployer.js index 980ac9e..9f18448 100644 --- a/scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryMultisigDeployer.js +++ b/scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryMultisigDeployer.js @@ -2,59 +2,68 @@ async function testDharmaAccountRecoveryMultisigDeployer(tester, contract) { await tester.runTest( `DharmaAccountRecoveryMultisig contract deployment fails if threshold is not met`, contract, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001' - ]], + "", + "deploy", + [["0x0000000000000000000000000000000000000001"]], false - ) + ); await tester.runTest( `DharmaAccountRecoveryMultisig contract deployment fails if sigs are out of order`, contract, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000001' - ]], + "", + "deploy", + [ + [ + "0x0000000000000000000000000000000000000005", + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", + "0x0000000000000000000000000000000000000004", + "0x0000000000000000000000000000000000000001" + ] + ], false - ) + ); await tester.runTest( `DharmaAccountRecoveryMultisig contract deployment fails with too many owners`, contract, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000006', - '0x0000000000000000000000000000000000000007', - '0x0000000000000000000000000000000000000008', - '0x0000000000000000000000000000000000000009', - '0x000000000000000000000000000000000000000a', - '0x000000000000000000000000000000000000000b' - ]], + "", + "deploy", + [ + [ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", + "0x0000000000000000000000000000000000000004", + "0x0000000000000000000000000000000000000005", + "0x0000000000000000000000000000000000000006", + "0x0000000000000000000000000000000000000007", + "0x0000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000009", + "0x000000000000000000000000000000000000000a", + "0x000000000000000000000000000000000000000b" + ] + ], false - ) + ); await tester.runTest( `DharmaAccountRecoveryMultisig contract deployment`, contract, - '', - 'deploy', - [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour]] - ) + "", + "deploy", + [ + [ + tester.ownerOne, + tester.ownerTwo, + tester.ownerThree, + tester.ownerFour + ] + ] + ); } module.exports = { - testDharmaAccountRecoveryMultisigDeployer, + testDharmaAccountRecoveryMultisigDeployer }; diff --git a/scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryOperatorMultisigDeployer.js b/scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryOperatorMultisigDeployer.js index e6f0a9c..9331d3d 100644 --- a/scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryOperatorMultisigDeployer.js +++ b/scripts/test/contracts/multisig-deployers/testDharmaAccountRecoveryOperatorMultisigDeployer.js @@ -1,52 +1,57 @@ -async function testDharmaAccountRecoveryOperatorMultisigDeployer(tester, contract) { +async function testDharmaAccountRecoveryOperatorMultisigDeployer( + tester, + contract +) { await tester.runTest( `DharmaAccountRecoveryOperatorMultisig contract deployment fails if threshold is not met`, contract, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001' - ]], + "", + "deploy", + [["0x0000000000000000000000000000000000000001"]], false - ) + ); await tester.runTest( `DharmaAccountRecoveryOperatorMultisig contract deployment fails if sigs are out of order`, contract, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000001' - ]], + "", + "deploy", + [ + [ + "0x0000000000000000000000000000000000000005", + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", + "0x0000000000000000000000000000000000000004", + "0x0000000000000000000000000000000000000001" + ] + ], false - ) + ); await tester.runTest( `DharmaAccountRecoveryOperatorMultisig contract deployment fails with too many owners`, contract, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000006', - '0x0000000000000000000000000000000000000007', - '0x0000000000000000000000000000000000000008', - '0x0000000000000000000000000000000000000009', - '0x000000000000000000000000000000000000000a', - '0x000000000000000000000000000000000000000b' - ]], + "", + "deploy", + [ + [ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", + "0x0000000000000000000000000000000000000004", + "0x0000000000000000000000000000000000000005", + "0x0000000000000000000000000000000000000006", + "0x0000000000000000000000000000000000000007", + "0x0000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000009", + "0x000000000000000000000000000000000000000a", + "0x000000000000000000000000000000000000000b" + ] + ], false - ) + ); } module.exports = { - testDharmaAccountRecoveryOperatorMultisigDeployer, + testDharmaAccountRecoveryOperatorMultisigDeployer }; diff --git a/scripts/test/contracts/multisig-deployers/testDharmaKeyRegistryMultisigDeployer.js b/scripts/test/contracts/multisig-deployers/testDharmaKeyRegistryMultisigDeployer.js index 1978046..aec9273 100644 --- a/scripts/test/contracts/multisig-deployers/testDharmaKeyRegistryMultisigDeployer.js +++ b/scripts/test/contracts/multisig-deployers/testDharmaKeyRegistryMultisigDeployer.js @@ -2,59 +2,69 @@ async function testDharmaKeyRegistryMultisigDeployer(tester, contract) { await tester.runTest( `DharmaKeyRegistryMultisig contract deployment fails if threshold is not met`, contract, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001' - ]], + "", + "deploy", + [["0x0000000000000000000000000000000000000001"]], false - ) + ); await tester.runTest( `DharmaKeyRegistryMultisig contract deployment fails if sigs are out of order`, contract, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000001' - ]], + "", + "deploy", + [ + [ + "0x0000000000000000000000000000000000000005", + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", + "0x0000000000000000000000000000000000000004", + "0x0000000000000000000000000000000000000001" + ] + ], false - ) + ); await tester.runTest( `DharmaKeyRegistryMultisig contract deployment fails with too many owners`, contract, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000006', - '0x0000000000000000000000000000000000000007', - '0x0000000000000000000000000000000000000008', - '0x0000000000000000000000000000000000000009', - '0x000000000000000000000000000000000000000a', - '0x000000000000000000000000000000000000000b' - ]], + "", + "deploy", + [ + [ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", + "0x0000000000000000000000000000000000000004", + "0x0000000000000000000000000000000000000005", + "0x0000000000000000000000000000000000000006", + "0x0000000000000000000000000000000000000007", + "0x0000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000009", + "0x000000000000000000000000000000000000000a", + "0x000000000000000000000000000000000000000b" + ] + ], false - ) + ); await tester.runTest( `DharmaKeyRegistryMultisig contract deployment`, contract, - '', - 'deploy', - [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] - ) + "", + "deploy", + [ + [ + tester.ownerOne, + tester.ownerTwo, + tester.ownerThree, + tester.ownerFour, + tester.ownerFive + ] + ] + ); } module.exports = { - testDharmaKeyRegistryMultisigDeployer, + testDharmaKeyRegistryMultisigDeployer }; diff --git a/scripts/test/contracts/multisig-deployers/testDharmaUpgradeMultisigDeployer.js b/scripts/test/contracts/multisig-deployers/testDharmaUpgradeMultisigDeployer.js index 2562050..7ddd18a 100644 --- a/scripts/test/contracts/multisig-deployers/testDharmaUpgradeMultisigDeployer.js +++ b/scripts/test/contracts/multisig-deployers/testDharmaUpgradeMultisigDeployer.js @@ -2,59 +2,69 @@ async function testDharmaUpgradeMultisigDeployer(tester, contract) { await tester.runTest( `DharmaUpgradeMultisig contract deployment fails if threshold is not met`, contract, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001' - ]], + "", + "deploy", + [["0x0000000000000000000000000000000000000001"]], false - ) + ); await tester.runTest( `DharmaUpgradeMultisig contract deployment fails if sigs are out of order`, contract, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000001' - ]], + "", + "deploy", + [ + [ + "0x0000000000000000000000000000000000000005", + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", + "0x0000000000000000000000000000000000000004", + "0x0000000000000000000000000000000000000001" + ] + ], false - ) + ); await tester.runTest( `DharmaUpgradeMultisig contract deployment fails with too many owners`, contract, - '', - 'deploy', - [[ - '0x0000000000000000000000000000000000000001', - '0x0000000000000000000000000000000000000002', - '0x0000000000000000000000000000000000000003', - '0x0000000000000000000000000000000000000004', - '0x0000000000000000000000000000000000000005', - '0x0000000000000000000000000000000000000006', - '0x0000000000000000000000000000000000000007', - '0x0000000000000000000000000000000000000008', - '0x0000000000000000000000000000000000000009', - '0x000000000000000000000000000000000000000a', - '0x000000000000000000000000000000000000000b' - ]], + "", + "deploy", + [ + [ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", + "0x0000000000000000000000000000000000000004", + "0x0000000000000000000000000000000000000005", + "0x0000000000000000000000000000000000000006", + "0x0000000000000000000000000000000000000007", + "0x0000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000009", + "0x000000000000000000000000000000000000000a", + "0x000000000000000000000000000000000000000b" + ] + ], false - ) + ); await tester.runTest( `DharmaUpgradeMultisig contract deployment`, contract, - '', - 'deploy', - [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] - ) + "", + "deploy", + [ + [ + tester.ownerOne, + tester.ownerTwo, + tester.ownerThree, + tester.ownerFour, + tester.ownerFive + ] + ] + ); } module.exports = { - testDharmaUpgradeMultisigDeployer, + testDharmaUpgradeMultisigDeployer }; diff --git a/scripts/test/contracts/registries/testKeyRegistryV2.js b/scripts/test/contracts/registries/testKeyRegistryV2.js index fab044d..a7d9e53 100644 --- a/scripts/test/contracts/registries/testKeyRegistryV2.js +++ b/scripts/test/contracts/registries/testKeyRegistryV2.js @@ -2,330 +2,298 @@ const { web3 } = require("../../web3"); const constants = require("../../constants"); const assert = require("assert"); -async function testKeyRegistryV2( - tester, - contract, - unownedKeyRegistryAddress -) { - await tester.runTest( - 'Dharma Key Registry V2 gets the initial global key correctly', - contract, - 'getGlobalKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 attempt to get an unset specific key throws', - contract, - 'getSpecificKey', - 'call', - [tester.address], - false - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets the global key when requesting unset key', - contract, - 'getKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 cannot set a new empty global key', - contract, - 'setGlobalKey', - 'send', - [ - constants.NULL_ADDRESS, - '0x' - ], - false, - receipt => {}, - tester.originalAddress - ) - - const message = ( - contract.options.address + - tester.addressTwo.slice(2) + - web3.utils.asciiToHex( - "This signature demonstrates that the supplied signing key is valid." - ).slice(2) - ) - - const newKeySignature = tester.signHashedPrefixedHashedHexString( - message, tester.addressTwo - ) - - const badNewKeySignature = tester.signHashedPrefixedHashedHexString( - '0x12', tester.addressTwo - ) - - await tester.runTest( - 'Dharma Key Registry V2 cannot set a new global key unless called by owner', - contract, - 'setGlobalKey', - 'send', - [ - tester.addressTwo, - newKeySignature - ], - false, - receipt => {}, - tester.addressTwo - ) - - await tester.runTest( - 'Dharma Key Registry V2 cannot set an empty global key', - contract, - 'setGlobalKey', - 'send', - [ - constants.NULL_ADDRESS, - newKeySignature - ], - false - ) - - await tester.runTest( - 'Dharma Key Registry V2 cannot set a new global key with a bad signature', - contract, - 'setGlobalKey', - 'send', - [ - tester.addressTwo, - badNewKeySignature - ], - false - ) - - await tester.runTest( - 'Dharma Key Registry V2 can set a new global key correctly', - contract, - 'setGlobalKey', - 'send', - [ - tester.addressTwo, - newKeySignature - ] - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets the new global key correctly', - contract, - 'getGlobalKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.addressTwo) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 cannot set a new specific key unless called by owner', - contract, - 'setSpecificKey', - 'send', - [ - tester.address, - unownedKeyRegistryAddress - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets global key for a user if no specific key set', - contract, - 'getKeyForUser', - 'call', - [tester.address], - true, - value => { - assert.strictEqual(value, tester.addressTwo) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 can set a new specific key', - contract, - 'setSpecificKey', - 'send', - [ - tester.address, - unownedKeyRegistryAddress - ] - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets specific key for user if one is set', - contract, - 'getKeyForUser', - 'call', - [tester.address], - true, - value => { - assert.strictEqual(value, unownedKeyRegistryAddress) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets the new specific key correctly', - contract, - 'getSpecificKey', - 'call', - [tester.address], - true, - value => { - assert.strictEqual(value, unownedKeyRegistryAddress) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets the specific key when requesting set key', - contract, - 'getKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, unownedKeyRegistryAddress) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 cannot reuse a specific key', - contract, - 'setSpecificKey', - 'send', - [ - tester.address, - unownedKeyRegistryAddress - ], - false - ) - - await tester.runTest( - 'Dharma Key Registry V2 new owner cannot accept ownership before added', - contract, - 'acceptOwnership', - 'send', - [], - false - ) - - await tester.runTest( - 'Dharma Key Registry V2 cannot prepare to transfer to the null address', - contract, - 'transferOwnership', - 'send', - [ - constants.NULL_ADDRESS - ], - false - ) - - await tester.runTest( - 'Dharma Key Registry V2 can prepare to transfer to a new owner', - contract, - 'transferOwnership', - 'send', - [ - tester.address - ] - ) - - await tester.runTest( - 'Dharma Key Registry V2 can cancel an ownership transfer', - contract, - 'cancelOwnershipTransfer' - ) - - await tester.runTest( - 'Dharma Key Registry V2 new owner cannot accept ownership after cancellation', - contract, - 'acceptOwnership', - 'send', - [], - false - ) - - await tester.runTest( - 'Dharma Key Registry V2 can prepare to transfer to a new owner again', - contract, - 'transferOwnership', - 'send', - [ - tester.address - ] - ) - - await tester.runTest( - 'Dharma Key Registry V2 new owner can accept ownership', - contract, - 'acceptOwnership' - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets the new owner', - contract, - 'owner', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets the global key correctly', - contract, - 'getGlobalKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.addressTwo) - } - ) - - const messageV2 = ( - contract.options.address + - tester.address.slice(2) + - web3.utils.asciiToHex( - "This signature demonstrates that the supplied signing key is valid." - ).slice(2) - ) - - const v2KeySignature = tester.signHashedPrefixedHashedHexString( - messageV2, tester.address - ) - - await tester.runTest( - 'Dharma Key Registry V2 cannot set a previously used global key', - contract, - 'setGlobalKey', - 'send', - [ - tester.address, - v2KeySignature - ], - false - ) +async function testKeyRegistryV2(tester, contract, unownedKeyRegistryAddress) { + await tester.runTest( + "Dharma Key Registry V2 gets the initial global key correctly", + contract, + "getGlobalKey", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.address); + } + ); + + await tester.runTest( + "Dharma Key Registry V2 attempt to get an unset specific key throws", + contract, + "getSpecificKey", + "call", + [tester.address], + false + ); + + await tester.runTest( + "Dharma Key Registry V2 gets the global key when requesting unset key", + contract, + "getKey", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.address); + } + ); + + await tester.runTest( + "Dharma Key Registry V2 cannot set a new empty global key", + contract, + "setGlobalKey", + "send", + [constants.NULL_ADDRESS, "0x"], + false, + receipt => {}, + tester.originalAddress + ); + + const message = + contract.options.address + + tester.addressTwo.slice(2) + + web3.utils + .asciiToHex( + "This signature demonstrates that the supplied signing key is valid." + ) + .slice(2); + + const newKeySignature = tester.signHashedPrefixedHashedHexString( + message, + tester.addressTwo + ); + + const badNewKeySignature = tester.signHashedPrefixedHashedHexString( + "0x12", + tester.addressTwo + ); + + await tester.runTest( + "Dharma Key Registry V2 cannot set a new global key unless called by owner", + contract, + "setGlobalKey", + "send", + [tester.addressTwo, newKeySignature], + false, + receipt => {}, + tester.addressTwo + ); + + await tester.runTest( + "Dharma Key Registry V2 cannot set an empty global key", + contract, + "setGlobalKey", + "send", + [constants.NULL_ADDRESS, newKeySignature], + false + ); + + await tester.runTest( + "Dharma Key Registry V2 cannot set a new global key with a bad signature", + contract, + "setGlobalKey", + "send", + [tester.addressTwo, badNewKeySignature], + false + ); + + await tester.runTest( + "Dharma Key Registry V2 can set a new global key correctly", + contract, + "setGlobalKey", + "send", + [tester.addressTwo, newKeySignature] + ); + + await tester.runTest( + "Dharma Key Registry V2 gets the new global key correctly", + contract, + "getGlobalKey", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.addressTwo); + } + ); + + await tester.runTest( + "Dharma Key Registry V2 cannot set a new specific key unless called by owner", + contract, + "setSpecificKey", + "send", + [tester.address, unownedKeyRegistryAddress], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "Dharma Key Registry V2 gets global key for a user if no specific key set", + contract, + "getKeyForUser", + "call", + [tester.address], + true, + value => { + assert.strictEqual(value, tester.addressTwo); + } + ); + + await tester.runTest( + "Dharma Key Registry V2 can set a new specific key", + contract, + "setSpecificKey", + "send", + [tester.address, unownedKeyRegistryAddress] + ); + + await tester.runTest( + "Dharma Key Registry V2 gets specific key for user if one is set", + contract, + "getKeyForUser", + "call", + [tester.address], + true, + value => { + assert.strictEqual(value, unownedKeyRegistryAddress); + } + ); + + await tester.runTest( + "Dharma Key Registry V2 gets the new specific key correctly", + contract, + "getSpecificKey", + "call", + [tester.address], + true, + value => { + assert.strictEqual(value, unownedKeyRegistryAddress); + } + ); + + await tester.runTest( + "Dharma Key Registry V2 gets the specific key when requesting set key", + contract, + "getKey", + "call", + [], + true, + value => { + assert.strictEqual(value, unownedKeyRegistryAddress); + } + ); + + await tester.runTest( + "Dharma Key Registry V2 cannot reuse a specific key", + contract, + "setSpecificKey", + "send", + [tester.address, unownedKeyRegistryAddress], + false + ); + + await tester.runTest( + "Dharma Key Registry V2 new owner cannot accept ownership before added", + contract, + "acceptOwnership", + "send", + [], + false + ); + + await tester.runTest( + "Dharma Key Registry V2 cannot prepare to transfer to the null address", + contract, + "transferOwnership", + "send", + [constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + "Dharma Key Registry V2 can prepare to transfer to a new owner", + contract, + "transferOwnership", + "send", + [tester.address] + ); + + await tester.runTest( + "Dharma Key Registry V2 can cancel an ownership transfer", + contract, + "cancelOwnershipTransfer" + ); + + await tester.runTest( + "Dharma Key Registry V2 new owner cannot accept ownership after cancellation", + contract, + "acceptOwnership", + "send", + [], + false + ); + + await tester.runTest( + "Dharma Key Registry V2 can prepare to transfer to a new owner again", + contract, + "transferOwnership", + "send", + [tester.address] + ); + + await tester.runTest( + "Dharma Key Registry V2 new owner can accept ownership", + contract, + "acceptOwnership" + ); + + await tester.runTest( + "Dharma Key Registry V2 gets the new owner", + contract, + "owner", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.address); + } + ); + + await tester.runTest( + "Dharma Key Registry V2 gets the global key correctly", + contract, + "getGlobalKey", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.addressTwo); + } + ); + + const messageV2 = + contract.options.address + + tester.address.slice(2) + + web3.utils + .asciiToHex( + "This signature demonstrates that the supplied signing key is valid." + ) + .slice(2); + + const v2KeySignature = tester.signHashedPrefixedHashedHexString( + messageV2, + tester.address + ); + + await tester.runTest( + "Dharma Key Registry V2 cannot set a previously used global key", + contract, + "setGlobalKey", + "send", + [tester.address, v2KeySignature], + false + ); } module.exports = { testKeyRegistryV2 -}; \ No newline at end of file +}; diff --git a/scripts/test/contracts/upgradeability/testPerformingUpgrade.js b/scripts/test/contracts/upgradeability/testPerformingUpgrade.js index b5f7d99..f85631f 100644 --- a/scripts/test/contracts/upgradeability/testPerformingUpgrade.js +++ b/scripts/test/contracts/upgradeability/testPerformingUpgrade.js @@ -2,181 +2,178 @@ const constants = require("../../constants"); const assert = require("assert"); async function testPerformingUpgrade( - tester, - contract, // new implementation - userSmartWalletContract, - upgradeBeaconControllerContract, - upgradeBeaconAddress, - newImplementationVersion, - initial = false + tester, + contract, // new implementation + userSmartWalletContract, + upgradeBeaconControllerContract, + upgradeBeaconAddress, + newImplementationVersion, + initial = false ) { - let nonce; - let userSigningKey; - let oldImplementation; - let oldImplementationCodeHash; - let newImplementationCodeHash; + let nonce; + let userSigningKey; + let oldImplementation; + let oldImplementationCodeHash; + let newImplementationCodeHash; - if (!initial) { - await tester.runTest( - 'User Smart Wallet can check the user signing key prior to upgrade', - userSmartWalletContract, - 'getUserSigningKey', - 'call', - [], - true, - value => { - userSigningKey = value - } - ) + if (!initial) { + await tester.runTest( + "User Smart Wallet can check the user signing key prior to upgrade", + userSmartWalletContract, + "getUserSigningKey", + "call", + [], + true, + value => { + userSigningKey = value; + } + ); - await tester.runTest( - 'User Smart Wallet can get the nonce prior to upgrade', - userSmartWalletContract, - 'getNonce', - 'call', - [], - true, - value => { - nonce = value - } - ) - } - - await tester.runTest( - 'DharmaUpgradeBeacon current implementation can be retrieved', - upgradeBeaconControllerContract, - 'getImplementation', - 'call', - [upgradeBeaconAddress], - true, - value => { - oldImplementation = value; + await tester.runTest( + "User Smart Wallet can get the nonce prior to upgrade", + userSmartWalletContract, + "getNonce", + "call", + [], + true, + value => { + nonce = value; + } + ); } - ) - await tester.runTest( - 'Old implementation code hash can be retrieved', - tester.MockCodeCheck, - 'hash', - 'call', - [oldImplementation], - true, - value => { - oldImplementationCodeHash = value; - } - ) - - await tester.runTest( - 'New implementation code hash can be retrieved', - tester.MockCodeCheck, - 'hash', - 'call', - [contract.options.address], - true, - value => { - newImplementationCodeHash = value; - } - ) + await tester.runTest( + "DharmaUpgradeBeacon current implementation can be retrieved", + upgradeBeaconControllerContract, + "getImplementation", + "call", + [upgradeBeaconAddress], + true, + value => { + oldImplementation = value; + } + ); - await tester.runTest( - `Dharma Upgrade Beacon Controller can upgrade to V${newImplementationVersion.toString()} implementation`, - upgradeBeaconControllerContract, - 'upgrade', - 'send', - [ - upgradeBeaconAddress, - contract.options.address - ], - true, - receipt => { - if (tester.context !== 'coverage') { - assert.strictEqual( - receipt.events.Upgraded.returnValues.upgradeBeacon, - upgradeBeaconAddress - ) + await tester.runTest( + "Old implementation code hash can be retrieved", + tester.MockCodeCheck, + "hash", + "call", + [oldImplementation], + true, + value => { + oldImplementationCodeHash = value; + } + ); - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementation, - oldImplementation - ) - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementationCodeHash, - oldImplementationCodeHash - ) + await tester.runTest( + "New implementation code hash can be retrieved", + tester.MockCodeCheck, + "hash", + "call", + [contract.options.address], + true, + value => { + newImplementationCodeHash = value; + } + ); - assert.strictEqual( - receipt.events.Upgraded.returnValues.newImplementation, - contract.options.address - ) - assert.strictEqual( - receipt.events.Upgraded.returnValues.newImplementationCodeHash, - newImplementationCodeHash - ) - } - } - ) + await tester.runTest( + `Dharma Upgrade Beacon Controller can upgrade to V${newImplementationVersion.toString()} implementation`, + upgradeBeaconControllerContract, + "upgrade", + "send", + [upgradeBeaconAddress, contract.options.address], + true, + receipt => { + if (tester.context !== "coverage") { + assert.strictEqual( + receipt.events.Upgraded.returnValues.upgradeBeacon, + upgradeBeaconAddress + ); - await tester.runTest( - 'DharmaUpgradeBeacon has the new implementation set', - upgradeBeaconControllerContract, - 'getImplementation', - 'call', - [upgradeBeaconAddress], - true, - value => { - assert.strictEqual(value, contract.options.address) - } - ) + assert.strictEqual( + receipt.events.Upgraded.returnValues.oldImplementation, + oldImplementation + ); + assert.strictEqual( + receipt.events.Upgraded.returnValues + .oldImplementationCodeHash, + oldImplementationCodeHash + ); - await tester.runTest( - `UpgradeBeaconImplementationCheck deployment`, - tester.UpgradeBeaconImplementationCheckDeployer, - '', - 'deploy', - [ - upgradeBeaconAddress, contract.options.address - ] - ) + assert.strictEqual( + receipt.events.Upgraded.returnValues.newImplementation, + contract.options.address + ); + assert.strictEqual( + receipt.events.Upgraded.returnValues + .newImplementationCodeHash, + newImplementationCodeHash + ); + } + } + ); - if (!initial) { - await tester.runTest( - `V${newImplementationVersion.toString()} User Smart Wallet can get the new version (${newImplementationVersion.toString()})`, - userSmartWalletContract, - 'getVersion', - 'call', - [], - true, - value => { - assert.strictEqual(value, newImplementationVersion.toString()) - } - ) - await tester.runTest( - `V${newImplementationVersion.toString()} user smart wallet still has the same user signing key set`, - userSmartWalletContract, - 'getUserSigningKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, userSigningKey) - } - ) + "DharmaUpgradeBeacon has the new implementation set", + upgradeBeaconControllerContract, + "getImplementation", + "call", + [upgradeBeaconAddress], + true, + value => { + assert.strictEqual(value, contract.options.address); + } + ); await tester.runTest( - `V${newImplementationVersion.toString()} User Smart Wallet nonce is still set to value from before upgrade`, - userSmartWalletContract, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, nonce) - } - ) - } + `UpgradeBeaconImplementationCheck deployment`, + tester.UpgradeBeaconImplementationCheckDeployer, + "", + "deploy", + [upgradeBeaconAddress, contract.options.address] + ); + + if (!initial) { + await tester.runTest( + `V${newImplementationVersion.toString()} User Smart Wallet can get the new version (${newImplementationVersion.toString()})`, + userSmartWalletContract, + "getVersion", + "call", + [], + true, + value => { + assert.strictEqual(value, newImplementationVersion.toString()); + } + ); + + await tester.runTest( + `V${newImplementationVersion.toString()} user smart wallet still has the same user signing key set`, + userSmartWalletContract, + "getUserSigningKey", + "call", + [], + true, + value => { + assert.strictEqual(value, userSigningKey); + } + ); + + await tester.runTest( + `V${newImplementationVersion.toString()} User Smart Wallet nonce is still set to value from before upgrade`, + userSmartWalletContract, + "getNonce", + "call", + [], + true, + value => { + assert.strictEqual(value, nonce); + } + ); + } } module.exports = { testPerformingUpgrade -}; \ No newline at end of file +}; diff --git a/scripts/test/contracts/upgradeability/testUpgradeBeaconController.js b/scripts/test/contracts/upgradeability/testUpgradeBeaconController.js index f04437d..d4f914a 100644 --- a/scripts/test/contracts/upgradeability/testUpgradeBeaconController.js +++ b/scripts/test/contracts/upgradeability/testUpgradeBeaconController.js @@ -2,197 +2,215 @@ const constants = require("../../constants"); const assert = require("assert"); async function testUpgradeBeaconController( - tester, - contract, - smartWalletControllerContract, - keyRingControllerContract, - envoyContract, - smartWalletUpgradeBeaconAddress, - keyRingUpgradeBeaconAddress, - badBeaconAddress -) { - await tester.runTest( - `DharmaUpgradeBeaconController initially gets zero for lastImplementation`, - contract, - 'getCodeHashAtLastUpgrade', - 'call', - [tester.address], - true, - value => { - assert.strictEqual(value, constants.NULL_BYTES_32) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot call upgrade from non-owner account`, + tester, contract, - 'upgrade', - 'send', - [smartWalletUpgradeBeaconAddress, smartWalletControllerContract.options.address], - false, - receipt => {}, - tester.addressTwo - ) - - await tester.runTest( - `DharmaUpgradeBeaconController can set implementation on upgrade beacon contract`, smartWalletControllerContract, - 'upgrade', - 'send', - [smartWalletUpgradeBeaconAddress, smartWalletControllerContract.options.address] - ) - - await tester.runTest( - `DharmaKeyRingUpgradeBeaconController can set implementation on key ring upgrade beacon contract`, keyRingControllerContract, - 'upgrade', - 'send', - [keyRingUpgradeBeaconAddress, smartWalletControllerContract.options.address] - ) - - await tester.runTest( - `DharmaUpgradeBeaconEnvoy throws when given invalid beacon`, - envoyContract, - 'getImplementation', - 'call', - [envoyContract.options.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconEnvoy throws when given non-contract beacon`, - envoyContract, - 'getImplementation', - 'call', - [tester.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconEnvoy can get the implementation of a valid beacon`, envoyContract, - 'getImplementation', - 'call', - [keyRingUpgradeBeaconAddress], - true, - value => { - assert.strictEqual(value, smartWalletControllerContract.options.address) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot set null implementation on an upgrade beacon contract`, - contract, - 'upgrade', - 'send', - [smartWalletUpgradeBeaconAddress, constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot set non-contract implementation`, - contract, - 'upgrade', - 'send', - [smartWalletUpgradeBeaconAddress, tester.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot set null address beacon`, - contract, - 'upgrade', - 'send', - [constants.NULL_ADDRESS, smartWalletControllerContract.options.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot set non-contract address beacon`, - contract, - 'upgrade', - 'send', - [tester.address, smartWalletControllerContract.options.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot set unowned bad beacon`, - contract, - 'upgrade', - 'send', - [badBeaconAddress, smartWalletControllerContract.options.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot set unowned beacon (Note that it still logs an event!)`, - contract, - 'upgrade', - 'send', - [smartWalletUpgradeBeaconAddress, smartWalletControllerContract.options.address] - ) - - await tester.runTest( - `DharmaUpgradeBeaconController can get implementation of a beacon`, - contract, - 'getImplementation', - 'call', - [smartWalletUpgradeBeaconAddress], - true, - value => { - assert.strictEqual(value, smartWalletControllerContract.options.address) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconController can get owner`, - contract, - 'owner', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconController can call isOwner and value is ok`, - contract, - 'isOwner', - 'call', - [], - true, - value => { - assert.ok(value) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconController cannot transfer ownership to null address`, - contract, - 'transferOwnership', - 'send', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconController can transfer ownership`, - contract, - 'transferOwnership', - 'send', - [tester.address] - ) - - await tester.runTest( - `DharmaUpgradeBeaconController can renounce ownership`, - contract, - 'renounceOwnership' - ) + smartWalletUpgradeBeaconAddress, + keyRingUpgradeBeaconAddress, + badBeaconAddress +) { + await tester.runTest( + `DharmaUpgradeBeaconController initially gets zero for lastImplementation`, + contract, + "getCodeHashAtLastUpgrade", + "call", + [tester.address], + true, + value => { + assert.strictEqual(value, constants.NULL_BYTES_32); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconController cannot call upgrade from non-owner account`, + contract, + "upgrade", + "send", + [ + smartWalletUpgradeBeaconAddress, + smartWalletControllerContract.options.address + ], + false, + receipt => {}, + tester.addressTwo + ); + + await tester.runTest( + `DharmaUpgradeBeaconController can set implementation on upgrade beacon contract`, + smartWalletControllerContract, + "upgrade", + "send", + [ + smartWalletUpgradeBeaconAddress, + smartWalletControllerContract.options.address + ] + ); + + await tester.runTest( + `DharmaKeyRingUpgradeBeaconController can set implementation on key ring upgrade beacon contract`, + keyRingControllerContract, + "upgrade", + "send", + [ + keyRingUpgradeBeaconAddress, + smartWalletControllerContract.options.address + ] + ); + + await tester.runTest( + `DharmaUpgradeBeaconEnvoy throws when given invalid beacon`, + envoyContract, + "getImplementation", + "call", + [envoyContract.options.address], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconEnvoy throws when given non-contract beacon`, + envoyContract, + "getImplementation", + "call", + [tester.address], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconEnvoy can get the implementation of a valid beacon`, + envoyContract, + "getImplementation", + "call", + [keyRingUpgradeBeaconAddress], + true, + value => { + assert.strictEqual( + value, + smartWalletControllerContract.options.address + ); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconController cannot set null implementation on an upgrade beacon contract`, + contract, + "upgrade", + "send", + [smartWalletUpgradeBeaconAddress, constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconController cannot set non-contract implementation`, + contract, + "upgrade", + "send", + [smartWalletUpgradeBeaconAddress, tester.address], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconController cannot set null address beacon`, + contract, + "upgrade", + "send", + [constants.NULL_ADDRESS, smartWalletControllerContract.options.address], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconController cannot set non-contract address beacon`, + contract, + "upgrade", + "send", + [tester.address, smartWalletControllerContract.options.address], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconController cannot set unowned bad beacon`, + contract, + "upgrade", + "send", + [badBeaconAddress, smartWalletControllerContract.options.address], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconController cannot set unowned beacon (Note that it still logs an event!)`, + contract, + "upgrade", + "send", + [ + smartWalletUpgradeBeaconAddress, + smartWalletControllerContract.options.address + ] + ); + + await tester.runTest( + `DharmaUpgradeBeaconController can get implementation of a beacon`, + contract, + "getImplementation", + "call", + [smartWalletUpgradeBeaconAddress], + true, + value => { + assert.strictEqual( + value, + smartWalletControllerContract.options.address + ); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconController can get owner`, + contract, + "owner", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.address); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconController can call isOwner and value is ok`, + contract, + "isOwner", + "call", + [], + true, + value => { + assert.ok(value); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconController cannot transfer ownership to null address`, + contract, + "transferOwnership", + "send", + [constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconController can transfer ownership`, + contract, + "transferOwnership", + "send", + [tester.address] + ); + + await tester.runTest( + `DharmaUpgradeBeaconController can renounce ownership`, + contract, + "renounceOwnership" + ); } module.exports = { testUpgradeBeaconController -}; \ No newline at end of file +}; diff --git a/scripts/test/contracts/upgradeability/testUpgradeBeaconControllerManager.js b/scripts/test/contracts/upgradeability/testUpgradeBeaconControllerManager.js index 94ca0f4..f090a96 100644 --- a/scripts/test/contracts/upgradeability/testUpgradeBeaconControllerManager.js +++ b/scripts/test/contracts/upgradeability/testUpgradeBeaconControllerManager.js @@ -1,334 +1,336 @@ const constants = require("../../constants"); const assert = require("assert"); -async function testUpgradeBeaconControllerManagerPartOne( - tester, - contract -) { - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot transfer ownership from a non-owner`, - contract, - 'transferOwnership', - 'send', - [tester.addressTwo], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with null controller`, - contract, - 'initiateUpgrade', - 'send', - [constants.NULL_ADDRESS, tester.address, tester.addressTwo, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with null beacon`, - contract, - 'initiateUpgrade', - 'send', - [tester.address, constants.NULL_ADDRESS, tester.addressTwo, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with null implementation`, - contract, - 'initiateUpgrade', - 'send', - [tester.address, tester.addressTwo, constants.NULL_ADDRESS, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with non-contract implementation`, - contract, - 'initiateUpgrade', - 'send', - [tester.address, tester.addressTwo, tester.address, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with massive extraTime`, - contract, - 'initiateUpgrade', - 'send', - [tester.address, tester.addressTwo, contract.options.address, constants.FULL_APPROVAL], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can initiate upgrade timelock`, - contract, - 'initiateUpgrade', - 'send', - [tester.address, tester.addressTwo, contract.options.address, 0] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can get an empty timelock`, - contract, - 'getTimelock', - 'call', - ['0x01020304', '0x'], - true, - value => { - assert.ok(!value.exists) - assert.ok(!value.completed) - assert.ok(!value.expired) - assert.strictEqual(value.completionTime, '0') - assert.strictEqual(value.expirationTime, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can get an empty default timelock interval`, - contract, - 'getDefaultTimelockInterval', - 'call', - ['0x01020304'], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can get an empty default timelock expiration`, - contract, - 'getDefaultTimelockExpiration', - 'call', - ['0x01020304'], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot upgrade before timelock is complete`, - contract, - 'upgrade', - 'send', - [tester.address, tester.addressTwo, contract.options.address], - false - ) - - // advance time by 7 days - await tester.advanceTime((60 * 60 * 24 * 7) + 5) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot upgrade an unowned controller`, - contract, - 'upgrade', - 'send', - [tester.address, tester.addressTwo, contract.options.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot transfer controller ownership before accepting ownership`, - contract, - 'transferControllerOwnership', - 'send', - [tester.address, tester.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot agree to accept ownership of null controller`, - contract, - 'agreeToAcceptControllerOwnership', - 'send', - [constants.NULL_ADDRESS, true], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can agree to accept ownership`, - contract, - 'agreeToAcceptControllerOwnership', - 'send', - [tester.address, true] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate controller ownership transfer with null controller`, - contract, - 'initiateTransferControllerOwnership', - 'send', - [constants.NULL_ADDRESS, tester.addressTwo, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate controller ownership transfer with null new owner`, - contract, - 'initiateTransferControllerOwnership', - 'send', - [tester.address, constants.NULL_ADDRESS, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot initiate controller ownership transfer if new owner has not accepted`, - contract, - 'initiateTransferControllerOwnership', - 'send', - [tester.address, tester.addressTwo, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can initiate controller ownership transfer if new owner has accepted`, - contract, - 'initiateTransferControllerOwnership', - 'send', - [tester.address, tester.address, 0] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot transfer controller ownership prior to timelock completion`, - contract, - 'transferControllerOwnership', - 'send', - [tester.address, tester.address], - false - ) - - // advance time by 4 weeks - await tester.advanceTime((60 * 60 * 24 * 7 * 4) + 5) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot transfer unowned controller ownership`, - contract, - 'transferControllerOwnership', - 'send', - [tester.address, tester.address], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot heartbeat from non-heartbeater`, - contract, - 'heartbeat', - 'send', - [], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can heartbeat`, - contract, - 'heartbeat' - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot set new heartbeater to null address`, - contract, - 'newHeartbeater', - 'send', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner can set new heartbeater`, - contract, - 'newHeartbeater', - 'send', - [tester.address] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot arm Adharma Contingency from non-owner when not expired`, - contract, - 'armAdharmaContingency', - 'send', - [true], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when not armed`, - contract, - 'activateAdharmaContingency', - 'send', - [], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner can arm an Adharma Contingency`, - contract, - 'armAdharmaContingency', - 'send', - [true] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner can disarm Adharma Contingency`, - contract, - 'armAdharmaContingency', - 'send', - [false] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner can re-arm Adharma Contingency`, - contract, - 'armAdharmaContingency', - 'send', - [true] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency from non-owner when not expired`, - contract, - 'activateAdharmaContingency', - 'send', - [], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when it doesn't own controllers`, - contract, - 'activateAdharmaContingency', - 'send', - [], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot roll back prior to first upgrade`, - contract, - 'rollback', - 'send', - [tester.address, tester.address, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot exit Adharma Contingency when not active`, - contract, - 'exitAdharmaContingency', - 'send', - [tester.address, tester.address], - false - ) - - /* +async function testUpgradeBeaconControllerManagerPartOne(tester, contract) { + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot transfer ownership from a non-owner`, + contract, + "transferOwnership", + "send", + [tester.addressTwo], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with null controller`, + contract, + "initiateUpgrade", + "send", + [constants.NULL_ADDRESS, tester.address, tester.addressTwo, 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with null beacon`, + contract, + "initiateUpgrade", + "send", + [tester.address, constants.NULL_ADDRESS, tester.addressTwo, 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with null implementation`, + contract, + "initiateUpgrade", + "send", + [tester.address, tester.addressTwo, constants.NULL_ADDRESS, 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with non-contract implementation`, + contract, + "initiateUpgrade", + "send", + [tester.address, tester.addressTwo, tester.address, 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate an upgrade with massive extraTime`, + contract, + "initiateUpgrade", + "send", + [ + tester.address, + tester.addressTwo, + contract.options.address, + constants.FULL_APPROVAL + ], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can initiate upgrade timelock`, + contract, + "initiateUpgrade", + "send", + [tester.address, tester.addressTwo, contract.options.address, 0] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can get an empty timelock`, + contract, + "getTimelock", + "call", + ["0x01020304", "0x"], + true, + value => { + assert.ok(!value.exists); + assert.ok(!value.completed); + assert.ok(!value.expired); + assert.strictEqual(value.completionTime, "0"); + assert.strictEqual(value.expirationTime, "0"); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can get an empty default timelock interval`, + contract, + "getDefaultTimelockInterval", + "call", + ["0x01020304"], + true, + value => { + assert.strictEqual(value, "0"); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can get an empty default timelock expiration`, + contract, + "getDefaultTimelockExpiration", + "call", + ["0x01020304"], + true, + value => { + assert.strictEqual(value, "0"); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot upgrade before timelock is complete`, + contract, + "upgrade", + "send", + [tester.address, tester.addressTwo, contract.options.address], + false + ); + + // advance time by 7 days + await tester.advanceTime(60 * 60 * 24 * 7 + 5); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot upgrade an unowned controller`, + contract, + "upgrade", + "send", + [tester.address, tester.addressTwo, contract.options.address], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot transfer controller ownership before accepting ownership`, + contract, + "transferControllerOwnership", + "send", + [tester.address, tester.address], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot agree to accept ownership of null controller`, + contract, + "agreeToAcceptControllerOwnership", + "send", + [constants.NULL_ADDRESS, true], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can agree to accept ownership`, + contract, + "agreeToAcceptControllerOwnership", + "send", + [tester.address, true] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate controller ownership transfer with null controller`, + contract, + "initiateTransferControllerOwnership", + "send", + [constants.NULL_ADDRESS, tester.addressTwo, 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate controller ownership transfer with null new owner`, + contract, + "initiateTransferControllerOwnership", + "send", + [tester.address, constants.NULL_ADDRESS, 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot initiate controller ownership transfer if new owner has not accepted`, + contract, + "initiateTransferControllerOwnership", + "send", + [tester.address, tester.addressTwo, 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can initiate controller ownership transfer if new owner has accepted`, + contract, + "initiateTransferControllerOwnership", + "send", + [tester.address, tester.address, 0] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot transfer controller ownership prior to timelock completion`, + contract, + "transferControllerOwnership", + "send", + [tester.address, tester.address], + false + ); + + // advance time by 4 weeks + await tester.advanceTime(60 * 60 * 24 * 7 * 4 + 5); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot transfer unowned controller ownership`, + contract, + "transferControllerOwnership", + "send", + [tester.address, tester.address], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot heartbeat from non-heartbeater`, + contract, + "heartbeat", + "send", + [], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can heartbeat`, + contract, + "heartbeat" + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot set new heartbeater to null address`, + contract, + "newHeartbeater", + "send", + [constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner can set new heartbeater`, + contract, + "newHeartbeater", + "send", + [tester.address] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot arm Adharma Contingency from non-owner when not expired`, + contract, + "armAdharmaContingency", + "send", + [true], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when not armed`, + contract, + "activateAdharmaContingency", + "send", + [], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner can arm an Adharma Contingency`, + contract, + "armAdharmaContingency", + "send", + [true] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner can disarm Adharma Contingency`, + contract, + "armAdharmaContingency", + "send", + [false] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner can re-arm Adharma Contingency`, + contract, + "armAdharmaContingency", + "send", + [true] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency from non-owner when not expired`, + contract, + "activateAdharmaContingency", + "send", + [], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when it doesn't own controllers`, + contract, + "activateAdharmaContingency", + "send", + [], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot roll back prior to first upgrade`, + contract, + "rollback", + "send", + [tester.address, tester.address, 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot exit Adharma Contingency when not active`, + contract, + "exitAdharmaContingency", + "send", + [tester.address, tester.address], + false + ); + + /* await tester.runTest( `DharmaUpgradeBeaconControllerManager can activate Adharma Contingency`, contract, @@ -439,593 +441,569 @@ async function testUpgradeBeaconControllerManagerPartOne( ) */ - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can get heartbeat status`, - contract, - 'heartbeatStatus', - 'call', - [], - true, - value => { - assert.ok(!value.expired) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager get contingency status when armed but not activated`, - contract, - 'contingencyStatus', - 'call', - [], - true, - value => { - assert.ok(value.armed) - assert.ok(!value.activated) - assert.strictEqual(value.activationTime, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager gets 0 for non-existent total implementations`, - contract, - 'getTotalPriorImplementations', - 'call', - [tester.address, tester.address], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot get a prior implementation with no index`, - contract, - 'getPriorImplementation', - 'call', - [tester.address, tester.address, 100], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot rollback to implementation with no index`, - contract, - 'rollback', - 'send', - [tester.address, tester.address, 100], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot block rollback to implementation with no index`, - contract, - 'blockRollback', - 'send', - [tester.address, tester.address, 100], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockInterval with no selector`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0x00000000', 0, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockInterval to modify interval over 8 weeks`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 5443200, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot create timelock with excessive duration`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', constants.FULL_APPROVAL, 0], - false // TODO: move this outside of Controller manager - ) + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can get heartbeat status`, + contract, + "heartbeatStatus", + "call", + [], + true, + value => { + assert.ok(!value.expired); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager get contingency status when armed but not activated`, + contract, + "contingencyStatus", + "call", + [], + true, + value => { + assert.ok(value.armed); + assert.ok(!value.activated); + assert.strictEqual(value.activationTime, "0"); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager gets 0 for non-existent total implementations`, + contract, + "getTotalPriorImplementations", + "call", + [tester.address, tester.address], + true, + value => { + assert.strictEqual(value, "0"); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot get a prior implementation with no index`, + contract, + "getPriorImplementation", + "call", + [tester.address, tester.address, 100], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot rollback to implementation with no index`, + contract, + "rollback", + "send", + [tester.address, tester.address, 100], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot block rollback to implementation with no index`, + contract, + "blockRollback", + "send", + [tester.address, tester.address, 100], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockInterval with no selector`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0x00000000", 0, 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockInterval to modify interval over 8 weeks`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0xe950c085", 5443200, 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot create timelock with excessive duration`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0xe950c085", constants.FULL_APPROVAL, 0], + false // TODO: move this outside of Controller manager + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockInterval to set a timelock`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0xe950c085", 10000, 5] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot shorten existing initiateModifyTimelockInterval timelock`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0xe950c085", 10000, 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockInterval to change a duration`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0xe950c085", 10001, 5] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockInterval to set a timelock on another function`, + contract, + "initiateModifyTimelockInterval", + "send", + ["0xaaaaaaaa", 10000, 0] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockInterval with no selector`, + contract, + "modifyTimelockInterval", + "send", + ["0x00000000", 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockInterval before timelock completion`, + contract, + "modifyTimelockInterval", + "send", + ["0xe950c085", 1000], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockExpiration with no selector`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0x00000000", 0, 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockExpiration to with expiration over one month`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0xe950c085", 5443200, 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockExpiration to modify expiration under one minute`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0xd7ce3c6f", 30, 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockExpiration to set a timelock`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0xd7ce3c6f", 300000, 0] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockExpiration to set a timelock on another function`, + contract, + "initiateModifyTimelockExpiration", + "send", + ["0xe950c085", 30, 0] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockExpiration with no selector`, + contract, + "modifyTimelockExpiration", + "send", + ["0x00000000", 0], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockExpiration before timelock completion`, + contract, + "modifyTimelockExpiration", + "send", + ["0xd7ce3c6f", 300], + false + ); + + // advance time by 4 weeks + await tester.advanceTime(60 * 60 * 24 * 7 * 4 + 5); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call modifyTimelockInterval`, + contract, + "modifyTimelockInterval", + "send", + ["0xaaaaaaaa", 10000] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call modifyTimelockExpiration`, + contract, + "modifyTimelockExpiration", + "send", + ["0xd7ce3c6f", 300000] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockExpiration if expiration is too short`, + contract, + "modifyTimelockExpiration", + "send", + ["0xe950c085", 30], + false + ); +} - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockInterval to set a timelock`, +async function testUpgradeBeaconControllerManagerPartTwo( + tester, contract, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 10000, 5] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot shorten existing initiateModifyTimelockInterval timelock`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 10000, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockInterval to change a duration`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0xe950c085', 10001, 5] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockInterval to set a timelock on another function`, - contract, - 'initiateModifyTimelockInterval', - 'send', - ['0xaaaaaaaa', 10000, 0] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockInterval with no selector`, - contract, - 'modifyTimelockInterval', - 'send', - ['0x00000000', 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockInterval before timelock completion`, - contract, - 'modifyTimelockInterval', - 'send', - ['0xe950c085', 1000], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockExpiration with no selector`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0x00000000', 0, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockExpiration to with expiration over one month`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0xe950c085', 5443200, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call initiateModifyTimelockExpiration to modify expiration under one minute`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 30, 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockExpiration to set a timelock`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 300000, 0], - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call initiateModifyTimelockExpiration to set a timelock on another function`, - contract, - 'initiateModifyTimelockExpiration', - 'send', - ['0xe950c085', 30, 0] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockExpiration with no selector`, - contract, - 'modifyTimelockExpiration', - 'send', - ['0x00000000', 0], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockExpiration before timelock completion`, - contract, - 'modifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 300], - false - ) - - // advance time by 4 weeks - await tester.advanceTime((60 * 60 * 24 * 7 * 4) + 5) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call modifyTimelockInterval`, - contract, - 'modifyTimelockInterval', - 'send', - ['0xaaaaaaaa', 10000] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call modifyTimelockExpiration`, - contract, - 'modifyTimelockExpiration', - 'send', - ['0xd7ce3c6f', 300000], - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call modifyTimelockExpiration if expiration is too short`, - contract, - 'modifyTimelockExpiration', - 'send', - ['0xe950c085', 30], - false - ) -} - -async function testUpgradeBeaconControllerManagerPartTwo( - tester, - contract, - upgradeBeaconControllerContract, - keyRingUpgradeBeaconControllerContract, - upgradeBeaconAddress, - adharmaSmartWalletImplementationAddress, - smartWalletImplementationAddress, - keyRingImplementationAddress -) { - // Transfer smart wallet controller ownership to coverage manager - await tester.runTest( - `DharmaUpgradeBeaconController can transfer ownership to manager`, upgradeBeaconControllerContract, - 'transferOwnership', - 'send', - [contract.options.address] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when it doesn't own keyring controller`, - contract, - 'activateAdharmaContingency', - 'send', - [], - false - ) - - await tester.runTest( - `DharmaKeyRingUpgradeBeaconController can transfer ownership to manager`, keyRingUpgradeBeaconControllerContract, - 'transferOwnership', - 'send', - [contract.options.address] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can activate Adharma Contingency`, - contract, - 'activateAdharmaContingency' - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can get contingency status when activated`, - contract, - 'contingencyStatus', - 'call', - [], - true, - value => { - assert.ok(!value.armed) - assert.ok(value.activated) - //assert.strictEqual(value.activationTime, '?') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner can re-arm an active Adharma Contingency`, - contract, - 'armAdharmaContingency', - 'send', - [true] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when already active`, - contract, - 'activateAdharmaContingency', - 'send', - [], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager now gets a prior implementation count`, - contract, - 'getTotalPriorImplementations', - 'call', - [ - upgradeBeaconControllerContract.options.address, - upgradeBeaconAddress - ], - true, - value => { - assert.strictEqual(value, '1') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can get the initial prior implementation`, - contract, - 'getPriorImplementation', - 'call', - [ - upgradeBeaconControllerContract.options.address, - upgradeBeaconAddress, - 0 - ], - true, - value => { - assert.strictEqual( - value.priorImplementation, adharmaSmartWalletImplementationAddress - ) - assert.ok(value.rollbackAllowed) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call "exitAdharmaContingency" before 48 hours has elapsed`, - contract, - 'exitAdharmaContingency', - 'send', - [ - tester.address, - tester.address - ], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can rollback to initial prior implementation`, - contract, - 'rollback', - 'send', - [ - upgradeBeaconControllerContract.options.address, - upgradeBeaconAddress, - 0 - ] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager contingency status is exited after rollback`, - contract, - 'contingencyStatus', - 'call', - [], - true, - value => { - assert.ok(!value.armed) - assert.ok(!value.activated) - assert.strictEqual(value.activationTime, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot rollback to implementation with no index`, - contract, - 'rollback', - 'send', - [tester.address, tester.address, 100], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner can re-arm an Adharma Contingency`, - contract, - 'armAdharmaContingency', - 'send', - [true] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager contingency status shows armed`, - contract, - 'contingencyStatus', - 'call', - [], - true, - value => { - assert.ok(value.armed) - assert.ok(!value.activated) - assert.strictEqual(value.activationTime, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can rollback to initial prior implementation`, - contract, - 'rollback', - 'send', - [ - upgradeBeaconControllerContract.options.address, - upgradeBeaconAddress, - 0 - ] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager contingency status shows no longer armed`, - contract, - 'contingencyStatus', - 'call', - [], - true, - value => { - assert.ok(!value.armed) - assert.ok(!value.activated) - assert.strictEqual(value.activationTime, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can block rollback to prior implementation`, - contract, - 'blockRollback', - 'send', - [ - upgradeBeaconControllerContract.options.address, - upgradeBeaconAddress, - 0 - ] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot block a blocked rollback`, - contract, - 'blockRollback', - 'send', - [ - upgradeBeaconControllerContract.options.address, - upgradeBeaconAddress, - 0 - ], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot rollback to a blocked rollback`, - contract, - 'rollback', - 'send', - [ - upgradeBeaconControllerContract.options.address, - upgradeBeaconAddress, - 0 - ], - false - ) - - // advance time by 90 days - await tester.advanceTime((60 * 60 * 24 * 90) + 5) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager deadman switch can arm an Adharma Contingency`, - contract, - 'armAdharmaContingency', - 'send', - [true], - true, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager deadman switch can activate an Adharma Contingency`, - contract, - 'activateAdharmaContingency', - 'send', - [], - true, - receipt => {}, - tester.originalAddress - ) - - // advance time by 2 days - await tester.advanceTime((60 * 60 * 24 * 2) + 5) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call exitAdharmaContingency with null implementation`, - contract, - 'exitAdharmaContingency', - 'send', - [ - constants.NULL_ADDRESS, - tester.address - ], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager cannot call exitAdharmaContingency with non-contract implementation`, - contract, - 'exitAdharmaContingency', - 'send', - [ - tester.address, - tester.address - ], - false - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can call exitAdharmaContingency`, - contract, - 'exitAdharmaContingency', - 'send', - [ - smartWalletImplementationAddress, - keyRingImplementationAddress - ] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can have an EOA accept controller ownership`, - contract, - 'agreeToAcceptControllerOwnership', - 'send', - [ - upgradeBeaconControllerContract.options.address, - true - ] - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can initiate timelock for transferring controller ownership`, - contract, - 'initiateTransferControllerOwnership', - 'send', - [ - upgradeBeaconControllerContract.options.address, - tester.address, - 0 - ] - ) - - // advance time by 4 weeks - await tester.advanceTime((60 * 60 * 24 * 7 * 4) + 5) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager can transfer controller ownership`, - contract, - 'transferControllerOwnership', - 'send', - [ - upgradeBeaconControllerContract.options.address, - tester.address - ] - ) - - await tester.runTest( - `DharmaUpgradeBeaconController can get new owner`, - upgradeBeaconControllerContract, - 'isOwner', - 'call', - [], - true, - value => { - assert.ok(value) - } - ) + upgradeBeaconAddress, + adharmaSmartWalletImplementationAddress, + smartWalletImplementationAddress, + keyRingImplementationAddress +) { + // Transfer smart wallet controller ownership to coverage manager + await tester.runTest( + `DharmaUpgradeBeaconController can transfer ownership to manager`, + upgradeBeaconControllerContract, + "transferOwnership", + "send", + [contract.options.address] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when it doesn't own keyring controller`, + contract, + "activateAdharmaContingency", + "send", + [], + false + ); + + await tester.runTest( + `DharmaKeyRingUpgradeBeaconController can transfer ownership to manager`, + keyRingUpgradeBeaconControllerContract, + "transferOwnership", + "send", + [contract.options.address] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can activate Adharma Contingency`, + contract, + "activateAdharmaContingency" + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can get contingency status when activated`, + contract, + "contingencyStatus", + "call", + [], + true, + value => { + assert.ok(!value.armed); + assert.ok(value.activated); + //assert.strictEqual(value.activationTime, '?') + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner can re-arm an active Adharma Contingency`, + contract, + "armAdharmaContingency", + "send", + [true] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot activate Adharma Contingency when already active`, + contract, + "activateAdharmaContingency", + "send", + [], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager now gets a prior implementation count`, + contract, + "getTotalPriorImplementations", + "call", + [upgradeBeaconControllerContract.options.address, upgradeBeaconAddress], + true, + value => { + assert.strictEqual(value, "1"); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can get the initial prior implementation`, + contract, + "getPriorImplementation", + "call", + [ + upgradeBeaconControllerContract.options.address, + upgradeBeaconAddress, + 0 + ], + true, + value => { + assert.strictEqual( + value.priorImplementation, + adharmaSmartWalletImplementationAddress + ); + assert.ok(value.rollbackAllowed); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call "exitAdharmaContingency" before 48 hours has elapsed`, + contract, + "exitAdharmaContingency", + "send", + [tester.address, tester.address], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can rollback to initial prior implementation`, + contract, + "rollback", + "send", + [ + upgradeBeaconControllerContract.options.address, + upgradeBeaconAddress, + 0 + ] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager contingency status is exited after rollback`, + contract, + "contingencyStatus", + "call", + [], + true, + value => { + assert.ok(!value.armed); + assert.ok(!value.activated); + assert.strictEqual(value.activationTime, "0"); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot rollback to implementation with no index`, + contract, + "rollback", + "send", + [tester.address, tester.address, 100], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner can re-arm an Adharma Contingency`, + contract, + "armAdharmaContingency", + "send", + [true] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager contingency status shows armed`, + contract, + "contingencyStatus", + "call", + [], + true, + value => { + assert.ok(value.armed); + assert.ok(!value.activated); + assert.strictEqual(value.activationTime, "0"); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can rollback to initial prior implementation`, + contract, + "rollback", + "send", + [ + upgradeBeaconControllerContract.options.address, + upgradeBeaconAddress, + 0 + ] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager contingency status shows no longer armed`, + contract, + "contingencyStatus", + "call", + [], + true, + value => { + assert.ok(!value.armed); + assert.ok(!value.activated); + assert.strictEqual(value.activationTime, "0"); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can block rollback to prior implementation`, + contract, + "blockRollback", + "send", + [ + upgradeBeaconControllerContract.options.address, + upgradeBeaconAddress, + 0 + ] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot block a blocked rollback`, + contract, + "blockRollback", + "send", + [ + upgradeBeaconControllerContract.options.address, + upgradeBeaconAddress, + 0 + ], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot rollback to a blocked rollback`, + contract, + "rollback", + "send", + [ + upgradeBeaconControllerContract.options.address, + upgradeBeaconAddress, + 0 + ], + false + ); + + // advance time by 90 days + await tester.advanceTime(60 * 60 * 24 * 90 + 5); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager deadman switch can arm an Adharma Contingency`, + contract, + "armAdharmaContingency", + "send", + [true], + true, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager deadman switch can activate an Adharma Contingency`, + contract, + "activateAdharmaContingency", + "send", + [], + true, + receipt => {}, + tester.originalAddress + ); + + // advance time by 2 days + await tester.advanceTime(60 * 60 * 24 * 2 + 5); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call exitAdharmaContingency with null implementation`, + contract, + "exitAdharmaContingency", + "send", + [constants.NULL_ADDRESS, tester.address], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager cannot call exitAdharmaContingency with non-contract implementation`, + contract, + "exitAdharmaContingency", + "send", + [tester.address, tester.address], + false + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can call exitAdharmaContingency`, + contract, + "exitAdharmaContingency", + "send", + [smartWalletImplementationAddress, keyRingImplementationAddress] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can have an EOA accept controller ownership`, + contract, + "agreeToAcceptControllerOwnership", + "send", + [upgradeBeaconControllerContract.options.address, true] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can initiate timelock for transferring controller ownership`, + contract, + "initiateTransferControllerOwnership", + "send", + [upgradeBeaconControllerContract.options.address, tester.address, 0] + ); + + // advance time by 4 weeks + await tester.advanceTime(60 * 60 * 24 * 7 * 4 + 5); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager can transfer controller ownership`, + contract, + "transferControllerOwnership", + "send", + [upgradeBeaconControllerContract.options.address, tester.address] + ); + + await tester.runTest( + `DharmaUpgradeBeaconController can get new owner`, + upgradeBeaconControllerContract, + "isOwner", + "call", + [], + true, + value => { + assert.ok(value); + } + ); } module.exports = { testUpgradeBeaconControllerManagerPartOne, testUpgradeBeaconControllerManagerPartTwo -}; \ No newline at end of file +}; diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index b651129..c11c706 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -1,14 +1,28 @@ -var assert = require('assert') -var fs = require('fs') -var util = require('ethereumjs-util') -const constants = require('./constants.js') +var assert = require("assert"); +var fs = require("fs"); +var util = require("ethereumjs-util"); +const constants = require("./constants.js"); const { web3 } = require("./web3"); -const { Tester, swapMetadataHash, newContractAndSwapMetadataHash } = require("./testHelpers"); -const { testIndestructibleRegistry } = require("./contracts/indestructible-registry/testIndestructibleRegistry"); -const { testDharmaUpgradeMultisigDeployer } = require("./contracts/multisig-deployers/testDharmaUpgradeMultisigDeployer"); -const { testDharmaAccountRecoveryMultisigDeployer } = require("./contracts/multisig-deployers/testDharmaAccountRecoveryMultisigDeployer"); -const { testDharmaAccountRecoveryOperatorMultisigDeployer } = require("./contracts/multisig-deployers/testDharmaAccountRecoveryOperatorMultisigDeployer"); -const { testDharmaKeyRegistryMultisigDeployer } = require("./contracts/multisig-deployers/testDharmaKeyRegistryMultisigDeployer"); +const { + Tester, + swapMetadataHash, + newContractAndSwapMetadataHash +} = require("./testHelpers"); +const { + testIndestructibleRegistry +} = require("./contracts/indestructible-registry/testIndestructibleRegistry"); +const { + testDharmaUpgradeMultisigDeployer +} = require("./contracts/multisig-deployers/testDharmaUpgradeMultisigDeployer"); +const { + testDharmaAccountRecoveryMultisigDeployer +} = require("./contracts/multisig-deployers/testDharmaAccountRecoveryMultisigDeployer"); +const { + testDharmaAccountRecoveryOperatorMultisigDeployer +} = require("./contracts/multisig-deployers/testDharmaAccountRecoveryOperatorMultisigDeployer"); +const { + testDharmaKeyRegistryMultisigDeployer +} = require("./contracts/multisig-deployers/testDharmaKeyRegistryMultisigDeployer"); let DharmaUpgradeBeaconArtifact; let DharmaUpgradeBeaconControllerArtifact; @@ -33,17 +47,17 @@ let DharmaUSDCArtifact; let SmartWalletRevertReasonHelperV1Artifact; -const DharmaDaiInitializerArtifact = require('../../build/contracts/DharmaDaiInitializer.json') -const DharmaDaiImplementationV1Artifact = require('../../build/contracts/MockDharmaDaiImplementationV1.json') +const DharmaDaiInitializerArtifact = require("../../build/contracts/DharmaDaiInitializer.json"); +const DharmaDaiImplementationV1Artifact = require("../../build/contracts/MockDharmaDaiImplementationV1.json"); -const DharmaUSDCInitializerArtifact = require('../../build/contracts/DharmaUSDCInitializer.json') -const DharmaUSDCImplementationV1Artifact = require('../../build/contracts/DharmaUSDCImplementationV1.json') +const DharmaUSDCInitializerArtifact = require("../../build/contracts/DharmaUSDCInitializer.json"); +const DharmaUSDCImplementationV1Artifact = require("../../build/contracts/DharmaUSDCImplementationV1.json"); -const DharmaUpgradeMultisigArtifact = require('../../build/contracts/DharmaUpgradeMultisig.json') -const DharmaAccountRecoveryMultisigArtifact = require('../../build/contracts/DharmaAccountRecoveryMultisig.json') -const DharmaAccountRecoveryOperatorMultisigArtifact = require('../../build/contracts/DharmaAccountRecoveryOperatorMultisig.json') -const DharmaKeyRegistryMultisigArtifact = require('../../build/contracts/DharmaKeyRegistryMultisig.json') -const DharmaTestingMultisigArtifact = require('../../build/contracts/DharmaTestingMultisig.json') +const DharmaUpgradeMultisigArtifact = require("../../build/contracts/DharmaUpgradeMultisig.json"); +const DharmaAccountRecoveryMultisigArtifact = require("../../build/contracts/DharmaAccountRecoveryMultisig.json"); +const DharmaAccountRecoveryOperatorMultisigArtifact = require("../../build/contracts/DharmaAccountRecoveryOperatorMultisig.json"); +const DharmaKeyRegistryMultisigArtifact = require("../../build/contracts/DharmaKeyRegistryMultisig.json"); +const DharmaTestingMultisigArtifact = require("../../build/contracts/DharmaTestingMultisig.json"); //const DharmaSmartWalletImplementationV0Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV0.json') //const DharmaSmartWalletImplementationV1Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV1.json') @@ -51,74 +65,74 @@ const DharmaTestingMultisigArtifact = require('../../build/contracts/DharmaTesti //const DharmaSmartWalletImplementationV3Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV3.json') //const DharmaSmartWalletImplementationV4Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV4.json') //const DharmaSmartWalletImplementationV5Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV5.json') -const DharmaSmartWalletImplementationV6Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV6.json') -const DharmaSmartWalletImplementationV7Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV7.json') +const DharmaSmartWalletImplementationV6Artifact = require("../../build/contracts/DharmaSmartWalletImplementationV6.json"); +const DharmaSmartWalletImplementationV7Artifact = require("../../build/contracts/DharmaSmartWalletImplementationV7.json"); //const DharmaKeyRingImplementationV0Artifact = require('../../build/contracts/DharmaKeyRingImplementationV0.json') -const DharmaKeyRingImplementationV1Artifact = require('../../build/contracts/DharmaKeyRingImplementationV1.json') +const DharmaKeyRingImplementationV1Artifact = require("../../build/contracts/DharmaKeyRingImplementationV1.json"); //const DharmaKeyRingImplementationV2Artifact = require('../../build/contracts/DharmaKeyRingImplementationV2.json') -const UpgradeBeaconImplementationCheckArtifact = require('../../build/contracts/UpgradeBeaconImplementationCheck.json') -const BadBeaconArtifact = require('../../build/contracts/BadBeacon.json') -const BadBeaconTwoArtifact = require('../../build/contracts/BadBeaconTwo.json') -const MockCodeCheckArtifact = require('../../build/contracts/MockCodeCheck.json') -const IERC20Artifact = require('../../build/contracts/IERC20.json') +const UpgradeBeaconImplementationCheckArtifact = require("../../build/contracts/UpgradeBeaconImplementationCheck.json"); +const BadBeaconArtifact = require("../../build/contracts/BadBeacon.json"); +const BadBeaconTwoArtifact = require("../../build/contracts/BadBeaconTwo.json"); +const MockCodeCheckArtifact = require("../../build/contracts/MockCodeCheck.json"); +const IERC20Artifact = require("../../build/contracts/IERC20.json"); -const DharmaUpgradeBeaconControllerCoverageArtifact = require('../../build/contracts/DharmaUpgradeBeaconController.json') -const DharmaUpgradeBeaconControllerManagerCoverageArtifact = require('../../build/contracts/DharmaUpgradeBeaconControllerManager.json') +const DharmaUpgradeBeaconControllerCoverageArtifact = require("../../build/contracts/DharmaUpgradeBeaconController.json"); +const DharmaUpgradeBeaconControllerManagerCoverageArtifact = require("../../build/contracts/DharmaUpgradeBeaconControllerManager.json"); -const ImmutableCreate2FactoryArtifact = require('../../build/contracts/ImmutableCreate2Factory.json') -const IndestructibleRegistryArtifact = require('../../build/contracts/IndestructibleRegistry.json') -const CodeHashCacheArtifact = require('../../build/contracts/CodeHashCache.json') +const ImmutableCreate2FactoryArtifact = require("../../build/contracts/ImmutableCreate2Factory.json"); +const IndestructibleRegistryArtifact = require("../../build/contracts/IndestructibleRegistry.json"); +const CodeHashCacheArtifact = require("../../build/contracts/CodeHashCache.json"); async function test(testingContext) { - if (testingContext === 'coverage') { - DharmaUpgradeBeaconEnvoyArtifact = require('../../../build/contracts/DharmaUpgradeBeaconEnvoy.json') - DharmaUpgradeBeaconControllerArtifact = require('../../../build/contracts/DharmaUpgradeBeaconController.json') - DharmaUpgradeBeaconArtifact = require('../../../build/contracts/DharmaUpgradeBeacon.json') - DharmaKeyRingUpgradeBeaconArtifact = require('../../../build/contracts/DharmaKeyRingUpgradeBeacon.json') - DharmaDaiUpgradeBeaconArtifact = require('../../../build/contracts/DharmaDaiUpgradeBeacon.json') - DharmaUSDCUpgradeBeaconArtifact = require('../../../build/contracts/DharmaUSDCUpgradeBeacon.json') - //DharmaKeyRegistryV1Artifact = require('../../../build/contracts/DharmaKeyRegistryV1.json') - DharmaKeyRegistryV2Artifact = require('../../../build/contracts/DharmaKeyRegistryV2.json') - DharmaSmartWalletFactoryV1Artifact = require('../../../build/contracts/DharmaSmartWalletFactoryV1.json') - DharmaKeyRingFactoryV2Artifact = require('../../../build/contracts/DharmaKeyRingFactoryV2.json') - UpgradeBeaconProxyV1Artifact = require('../../../build/contracts/UpgradeBeaconProxyV1.json') - DharmaAccountRecoveryManagerV2Artifact = require('../../../build/contracts/DharmaAccountRecoveryManagerV2.json') - AdharmaSmartWalletImplementationArtifact = require('../../../build/contracts/AdharmaSmartWalletImplementation.json') - AdharmaKeyRingImplementationArtifact = require('../../../build/contracts/AdharmaKeyRingImplementation.json') - DharmaUpgradeBeaconControllerManagerArtifact = require('../../../build/contracts/DharmaUpgradeBeaconControllerManager.json') - DharmaEscapeHatchRegistryArtifact = require('../../../build/contracts/DharmaEscapeHatchRegistry.json') - DharmaDaiUpgradeBeaconArtifact = require('../../../build/contracts/DharmaDaiUpgradeBeacon.json') - DharmaDaiArtifact = require('../../../build/contracts/DharmaDai.json') - DharmaUSDCUpgradeBeaconArtifact = require('../../../build/contracts/DharmaUSDCUpgradeBeacon.json') - DharmaUSDCArtifact = require('../../../build/contracts/DharmaUSDC.json') - SmartWalletRevertReasonHelperV1Artifact = require('../../../build/contracts/SmartWalletRevertReasonHelperV1.json') - } else { - DharmaUpgradeBeaconEnvoyArtifact = require('../../build/contracts/DharmaUpgradeBeaconEnvoy.json') - DharmaUpgradeBeaconControllerArtifact = require('../../build/contracts/DharmaUpgradeBeaconController.json') - DharmaUpgradeBeaconArtifact = require('../../build/contracts/DharmaUpgradeBeacon.json') - DharmaKeyRingUpgradeBeaconArtifact = require('../../build/contracts/DharmaKeyRingUpgradeBeacon.json') - DharmaDaiUpgradeBeaconArtifact = require('../../build/contracts/DharmaDaiUpgradeBeacon.json') - DharmaUSDCUpgradeBeaconArtifact = require('../../build/contracts/DharmaUSDCUpgradeBeacon.json') - //DharmaKeyRegistryV1Artifact = require('../../build/contracts/DharmaKeyRegistryV1.json') - DharmaKeyRegistryV2Artifact = require('../../build/contracts/DharmaKeyRegistryV2.json') - DharmaSmartWalletFactoryV1Artifact = require('../../build/contracts/DharmaSmartWalletFactoryV1.json') - DharmaKeyRingFactoryV2Artifact = require('../../build/contracts/DharmaKeyRingFactoryV2.json') - UpgradeBeaconProxyV1Artifact = require('../../build/contracts/UpgradeBeaconProxyV1.json') - DharmaAccountRecoveryManagerV2Artifact = require('../../build/contracts/DharmaAccountRecoveryManagerV2.json') - AdharmaSmartWalletImplementationArtifact = require('../../build/contracts/AdharmaSmartWalletImplementation.json') - AdharmaKeyRingImplementationArtifact = require('../../build/contracts/AdharmaKeyRingImplementation.json') - DharmaUpgradeBeaconControllerManagerArtifact = require('../../build/contracts/DharmaUpgradeBeaconControllerManager.json') - DharmaEscapeHatchRegistryArtifact = require('../../build/contracts/DharmaEscapeHatchRegistry.json') - DharmaDaiUpgradeBeaconArtifact = require('../../build/contracts/DharmaDaiUpgradeBeacon.json') - DharmaDaiArtifact = require('../../build/contracts/DharmaDai.json') - DharmaUSDCUpgradeBeaconArtifact = require('../../build/contracts/DharmaUSDCUpgradeBeacon.json') - DharmaUSDCArtifact = require('../../build/contracts/DharmaUSDC.json') - SmartWalletRevertReasonHelperV1Artifact = require('../../build/contracts/SmartWalletRevertReasonHelperV1.json') - } - - /* + if (testingContext === "coverage") { + DharmaUpgradeBeaconEnvoyArtifact = require("../../../build/contracts/DharmaUpgradeBeaconEnvoy.json"); + DharmaUpgradeBeaconControllerArtifact = require("../../../build/contracts/DharmaUpgradeBeaconController.json"); + DharmaUpgradeBeaconArtifact = require("../../../build/contracts/DharmaUpgradeBeacon.json"); + DharmaKeyRingUpgradeBeaconArtifact = require("../../../build/contracts/DharmaKeyRingUpgradeBeacon.json"); + DharmaDaiUpgradeBeaconArtifact = require("../../../build/contracts/DharmaDaiUpgradeBeacon.json"); + DharmaUSDCUpgradeBeaconArtifact = require("../../../build/contracts/DharmaUSDCUpgradeBeacon.json"); + //DharmaKeyRegistryV1Artifact = require('../../../build/contracts/DharmaKeyRegistryV1.json') + DharmaKeyRegistryV2Artifact = require("../../../build/contracts/DharmaKeyRegistryV2.json"); + DharmaSmartWalletFactoryV1Artifact = require("../../../build/contracts/DharmaSmartWalletFactoryV1.json"); + DharmaKeyRingFactoryV2Artifact = require("../../../build/contracts/DharmaKeyRingFactoryV2.json"); + UpgradeBeaconProxyV1Artifact = require("../../../build/contracts/UpgradeBeaconProxyV1.json"); + DharmaAccountRecoveryManagerV2Artifact = require("../../../build/contracts/DharmaAccountRecoveryManagerV2.json"); + AdharmaSmartWalletImplementationArtifact = require("../../../build/contracts/AdharmaSmartWalletImplementation.json"); + AdharmaKeyRingImplementationArtifact = require("../../../build/contracts/AdharmaKeyRingImplementation.json"); + DharmaUpgradeBeaconControllerManagerArtifact = require("../../../build/contracts/DharmaUpgradeBeaconControllerManager.json"); + DharmaEscapeHatchRegistryArtifact = require("../../../build/contracts/DharmaEscapeHatchRegistry.json"); + DharmaDaiUpgradeBeaconArtifact = require("../../../build/contracts/DharmaDaiUpgradeBeacon.json"); + DharmaDaiArtifact = require("../../../build/contracts/DharmaDai.json"); + DharmaUSDCUpgradeBeaconArtifact = require("../../../build/contracts/DharmaUSDCUpgradeBeacon.json"); + DharmaUSDCArtifact = require("../../../build/contracts/DharmaUSDC.json"); + SmartWalletRevertReasonHelperV1Artifact = require("../../../build/contracts/SmartWalletRevertReasonHelperV1.json"); + } else { + DharmaUpgradeBeaconEnvoyArtifact = require("../../build/contracts/DharmaUpgradeBeaconEnvoy.json"); + DharmaUpgradeBeaconControllerArtifact = require("../../build/contracts/DharmaUpgradeBeaconController.json"); + DharmaUpgradeBeaconArtifact = require("../../build/contracts/DharmaUpgradeBeacon.json"); + DharmaKeyRingUpgradeBeaconArtifact = require("../../build/contracts/DharmaKeyRingUpgradeBeacon.json"); + DharmaDaiUpgradeBeaconArtifact = require("../../build/contracts/DharmaDaiUpgradeBeacon.json"); + DharmaUSDCUpgradeBeaconArtifact = require("../../build/contracts/DharmaUSDCUpgradeBeacon.json"); + //DharmaKeyRegistryV1Artifact = require('../../build/contracts/DharmaKeyRegistryV1.json') + DharmaKeyRegistryV2Artifact = require("../../build/contracts/DharmaKeyRegistryV2.json"); + DharmaSmartWalletFactoryV1Artifact = require("../../build/contracts/DharmaSmartWalletFactoryV1.json"); + DharmaKeyRingFactoryV2Artifact = require("../../build/contracts/DharmaKeyRingFactoryV2.json"); + UpgradeBeaconProxyV1Artifact = require("../../build/contracts/UpgradeBeaconProxyV1.json"); + DharmaAccountRecoveryManagerV2Artifact = require("../../build/contracts/DharmaAccountRecoveryManagerV2.json"); + AdharmaSmartWalletImplementationArtifact = require("../../build/contracts/AdharmaSmartWalletImplementation.json"); + AdharmaKeyRingImplementationArtifact = require("../../build/contracts/AdharmaKeyRingImplementation.json"); + DharmaUpgradeBeaconControllerManagerArtifact = require("../../build/contracts/DharmaUpgradeBeaconControllerManager.json"); + DharmaEscapeHatchRegistryArtifact = require("../../build/contracts/DharmaEscapeHatchRegistry.json"); + DharmaDaiUpgradeBeaconArtifact = require("../../build/contracts/DharmaDaiUpgradeBeacon.json"); + DharmaDaiArtifact = require("../../build/contracts/DharmaDai.json"); + DharmaUSDCUpgradeBeaconArtifact = require("../../build/contracts/DharmaUSDCUpgradeBeacon.json"); + DharmaUSDCArtifact = require("../../build/contracts/DharmaUSDC.json"); + SmartWalletRevertReasonHelperV1Artifact = require("../../build/contracts/SmartWalletRevertReasonHelperV1.json"); + } + + /* console.log( swapMetadataHash( DharmaSmartWalletImplementationV7Artifact.bytecode, @@ -132,183 +146,173 @@ async function test(testingContext) { process.exit(0) */ - const DharmaUpgradeBeaconController = new web3.eth.Contract( - DharmaUpgradeBeaconControllerArtifact.abi, - constants.UPGRADE_BEACON_CONTROLLER_ADDRESS - ) + const DharmaUpgradeBeaconController = new web3.eth.Contract( + DharmaUpgradeBeaconControllerArtifact.abi, + constants.UPGRADE_BEACON_CONTROLLER_ADDRESS + ); - const DharmaUpgradeBeacon = new web3.eth.Contract( - DharmaUpgradeBeaconArtifact.abi, - constants.UPGRADE_BEACON_ADDRESS - ) + const DharmaUpgradeBeacon = new web3.eth.Contract( + DharmaUpgradeBeaconArtifact.abi, + constants.UPGRADE_BEACON_ADDRESS + ); - const DharmaKeyRingUpgradeBeaconController = new web3.eth.Contract( - DharmaUpgradeBeaconControllerArtifact.abi, - constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS - ) + const DharmaKeyRingUpgradeBeaconController = new web3.eth.Contract( + DharmaUpgradeBeaconControllerArtifact.abi, + constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS + ); - const DharmaKeyRingUpgradeBeacon = new web3.eth.Contract( - DharmaKeyRingUpgradeBeaconArtifact.abi, - constants.KEY_RING_UPGRADE_BEACON_ADDRESS - ) + const DharmaKeyRingUpgradeBeacon = new web3.eth.Contract( + DharmaKeyRingUpgradeBeaconArtifact.abi, + constants.KEY_RING_UPGRADE_BEACON_ADDRESS + ); - const DharmaAccountRecoveryManagerV2 = new web3.eth.Contract( - DharmaAccountRecoveryManagerV2Artifact.abi, - constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS - ) + const DharmaAccountRecoveryManagerV2 = new web3.eth.Contract( + DharmaAccountRecoveryManagerV2Artifact.abi, + constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS + ); - /* + /* const DharmaKeyRegistryV1 = new web3.eth.Contract( DharmaKeyRegistryV1Artifact.abi, constants.KEY_REGISTRY_ADDRESS ) */ - const DharmaKeyRegistryV2 = new web3.eth.Contract( - DharmaKeyRegistryV2Artifact.abi, - constants.KEY_REGISTRY_V2_ADDRESS - ) + const DharmaKeyRegistryV2 = new web3.eth.Contract( + DharmaKeyRegistryV2Artifact.abi, + constants.KEY_REGISTRY_V2_ADDRESS + ); - const DharmaEscapeHatchRegistry = new web3.eth.Contract( - DharmaEscapeHatchRegistryArtifact.abi, - constants.ESCAPE_HATCH_REGISTRY_ADDRESS - ) + const DharmaEscapeHatchRegistry = new web3.eth.Contract( + DharmaEscapeHatchRegistryArtifact.abi, + constants.ESCAPE_HATCH_REGISTRY_ADDRESS + ); - const DharmaSmartWalletFactoryV1 = new web3.eth.Contract( - DharmaSmartWalletFactoryV1Artifact.abi, - constants.FACTORY_ADDRESS - ) + const DharmaSmartWalletFactoryV1 = new web3.eth.Contract( + DharmaSmartWalletFactoryV1Artifact.abi, + constants.FACTORY_ADDRESS + ); - const DharmaKeyRingFactoryV2 = new web3.eth.Contract( - DharmaKeyRingFactoryV2Artifact.abi, - constants.KEY_RING_FACTORY_V2_ADDRESS - ) + const DharmaKeyRingFactoryV2 = new web3.eth.Contract( + DharmaKeyRingFactoryV2Artifact.abi, + constants.KEY_RING_FACTORY_V2_ADDRESS + ); - const ActualIndestructibleRegistry = new web3.eth.Contract( - IndestructibleRegistryArtifact.abi, - constants.INDESTRUCTIBLE_REGISTRY_ADDRESS - ) + const ActualIndestructibleRegistry = new web3.eth.Contract( + IndestructibleRegistryArtifact.abi, + constants.INDESTRUCTIBLE_REGISTRY_ADDRESS + ); - const DharmaDaiUpgradeBeaconController = new web3.eth.Contract( - DharmaUpgradeBeaconControllerArtifact.abi, - constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_ADDRESS - ) + const DharmaDaiUpgradeBeaconController = new web3.eth.Contract( + DharmaUpgradeBeaconControllerArtifact.abi, + constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_ADDRESS + ); - const DharmaUSDCUpgradeBeaconController = new web3.eth.Contract( - DharmaUpgradeBeaconControllerArtifact.abi, - constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_ADDRESS - ) + const DharmaUSDCUpgradeBeaconController = new web3.eth.Contract( + DharmaUpgradeBeaconControllerArtifact.abi, + constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_ADDRESS + ); - const DharmaDaiInitializer = new web3.eth.Contract( - DharmaDaiInitializerArtifact.abi, - constants.DHARMA_DAI_ADDRESS - ) + const DharmaDaiInitializer = new web3.eth.Contract( + DharmaDaiInitializerArtifact.abi, + constants.DHARMA_DAI_ADDRESS + ); - const DharmaUSDCInitializer = new web3.eth.Contract( - DharmaUSDCInitializerArtifact.abi, - constants.DHARMA_USDC_ADDRESS - ) + const DharmaUSDCInitializer = new web3.eth.Contract( + DharmaUSDCInitializerArtifact.abi, + constants.DHARMA_USDC_ADDRESS + ); - const SmartWalletRevertReasonHelperV1 = new web3.eth.Contract( - SmartWalletRevertReasonHelperV1Artifact.abi, - constants.REVERT_REASON_HELPER_ADDRESS - ) + const SmartWalletRevertReasonHelperV1 = new web3.eth.Contract( + SmartWalletRevertReasonHelperV1Artifact.abi, + constants.REVERT_REASON_HELPER_ADDRESS + ); - const CodeHashCacheDeployer = newContractAndSwapMetadataHash( - CodeHashCacheArtifact - ); + const CodeHashCacheDeployer = newContractAndSwapMetadataHash( + CodeHashCacheArtifact + ); - const DharmaUpgradeMultisigDeployer = new web3.eth.Contract( - DharmaUpgradeMultisigArtifact.abi - ) - DharmaUpgradeMultisigDeployer.options.data = ( - DharmaUpgradeMultisigArtifact.bytecode - ) + const DharmaUpgradeMultisigDeployer = new web3.eth.Contract( + DharmaUpgradeMultisigArtifact.abi + ); + DharmaUpgradeMultisigDeployer.options.data = + DharmaUpgradeMultisigArtifact.bytecode; - const DharmaAccountRecoveryMultisigDeployer = new web3.eth.Contract( - DharmaAccountRecoveryMultisigArtifact.abi - ) - DharmaAccountRecoveryMultisigDeployer.options.data = ( - DharmaAccountRecoveryMultisigArtifact.bytecode - ) + const DharmaAccountRecoveryMultisigDeployer = new web3.eth.Contract( + DharmaAccountRecoveryMultisigArtifact.abi + ); + DharmaAccountRecoveryMultisigDeployer.options.data = + DharmaAccountRecoveryMultisigArtifact.bytecode; - const DharmaAccountRecoveryOperatorMultisigDeployer = new web3.eth.Contract( - DharmaAccountRecoveryOperatorMultisigArtifact.abi - ) - DharmaAccountRecoveryOperatorMultisigDeployer.options.data = ( - DharmaAccountRecoveryOperatorMultisigArtifact.bytecode - ) + const DharmaAccountRecoveryOperatorMultisigDeployer = new web3.eth.Contract( + DharmaAccountRecoveryOperatorMultisigArtifact.abi + ); + DharmaAccountRecoveryOperatorMultisigDeployer.options.data = + DharmaAccountRecoveryOperatorMultisigArtifact.bytecode; - const DharmaKeyRegistryMultisigDeployer = new web3.eth.Contract( - DharmaKeyRegistryMultisigArtifact.abi - ) - DharmaKeyRegistryMultisigDeployer.options.data = ( - DharmaKeyRegistryMultisigArtifact.bytecode - ) + const DharmaKeyRegistryMultisigDeployer = new web3.eth.Contract( + DharmaKeyRegistryMultisigArtifact.abi + ); + DharmaKeyRegistryMultisigDeployer.options.data = + DharmaKeyRegistryMultisigArtifact.bytecode; - const DharmaTestingMultisigDeployer = new web3.eth.Contract( - DharmaTestingMultisigArtifact.abi - ) - DharmaTestingMultisigDeployer.options.data = ( - DharmaTestingMultisigArtifact.bytecode - ) + const DharmaTestingMultisigDeployer = new web3.eth.Contract( + DharmaTestingMultisigArtifact.abi + ); + DharmaTestingMultisigDeployer.options.data = + DharmaTestingMultisigArtifact.bytecode; - const DharmaUpgradeBeaconControllerDeployer = new web3.eth.Contract( - DharmaUpgradeBeaconControllerArtifact.abi - ) - DharmaUpgradeBeaconControllerDeployer.options.data = ( - DharmaUpgradeBeaconControllerArtifact.bytecode - ) + const DharmaUpgradeBeaconControllerDeployer = new web3.eth.Contract( + DharmaUpgradeBeaconControllerArtifact.abi + ); + DharmaUpgradeBeaconControllerDeployer.options.data = + DharmaUpgradeBeaconControllerArtifact.bytecode; - const DharmaUpgradeBeaconControllerCoverageDeployer = new web3.eth.Contract( - DharmaUpgradeBeaconControllerCoverageArtifact.abi - ) - DharmaUpgradeBeaconControllerCoverageDeployer.options.data = ( - DharmaUpgradeBeaconControllerCoverageArtifact.bytecode - ) + const DharmaUpgradeBeaconControllerCoverageDeployer = new web3.eth.Contract( + DharmaUpgradeBeaconControllerCoverageArtifact.abi + ); + DharmaUpgradeBeaconControllerCoverageDeployer.options.data = + DharmaUpgradeBeaconControllerCoverageArtifact.bytecode; - const DharmaUpgradeBeaconControllerManagerDeployer = new web3.eth.Contract( - DharmaUpgradeBeaconControllerManagerArtifact.abi - ) - DharmaUpgradeBeaconControllerManagerDeployer.options.data = ( - DharmaUpgradeBeaconControllerManagerArtifact.bytecode - ) + const DharmaUpgradeBeaconControllerManagerDeployer = new web3.eth.Contract( + DharmaUpgradeBeaconControllerManagerArtifact.abi + ); + DharmaUpgradeBeaconControllerManagerDeployer.options.data = + DharmaUpgradeBeaconControllerManagerArtifact.bytecode; - const DharmaUpgradeBeaconControllerManagerCoverageDeployer = new web3.eth.Contract( - DharmaUpgradeBeaconControllerManagerCoverageArtifact.abi - ) - DharmaUpgradeBeaconControllerManagerCoverageDeployer.options.data = ( - DharmaUpgradeBeaconControllerManagerCoverageArtifact.bytecode - ) + const DharmaUpgradeBeaconControllerManagerCoverageDeployer = new web3.eth.Contract( + DharmaUpgradeBeaconControllerManagerCoverageArtifact.abi + ); + DharmaUpgradeBeaconControllerManagerCoverageDeployer.options.data = + DharmaUpgradeBeaconControllerManagerCoverageArtifact.bytecode; - const DharmaUpgradeBeaconDeployer = new web3.eth.Contract( - DharmaUpgradeBeaconArtifact.abi - ) - DharmaUpgradeBeaconDeployer.options.data = ( - DharmaUpgradeBeaconArtifact.bytecode - ) + const DharmaUpgradeBeaconDeployer = new web3.eth.Contract( + DharmaUpgradeBeaconArtifact.abi + ); + DharmaUpgradeBeaconDeployer.options.data = + DharmaUpgradeBeaconArtifact.bytecode; - const DharmaKeyRingUpgradeBeaconDeployer = new web3.eth.Contract( - DharmaKeyRingUpgradeBeaconArtifact.abi - ) - DharmaKeyRingUpgradeBeaconDeployer.options.data = ( - DharmaKeyRingUpgradeBeaconArtifact.bytecode - ) + const DharmaKeyRingUpgradeBeaconDeployer = new web3.eth.Contract( + DharmaKeyRingUpgradeBeaconArtifact.abi + ); + DharmaKeyRingUpgradeBeaconDeployer.options.data = + DharmaKeyRingUpgradeBeaconArtifact.bytecode; - const BadBeaconDeployer = new web3.eth.Contract(BadBeaconArtifact.abi) - BadBeaconDeployer.options.data = BadBeaconArtifact.bytecode + const BadBeaconDeployer = new web3.eth.Contract(BadBeaconArtifact.abi); + BadBeaconDeployer.options.data = BadBeaconArtifact.bytecode; - const BadBeaconTwoDeployer = new web3.eth.Contract(BadBeaconTwoArtifact.abi) - BadBeaconTwoDeployer.options.data = BadBeaconTwoArtifact.bytecode + const BadBeaconTwoDeployer = new web3.eth.Contract( + BadBeaconTwoArtifact.abi + ); + BadBeaconTwoDeployer.options.data = BadBeaconTwoArtifact.bytecode; - const UpgradeBeaconProxyV1Deployer = new web3.eth.Contract( - UpgradeBeaconProxyV1Artifact.abi - ) - UpgradeBeaconProxyV1Deployer.options.data = ( - UpgradeBeaconProxyV1Artifact.bytecode - ) + const UpgradeBeaconProxyV1Deployer = new web3.eth.Contract( + UpgradeBeaconProxyV1Artifact.abi + ); + UpgradeBeaconProxyV1Deployer.options.data = + UpgradeBeaconProxyV1Artifact.bytecode; - /* + /* const DharmaKeyRegistryV1Deployer = new web3.eth.Contract( DharmaKeyRegistryV1Artifact.abi ) @@ -317,40 +321,37 @@ async function test(testingContext) { ) */ - const DharmaKeyRegistryV2Deployer = new web3.eth.Contract( - DharmaKeyRegistryV2Artifact.abi - ) - DharmaKeyRegistryV2Deployer.options.data = ( - DharmaKeyRegistryV2Artifact.bytecode - ) + const DharmaKeyRegistryV2Deployer = new web3.eth.Contract( + DharmaKeyRegistryV2Artifact.abi + ); + DharmaKeyRegistryV2Deployer.options.data = + DharmaKeyRegistryV2Artifact.bytecode; - const DharmaSmartWalletFactoryV1Deployer = new web3.eth.Contract( - DharmaSmartWalletFactoryV1Artifact.abi - ) - DharmaSmartWalletFactoryV1Deployer.options.data = ( - DharmaSmartWalletFactoryV1Artifact.bytecode - ) + const DharmaSmartWalletFactoryV1Deployer = new web3.eth.Contract( + DharmaSmartWalletFactoryV1Artifact.abi + ); + DharmaSmartWalletFactoryV1Deployer.options.data = + DharmaSmartWalletFactoryV1Artifact.bytecode; - const DharmaKeyRingFactoryV2Deployer = new web3.eth.Contract( - DharmaKeyRingFactoryV2Artifact.abi - ) - DharmaKeyRingFactoryV2Deployer.options.data = ( - DharmaKeyRingFactoryV2Artifact.bytecode - ) + const DharmaKeyRingFactoryV2Deployer = new web3.eth.Contract( + DharmaKeyRingFactoryV2Artifact.abi + ); + DharmaKeyRingFactoryV2Deployer.options.data = + DharmaKeyRingFactoryV2Artifact.bytecode; - const AdharmaSmartWalletImplementationDeployer = newContractAndSwapMetadataHash( - AdharmaSmartWalletImplementationArtifact - ); + const AdharmaSmartWalletImplementationDeployer = newContractAndSwapMetadataHash( + AdharmaSmartWalletImplementationArtifact + ); - const AdharmaKeyRingImplementationDeployer = newContractAndSwapMetadataHash( - AdharmaKeyRingImplementationArtifact - ); + const AdharmaKeyRingImplementationDeployer = newContractAndSwapMetadataHash( + AdharmaKeyRingImplementationArtifact + ); - const DharmaAccountRecoveryManagerV2Deployer = newContractAndSwapMetadataHash( - DharmaAccountRecoveryManagerV2Artifact - ); + const DharmaAccountRecoveryManagerV2Deployer = newContractAndSwapMetadataHash( + DharmaAccountRecoveryManagerV2Artifact + ); - /* + /* const DharmaSmartWalletImplementationV0Deployer = newContractAndSwapMetadataHash( DharmaSmartWalletImplementationV0Artifact ); @@ -388,43 +389,39 @@ async function test(testingContext) { ); */ - const DharmaSmartWalletImplementationV6Deployer = newContractAndSwapMetadataHash( - DharmaSmartWalletImplementationV6Artifact - ); + const DharmaSmartWalletImplementationV6Deployer = newContractAndSwapMetadataHash( + DharmaSmartWalletImplementationV6Artifact + ); - const DharmaSmartWalletImplementationV7Deployer = newContractAndSwapMetadataHash( - DharmaSmartWalletImplementationV7Artifact - ); + const DharmaSmartWalletImplementationV7Deployer = newContractAndSwapMetadataHash( + DharmaSmartWalletImplementationV7Artifact + ); - const DharmaDaiInitializerDeployer = new web3.eth.Contract( - DharmaDaiInitializerArtifact.abi - ) - DharmaDaiInitializerDeployer.options.data = ( - DharmaDaiInitializerArtifact.bytecode - ) + const DharmaDaiInitializerDeployer = new web3.eth.Contract( + DharmaDaiInitializerArtifact.abi + ); + DharmaDaiInitializerDeployer.options.data = + DharmaDaiInitializerArtifact.bytecode; - const DharmaDaiImplementationV1Deployer = new web3.eth.Contract( - DharmaDaiImplementationV1Artifact.abi - ) - DharmaDaiImplementationV1Deployer.options.data = ( - DharmaDaiImplementationV1Artifact.bytecode - ) + const DharmaDaiImplementationV1Deployer = new web3.eth.Contract( + DharmaDaiImplementationV1Artifact.abi + ); + DharmaDaiImplementationV1Deployer.options.data = + DharmaDaiImplementationV1Artifact.bytecode; - const DharmaUSDCInitializerDeployer = new web3.eth.Contract( - DharmaUSDCInitializerArtifact.abi - ) - DharmaUSDCInitializerDeployer.options.data = ( - DharmaUSDCInitializerArtifact.bytecode - ) + const DharmaUSDCInitializerDeployer = new web3.eth.Contract( + DharmaUSDCInitializerArtifact.abi + ); + DharmaUSDCInitializerDeployer.options.data = + DharmaUSDCInitializerArtifact.bytecode; - const DharmaUSDCImplementationV1Deployer = new web3.eth.Contract( - DharmaUSDCImplementationV1Artifact.abi - ) - DharmaUSDCImplementationV1Deployer.options.data = ( - DharmaUSDCImplementationV1Artifact.bytecode - ) + const DharmaUSDCImplementationV1Deployer = new web3.eth.Contract( + DharmaUSDCImplementationV1Artifact.abi + ); + DharmaUSDCImplementationV1Deployer.options.data = + DharmaUSDCImplementationV1Artifact.bytecode; - /* + /* const DharmaKeyRingImplementationV0Deployer = new web3.eth.Contract( DharmaKeyRingImplementationV0Artifact.abi ) @@ -436,12 +433,11 @@ async function test(testingContext) { ) */ + const DharmaKeyRingImplementationV1Deployer = newContractAndSwapMetadataHash( + DharmaKeyRingImplementationV1Artifact + ); - const DharmaKeyRingImplementationV1Deployer = newContractAndSwapMetadataHash( - DharmaKeyRingImplementationV1Artifact - ); - - /* + /* const DharmaKeyRingImplementationV2Deployer = new web3.eth.Contract( DharmaKeyRingImplementationV2Artifact.abi ) @@ -453,337 +449,352 @@ async function test(testingContext) { ) */ - const UpgradeBeaconImplementationCheckDeployer = new web3.eth.Contract( - UpgradeBeaconImplementationCheckArtifact.abi - ) - UpgradeBeaconImplementationCheckDeployer.options.data = ( - UpgradeBeaconImplementationCheckArtifact.bytecode - ) - - const InefficientImmutableCreate2Factory = new web3.eth.Contract( - ImmutableCreate2FactoryArtifact.abi, - constants.INEFFICIENT_IMMUTABLE_CREATE2_FACTORY_ADDRESS - ) - - const ImmutableCreate2Factory = new web3.eth.Contract( - ImmutableCreate2FactoryArtifact.abi, - constants.IMMUTABLE_CREATE2_FACTORY_ADDRESS - ) + const UpgradeBeaconImplementationCheckDeployer = new web3.eth.Contract( + UpgradeBeaconImplementationCheckArtifact.abi + ); + UpgradeBeaconImplementationCheckDeployer.options.data = + UpgradeBeaconImplementationCheckArtifact.bytecode; - // construct the payload passed to create2 in order to verify correct behavior - const testCreate2payload = ( - '0xff' + - constants.KEYLESS_CREATE2_ADDRESS.slice(2) + - '0000000000000000000000000000000000000000000000000000000000000000' + - web3.utils.keccak256( - MockCodeCheckArtifact.bytecode, - {encoding: 'hex'} - ).slice(2) - ) + const InefficientImmutableCreate2Factory = new web3.eth.Contract( + ImmutableCreate2FactoryArtifact.abi, + constants.INEFFICIENT_IMMUTABLE_CREATE2_FACTORY_ADDRESS + ); - // determine the target address using the payload - const targetCodeCheckAddress = web3.utils.toChecksumAddress( - '0x' + web3.utils.keccak256( - testCreate2payload, - {encoding: "hex"} - ).slice(12).substring(14) - ) + const ImmutableCreate2Factory = new web3.eth.Contract( + ImmutableCreate2FactoryArtifact.abi, + constants.IMMUTABLE_CREATE2_FACTORY_ADDRESS + ); - const tester = new Tester(testingContext); - await tester.init(); - - console.log('funding initial create2 contract deployer address...') - await web3.eth.sendTransaction({ - from: tester.originalAddress, - to: constants.KEYLESS_CREATE2_DEPLOYER_ADDRESS, - value: web3.utils.toWei('0.01', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : tester.gasLimit - 1, - gasPrice: 1 - }) - - console.log('running tests...') - - let currentKeylessCreate2Runtime; - await tester.runTest( - 'Current runtime code at address of initial create2 factory can be retrieved', - tester.MockCodeCheck, - 'code', - 'call', - [constants.KEYLESS_CREATE2_ADDRESS], - true, - value => { - currentKeylessCreate2Runtime = value - } - ) + // construct the payload passed to create2 in order to verify correct behavior + const testCreate2payload = + "0xff" + + constants.KEYLESS_CREATE2_ADDRESS.slice(2) + + "0000000000000000000000000000000000000000000000000000000000000000" + + web3.utils + .keccak256(MockCodeCheckArtifact.bytecode, { encoding: "hex" }) + .slice(2); + + // determine the target address using the payload + const targetCodeCheckAddress = web3.utils.toChecksumAddress( + "0x" + + web3.utils + .keccak256(testCreate2payload, { encoding: "hex" }) + .slice(12) + .substring(14) + ); - // submit the initial create2 deployment transaction if needed - if (currentKeylessCreate2Runtime !== constants.KEYLESS_CREATE2_RUNTIME_HASH) { - console.log(' ✓ submitting initial create2 contract deployment transaction...') - await web3.eth.sendSignedTransaction( - constants.KEYLESS_CREATE2_DEPLOYMENT_TRANSACTION - ); - tester.passed++ - - // deploy a mock code check contract using the initial create2 deployer - console.log(' ✓ deploying test contract via create2 contract...') - const DeploymentTx = await web3.eth.sendTransaction({ - from: tester.originalAddress, - to: constants.KEYLESS_CREATE2_ADDRESS, - value: 0, - gas: (testingContext !== 'coverage') ? 1500051 : tester.gasLimit - 1, - gasPrice: 1, - data: MockCodeCheckArtifact.bytecode - }) - tester.passed++ - } else { - console.log(' ✓ initial create2 contract already deployed, skipping...') - } - - let currentInefficientImmutableCreate2FactoryRuntimeHash; - await tester.runTest( - 'Current runtime hash at address of inefficient immutable create2 factory can be retrieved', - tester.MockCodeCheck, - 'hash', - 'call', - [constants.INEFFICIENT_IMMUTABLE_CREATE2_FACTORY_ADDRESS], - true, - value => { - currentInefficientImmutableCreate2FactoryRuntimeHash = value - } - ) + const tester = new Tester(testingContext); + await tester.init(); - // submit the inefficient immutable create2 deployment transaction if needed - if (currentInefficientImmutableCreate2FactoryRuntimeHash !== constants.IMMUTABLE_CREATE2_FACTORY_RUNTIME_HASH) { - console.log( - ' ✓ submitting inefficient immutable create2 factory deployment through' + - ' initial create2 contract...' - ) + console.log("funding initial create2 contract deployer address..."); await web3.eth.sendTransaction({ - from: tester.originalAddress, - to: constants.KEYLESS_CREATE2_ADDRESS, - value: '0', - gas: (testingContext !== 'coverage') ? '608261' : tester.gasLimit - 1, - gasPrice: 1, - data: constants.IMMUTABLE_CREATE2_FACTORY_CREATION_CODE + from: tester.originalAddress, + to: constants.KEYLESS_CREATE2_DEPLOYER_ADDRESS, + value: web3.utils.toWei("0.01", "ether"), + gas: testingContext !== "coverage" ? "0x5208" : tester.gasLimit - 1, + gasPrice: 1 }); - tester.passed++ - } else { - console.log(' ✓ inefficient immutable create2 factory contract already deployed, skipping...') - } - - let currentImmutableCreate2FactoryRuntimeHash; - await tester.runTest( - 'Current runtime hash at address of immutable create2 factory can be retrieved', - tester.MockCodeCheck, - 'hash', - 'call', - [constants.IMMUTABLE_CREATE2_FACTORY_ADDRESS], - true, - value => { - currentImmutableCreate2FactoryRuntimeHash = value - } - ) - // submit the immutable create2 deployment transaction if needed - if (currentImmutableCreate2FactoryRuntimeHash !== constants.IMMUTABLE_CREATE2_FACTORY_RUNTIME_HASH) { - await tester.runTest( - `submitting immutable create2 factory deployment through initial create2 contract...`, - InefficientImmutableCreate2Factory, - 'safeCreate2', - 'send', - [ - constants.IMMUTABLE_CREATE2_FACTORY_SALT, - constants.IMMUTABLE_CREATE2_FACTORY_CREATION_CODE - ], - true - ) - } else { - console.log(' ✓ immutable create2 factory contract already deployed, skipping...') - } - - let currentIndestructibleRegistryRuntimeHash; - await tester.runTest( - 'Current runtime hash at address of indestructible registry can be retrieved', - tester.MockCodeCheck, - 'hash', - 'call', - [constants.INDESTRUCTIBLE_REGISTRY_ADDRESS], - true, - value => { - currentIndestructibleRegistryRuntimeHash = value - } - ) + console.log("running tests..."); - // submit the indestructible registry deployment transaction if needed - if (currentIndestructibleRegistryRuntimeHash !== constants.INDESTRUCTIBLE_REGISTRY_RUNTIME_HASH) { - console.log(` ✓ submitting indestructible registry deployment through immutable create2 contract...`) - await web3.eth.sendTransaction({ - from: tester.originalAddress, - to: constants.IMMUTABLE_CREATE2_FACTORY_ADDRESS, - value: '0', - gas: (testingContext !== 'coverage') ? '3000000' : tester.gasLimit - 1, - gasPrice: 1, - data: constants.INDESTRUCTIBLE_REGISTRY_CREATION_TX - }); - tester.passed++ - } else { - console.log(' ✓ indestructible registry contract already deployed, skipping...') - } + let currentKeylessCreate2Runtime; + await tester.runTest( + "Current runtime code at address of initial create2 factory can be retrieved", + tester.MockCodeCheck, + "code", + "call", + [constants.KEYLESS_CREATE2_ADDRESS], + true, + value => { + currentKeylessCreate2Runtime = value; + } + ); - // BEGIN ACTUAL DEPLOYMENT TESTS + // submit the initial create2 deployment transaction if needed + if ( + currentKeylessCreate2Runtime !== constants.KEYLESS_CREATE2_RUNTIME_HASH + ) { + console.log( + " ✓ submitting initial create2 contract deployment transaction..." + ); + await web3.eth.sendSignedTransaction( + constants.KEYLESS_CREATE2_DEPLOYMENT_TRANSACTION + ); + tester.passed++; + + // deploy a mock code check contract using the initial create2 deployer + console.log(" ✓ deploying test contract via create2 contract..."); + const DeploymentTx = await web3.eth.sendTransaction({ + from: tester.originalAddress, + to: constants.KEYLESS_CREATE2_ADDRESS, + value: 0, + gas: testingContext !== "coverage" ? 1500051 : tester.gasLimit - 1, + gasPrice: 1, + data: MockCodeCheckArtifact.bytecode + }); + tester.passed++; + } else { + console.log( + " ✓ initial create2 contract already deployed, skipping..." + ); + } - await tester.runTest( - `DharmaUpgradeBeaconController contract deployment fails before other deployments`, - DharmaUpgradeBeaconControllerCoverageDeployer, - '', - 'deploy', - [], - false - ) + let currentInefficientImmutableCreate2FactoryRuntimeHash; + await tester.runTest( + "Current runtime hash at address of inefficient immutable create2 factory can be retrieved", + tester.MockCodeCheck, + "hash", + "call", + [constants.INEFFICIENT_IMMUTABLE_CREATE2_FACTORY_ADDRESS], + true, + value => { + currentInefficientImmutableCreate2FactoryRuntimeHash = value; + } + ); - await tester.runTest( - `DharmaUpgradeBeaconControllerManager contract deployment fails before other deployments`, - DharmaUpgradeBeaconControllerManagerCoverageDeployer, - '', - 'deploy', - [], - false - ) + // submit the inefficient immutable create2 deployment transaction if needed + if ( + currentInefficientImmutableCreate2FactoryRuntimeHash !== + constants.IMMUTABLE_CREATE2_FACTORY_RUNTIME_HASH + ) { + console.log( + " ✓ submitting inefficient immutable create2 factory deployment through" + + " initial create2 contract..." + ); + await web3.eth.sendTransaction({ + from: tester.originalAddress, + to: constants.KEYLESS_CREATE2_ADDRESS, + value: "0", + gas: testingContext !== "coverage" ? "608261" : tester.gasLimit - 1, + gasPrice: 1, + data: constants.IMMUTABLE_CREATE2_FACTORY_CREATION_CODE + }); + tester.passed++; + } else { + console.log( + " ✓ inefficient immutable create2 factory contract already deployed, skipping..." + ); + } + let currentImmutableCreate2FactoryRuntimeHash; + await tester.runTest( + "Current runtime hash at address of immutable create2 factory can be retrieved", + tester.MockCodeCheck, + "hash", + "call", + [constants.IMMUTABLE_CREATE2_FACTORY_ADDRESS], + true, + value => { + currentImmutableCreate2FactoryRuntimeHash = value; + } + ); - // UpgradeBeaconEnvoy - await tester.checkAndDeploy( - "UpgradeBeaconEnvoy", - constants.UPGRADE_BEACON_ENVOY_ADDRESS, - constants.UPGRADE_BEACON_ENVOY_SALT, - constants.UPGRADE_BEACON_ENVOY_RUNTIME_CODE, - constants.UPGRADE_BEACON_ENVOY_CREATION_CODE, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + // submit the immutable create2 deployment transaction if needed + if ( + currentImmutableCreate2FactoryRuntimeHash !== + constants.IMMUTABLE_CREATE2_FACTORY_RUNTIME_HASH + ) { + await tester.runTest( + `submitting immutable create2 factory deployment through initial create2 contract...`, + InefficientImmutableCreate2Factory, + "safeCreate2", + "send", + [ + constants.IMMUTABLE_CREATE2_FACTORY_SALT, + constants.IMMUTABLE_CREATE2_FACTORY_CREATION_CODE + ], + true + ); + } else { + console.log( + " ✓ immutable create2 factory contract already deployed, skipping..." + ); + } + let currentIndestructibleRegistryRuntimeHash; + await tester.runTest( + "Current runtime hash at address of indestructible registry can be retrieved", + tester.MockCodeCheck, + "hash", + "call", + [constants.INDESTRUCTIBLE_REGISTRY_ADDRESS], + true, + value => { + currentIndestructibleRegistryRuntimeHash = value; + } + ); - // UpgradeBeaconController - const upgradeBeaconControllerRuntimeCode = swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.deployedBytecode, - constants.UPGRADE_BEACON_CONTROLLER_METADATA - ); + // submit the indestructible registry deployment transaction if needed + if ( + currentIndestructibleRegistryRuntimeHash !== + constants.INDESTRUCTIBLE_REGISTRY_RUNTIME_HASH + ) { + console.log( + ` ✓ submitting indestructible registry deployment through immutable create2 contract...` + ); + await web3.eth.sendTransaction({ + from: tester.originalAddress, + to: constants.IMMUTABLE_CREATE2_FACTORY_ADDRESS, + value: "0", + gas: + testingContext !== "coverage" ? "3000000" : tester.gasLimit - 1, + gasPrice: 1, + data: constants.INDESTRUCTIBLE_REGISTRY_CREATION_TX + }); + tester.passed++; + } else { + console.log( + " ✓ indestructible registry contract already deployed, skipping..." + ); + } - const upgradeBeaconControllerCreationCode = swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.bytecode, - constants.UPGRADE_BEACON_CONTROLLER_METADATA - ); + // BEGIN ACTUAL DEPLOYMENT TESTS - await tester.checkAndDeploy( - "UpgradeBeaconController", - constants.UPGRADE_BEACON_CONTROLLER_ADDRESS, - constants.UPGRADE_BEACON_CONTROLLER_SALT, - upgradeBeaconControllerRuntimeCode, - upgradeBeaconControllerCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + await tester.runTest( + `DharmaUpgradeBeaconController contract deployment fails before other deployments`, + DharmaUpgradeBeaconControllerCoverageDeployer, + "", + "deploy", + [], + false + ); + await tester.runTest( + `DharmaUpgradeBeaconControllerManager contract deployment fails before other deployments`, + DharmaUpgradeBeaconControllerManagerCoverageDeployer, + "", + "deploy", + [], + false + ); - // KeyRingUpgradeBeaconController - const keyRingUpgradeBeaconControllerRuntimeCode = swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.deployedBytecode, - constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_METADATA - ); + // UpgradeBeaconEnvoy + await tester.checkAndDeploy( + "UpgradeBeaconEnvoy", + constants.UPGRADE_BEACON_ENVOY_ADDRESS, + constants.UPGRADE_BEACON_ENVOY_SALT, + constants.UPGRADE_BEACON_ENVOY_RUNTIME_CODE, + constants.UPGRADE_BEACON_ENVOY_CREATION_CODE, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - const keyRingUpgradeBeaconControllerCreationCode = swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.bytecode, - constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_METADATA - ); + // UpgradeBeaconController + const upgradeBeaconControllerRuntimeCode = swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.deployedBytecode, + constants.UPGRADE_BEACON_CONTROLLER_METADATA + ); - await tester.checkAndDeploy( - "KeyRingUpgradeBeaconController", - constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS, - constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_SALT, - keyRingUpgradeBeaconControllerRuntimeCode, - keyRingUpgradeBeaconControllerCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + const upgradeBeaconControllerCreationCode = swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.bytecode, + constants.UPGRADE_BEACON_CONTROLLER_METADATA + ); - await tester.runTest( - `DharmaUpgradeBeaconController contract deployment`, - DharmaUpgradeBeaconControllerDeployer, - '', - 'deploy' - ); + await tester.checkAndDeploy( + "UpgradeBeaconController", + constants.UPGRADE_BEACON_CONTROLLER_ADDRESS, + constants.UPGRADE_BEACON_CONTROLLER_SALT, + upgradeBeaconControllerRuntimeCode, + upgradeBeaconControllerCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - await tester.runTest( - `failure when deploying UpgradeBeaconProxyV1 contract using an undeployed beacon`, - UpgradeBeaconProxyV1Deployer, - '', - 'deploy', - ["0x"], - false - ); + // KeyRingUpgradeBeaconController + const keyRingUpgradeBeaconControllerRuntimeCode = swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.deployedBytecode, + constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_METADATA + ); + const keyRingUpgradeBeaconControllerCreationCode = swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.bytecode, + constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_METADATA + ); - // UpgradeBeacon - const upgradeBeaconRuntimeCode = swapMetadataHash( - DharmaUpgradeBeaconArtifact.deployedBytecode, - constants.UPGRADE_BEACON_METADATA - ); + await tester.checkAndDeploy( + "KeyRingUpgradeBeaconController", + constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS, + constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_SALT, + keyRingUpgradeBeaconControllerRuntimeCode, + keyRingUpgradeBeaconControllerCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - const upgradeBeaconCreationCode = swapMetadataHash( - DharmaUpgradeBeaconArtifact.bytecode, - constants.UPGRADE_BEACON_METADATA - ); + await tester.runTest( + `DharmaUpgradeBeaconController contract deployment`, + DharmaUpgradeBeaconControllerDeployer, + "", + "deploy" + ); - await tester.checkAndDeploy( - "UpgradeBeacon", - constants.UPGRADE_BEACON_ADDRESS, - constants.UPGRADE_BEACON_SALT, - upgradeBeaconRuntimeCode, - upgradeBeaconCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + await tester.runTest( + `failure when deploying UpgradeBeaconProxyV1 contract using an undeployed beacon`, + UpgradeBeaconProxyV1Deployer, + "", + "deploy", + ["0x"], + false + ); + // UpgradeBeacon + const upgradeBeaconRuntimeCode = swapMetadataHash( + DharmaUpgradeBeaconArtifact.deployedBytecode, + constants.UPGRADE_BEACON_METADATA + ); - await tester.runTest( - `DharmaUpgradeBeacon contract deployment`, - DharmaUpgradeBeaconDeployer, - '', - 'deploy' - ); + const upgradeBeaconCreationCode = swapMetadataHash( + DharmaUpgradeBeaconArtifact.bytecode, + constants.UPGRADE_BEACON_METADATA + ); + await tester.checkAndDeploy( + "UpgradeBeacon", + constants.UPGRADE_BEACON_ADDRESS, + constants.UPGRADE_BEACON_SALT, + upgradeBeaconRuntimeCode, + upgradeBeaconCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - // KeyRingUpgradeBeacon - const keyRingUpgradeBeaconRuntimeCode = swapMetadataHash( - DharmaKeyRingUpgradeBeaconArtifact.deployedBytecode, - constants.KEY_RING_UPGRADE_BEACON_METADATA - ); + await tester.runTest( + `DharmaUpgradeBeacon contract deployment`, + DharmaUpgradeBeaconDeployer, + "", + "deploy" + ); - const keyRingUpgradeBeaconCreationCode = swapMetadataHash( - DharmaKeyRingUpgradeBeaconArtifact.bytecode, - constants.KEY_RING_UPGRADE_BEACON_METADATA - ); + // KeyRingUpgradeBeacon + const keyRingUpgradeBeaconRuntimeCode = swapMetadataHash( + DharmaKeyRingUpgradeBeaconArtifact.deployedBytecode, + constants.KEY_RING_UPGRADE_BEACON_METADATA + ); - await tester.checkAndDeploy( - "KeyRingUpgradeBeacon", - constants.KEY_RING_UPGRADE_BEACON_ADDRESS, - constants.KEY_RING_UPGRADE_BEACON_SALT, - keyRingUpgradeBeaconRuntimeCode, - keyRingUpgradeBeaconCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + const keyRingUpgradeBeaconCreationCode = swapMetadataHash( + DharmaKeyRingUpgradeBeaconArtifact.bytecode, + constants.KEY_RING_UPGRADE_BEACON_METADATA + ); - await tester.runTest( - `DharmaKeyRingUpgradeBeacon contract deployment`, - DharmaKeyRingUpgradeBeaconDeployer, - '', - 'deploy' - ); + await tester.checkAndDeploy( + "KeyRingUpgradeBeacon", + constants.KEY_RING_UPGRADE_BEACON_ADDRESS, + constants.KEY_RING_UPGRADE_BEACON_SALT, + keyRingUpgradeBeaconRuntimeCode, + keyRingUpgradeBeaconCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); + await tester.runTest( + `DharmaKeyRingUpgradeBeacon contract deployment`, + DharmaKeyRingUpgradeBeaconDeployer, + "", + "deploy" + ); - // KeyRegistry - /* + // KeyRegistry + /* const keyRegistryRuntimeCode = swapMetadataHash( DharmaKeyRegistryV1Artifact.deployedBytecode, constants.KEY_REGISTRY_METADATA @@ -805,75 +816,71 @@ async function test(testingContext) { ); */ + // KeyRegistryV2 + const keyRegistryV2RuntimeCode = swapMetadataHash( + DharmaKeyRegistryV2Artifact.deployedBytecode, + constants.KEY_REGISTRY_V2_METADATA + ); - // KeyRegistryV2 - const keyRegistryV2RuntimeCode = swapMetadataHash( - DharmaKeyRegistryV2Artifact.deployedBytecode, - constants.KEY_REGISTRY_V2_METADATA - ); - - const keyRegistryV2CreationCode = swapMetadataHash( - DharmaKeyRegistryV2Artifact.bytecode, - constants.KEY_REGISTRY_V2_METADATA - ); - - await tester.checkAndDeploy( - "KeyRegistryV2", - constants.KEY_REGISTRY_V2_ADDRESS, - constants.KEY_REGISTRY_V2_SALT, - keyRegistryV2RuntimeCode, - keyRegistryV2CreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); - - - // RevertReasonHelper - const revertReasonHelperRuntimeCode = swapMetadataHash( - SmartWalletRevertReasonHelperV1Artifact.deployedBytecode, - constants.REVERT_REASON_HELPER_METADATA - ); + const keyRegistryV2CreationCode = swapMetadataHash( + DharmaKeyRegistryV2Artifact.bytecode, + constants.KEY_REGISTRY_V2_METADATA + ); - const revertReasonHelperCreationCode = swapMetadataHash( - SmartWalletRevertReasonHelperV1Artifact.bytecode, - constants.REVERT_REASON_HELPER_METADATA - ); + await tester.checkAndDeploy( + "KeyRegistryV2", + constants.KEY_REGISTRY_V2_ADDRESS, + constants.KEY_REGISTRY_V2_SALT, + keyRegistryV2RuntimeCode, + keyRegistryV2CreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - await tester.checkAndDeploy( - "RevertReasonHelper", - constants.REVERT_REASON_HELPER_ADDRESS, - constants.NULL_BYTES_32, - revertReasonHelperRuntimeCode, - revertReasonHelperCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + // RevertReasonHelper + const revertReasonHelperRuntimeCode = swapMetadataHash( + SmartWalletRevertReasonHelperV1Artifact.deployedBytecode, + constants.REVERT_REASON_HELPER_METADATA + ); + const revertReasonHelperCreationCode = swapMetadataHash( + SmartWalletRevertReasonHelperV1Artifact.bytecode, + constants.REVERT_REASON_HELPER_METADATA + ); - // EscapeHatchRegistry - const escapeHatchRegistryRuntimeCode = swapMetadataHash( - DharmaEscapeHatchRegistryArtifact.deployedBytecode, - constants.ESCAPE_HATCH_REGISTRY_METADATA - ); + await tester.checkAndDeploy( + "RevertReasonHelper", + constants.REVERT_REASON_HELPER_ADDRESS, + constants.NULL_BYTES_32, + revertReasonHelperRuntimeCode, + revertReasonHelperCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - const escapeHatchRegistryCreationCode = swapMetadataHash( - DharmaEscapeHatchRegistryArtifact.bytecode, - constants.ESCAPE_HATCH_REGISTRY_METADATA - ); + // EscapeHatchRegistry + const escapeHatchRegistryRuntimeCode = swapMetadataHash( + DharmaEscapeHatchRegistryArtifact.deployedBytecode, + constants.ESCAPE_HATCH_REGISTRY_METADATA + ); - await tester.checkAndDeploy( - "EscapeHatchRegistry", - constants.ESCAPE_HATCH_REGISTRY_ADDRESS, - constants.ESCAPE_HATCH_REGISTRY_SALT, - escapeHatchRegistryRuntimeCode, - escapeHatchRegistryCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + const escapeHatchRegistryCreationCode = swapMetadataHash( + DharmaEscapeHatchRegistryArtifact.bytecode, + constants.ESCAPE_HATCH_REGISTRY_METADATA + ); + await tester.checkAndDeploy( + "EscapeHatchRegistry", + constants.ESCAPE_HATCH_REGISTRY_ADDRESS, + constants.ESCAPE_HATCH_REGISTRY_SALT, + escapeHatchRegistryRuntimeCode, + escapeHatchRegistryCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - // Dharma Smart Wallet Implementations - /* + // Dharma Smart Wallet Implementations + /* const DharmaSmartWalletImplementationV0 = await tester.runTest( `DharmaSmartWalletImplementationV0 contract deployment`, DharmaSmartWalletImplementationV0Deployer, @@ -917,21 +924,21 @@ async function test(testingContext) { ) */ - const DharmaSmartWalletImplementationV6 = await tester.runTest( - `DharmaSmartWalletImplementationV6 contract deployment`, - DharmaSmartWalletImplementationV6Deployer, - '', - 'deploy' - ) + const DharmaSmartWalletImplementationV6 = await tester.runTest( + `DharmaSmartWalletImplementationV6 contract deployment`, + DharmaSmartWalletImplementationV6Deployer, + "", + "deploy" + ); - const DharmaSmartWalletImplementationV7 = await tester.runTest( - `DharmaSmartWalletImplementationV7 contract deployment`, - DharmaSmartWalletImplementationV7Deployer, - '', - 'deploy' - ) + const DharmaSmartWalletImplementationV7 = await tester.runTest( + `DharmaSmartWalletImplementationV7 contract deployment`, + DharmaSmartWalletImplementationV7Deployer, + "", + "deploy" + ); - /* + /* const DharmaKeyRingImplementationV0 = await runTest( `DharmaKeyRingImplementationV0 contract deployment`, DharmaKeyRingImplementationV0Deployer, @@ -940,15 +947,15 @@ async function test(testingContext) { ) */ - // Dharma Key Ring Implementations - const DharmaKeyRingImplementationV1 = await tester.runTest( - `DharmaKeyRingImplementationV1 contract deployment`, - DharmaKeyRingImplementationV1Deployer, - '', - 'deploy' - ) + // Dharma Key Ring Implementations + const DharmaKeyRingImplementationV1 = await tester.runTest( + `DharmaKeyRingImplementationV1 contract deployment`, + DharmaKeyRingImplementationV1Deployer, + "", + "deploy" + ); - /* + /* const DharmaKeyRingImplementationV2 = await runTest( `DharmaKeyRingImplementationV2 contract deployment`, DharmaKeyRingImplementationV2Deployer, @@ -957,528 +964,547 @@ async function test(testingContext) { ) */ + // AccountRecoveryManager + const accountRecoveryManagerRuntimeCode = swapMetadataHash( + DharmaAccountRecoveryManagerV2Artifact.deployedBytecode, + constants.ACCOUNT_RECOVERY_MANAGER_V2_METADATA + ); - // AccountRecoveryManager - const accountRecoveryManagerRuntimeCode = swapMetadataHash( - DharmaAccountRecoveryManagerV2Artifact.deployedBytecode, - constants.ACCOUNT_RECOVERY_MANAGER_V2_METADATA - ); - - const accountRecoveryManagerCreationCode = swapMetadataHash( - DharmaAccountRecoveryManagerV2Artifact.bytecode, - constants.ACCOUNT_RECOVERY_MANAGER_V2_METADATA - ); - - await tester.checkAndDeploy( - "AccountRecoveryManager", - constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS, - constants.ACCOUNT_RECOVERY_MANAGER_V2_SALT, - accountRecoveryManagerRuntimeCode, - accountRecoveryManagerCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 contract deployment`, - DharmaAccountRecoveryManagerV2Deployer, - '', - 'deploy' - ); - - - // DharmaSmartWalletFactory - const dharmaSmartWalletFactoryRuntimeCode = swapMetadataHash( - DharmaSmartWalletFactoryV1Artifact.deployedBytecode, - constants.FACTORY_METADATA - ); - - const dharmaSmartWalletFactoryCreationCode = swapMetadataHash( - DharmaSmartWalletFactoryV1Artifact.bytecode, - constants.FACTORY_METADATA - ); - - await tester.checkAndDeploy( - "DharmaSmartWalletFactory", - constants.FACTORY_ADDRESS, - constants.FACTORY_SALT, - dharmaSmartWalletFactoryRuntimeCode, - dharmaSmartWalletFactoryCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); - - await tester.runTest( - `DharmaSmartWalletFactoryV1 contract deployment`, - DharmaSmartWalletFactoryV1Deployer, - '', - 'deploy', - [] - ); - - - // KeyRingFactory - const keyRingFactoryRuntimeCode = swapMetadataHash( - DharmaKeyRingFactoryV2Artifact.deployedBytecode, - constants.KEY_RING_FACTORY_V2_METADATA - ); + const accountRecoveryManagerCreationCode = swapMetadataHash( + DharmaAccountRecoveryManagerV2Artifact.bytecode, + constants.ACCOUNT_RECOVERY_MANAGER_V2_METADATA + ); - const keyRingFactoryCreationCode = swapMetadataHash( - DharmaKeyRingFactoryV2Artifact.bytecode, - constants.KEY_RING_FACTORY_V2_METADATA - ); + await tester.checkAndDeploy( + "AccountRecoveryManager", + constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS, + constants.ACCOUNT_RECOVERY_MANAGER_V2_SALT, + accountRecoveryManagerRuntimeCode, + accountRecoveryManagerCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - await tester.checkAndDeploy( - "KeyRingFactory", - constants.KEY_RING_FACTORY_V2_ADDRESS, - constants.KEY_RING_FACTORY_V2_SALT, - keyRingFactoryRuntimeCode, - keyRingFactoryCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + await tester.runTest( + `DharmaAccountRecoveryManagerV2 contract deployment`, + DharmaAccountRecoveryManagerV2Deployer, + "", + "deploy" + ); - await tester.runTest( - `DharmaKeyRingFactoryV2 contract deployment`, - DharmaKeyRingFactoryV2Deployer, - '', - 'deploy', - [] - ); + // DharmaSmartWalletFactory + const dharmaSmartWalletFactoryRuntimeCode = swapMetadataHash( + DharmaSmartWalletFactoryV1Artifact.deployedBytecode, + constants.FACTORY_METADATA + ); - // AdharmaSmartWalletImplementation - const adharmaSmartWalletImplementationRuntimeCode = swapMetadataHash( - AdharmaSmartWalletImplementationArtifact.deployedBytecode, - constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_METADATA - ); + const dharmaSmartWalletFactoryCreationCode = swapMetadataHash( + DharmaSmartWalletFactoryV1Artifact.bytecode, + constants.FACTORY_METADATA + ); - const adharmaSmartWalletImplementationCreationCode = swapMetadataHash( - AdharmaSmartWalletImplementationArtifact.bytecode, - constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_METADATA - ); + await tester.checkAndDeploy( + "DharmaSmartWalletFactory", + constants.FACTORY_ADDRESS, + constants.FACTORY_SALT, + dharmaSmartWalletFactoryRuntimeCode, + dharmaSmartWalletFactoryCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - await tester.checkAndDeploy( - "AdharmaSmartWalletImplementation", - constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS, - constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_SALT, - adharmaSmartWalletImplementationRuntimeCode, - adharmaSmartWalletImplementationCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + await tester.runTest( + `DharmaSmartWalletFactoryV1 contract deployment`, + DharmaSmartWalletFactoryV1Deployer, + "", + "deploy", + [] + ); + // KeyRingFactory + const keyRingFactoryRuntimeCode = swapMetadataHash( + DharmaKeyRingFactoryV2Artifact.deployedBytecode, + constants.KEY_RING_FACTORY_V2_METADATA + ); - // DharmaDaiUpgrageBeaconController - const dharmaDaiUpgradeBeaconControllerRuntimeCode = swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.deployedBytecode, - constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA - ); + const keyRingFactoryCreationCode = swapMetadataHash( + DharmaKeyRingFactoryV2Artifact.bytecode, + constants.KEY_RING_FACTORY_V2_METADATA + ); - const dharmaDaiUpgradeBeaconControllerCreationCode = swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.bytecode, - constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA - ); + await tester.checkAndDeploy( + "KeyRingFactory", + constants.KEY_RING_FACTORY_V2_ADDRESS, + constants.KEY_RING_FACTORY_V2_SALT, + keyRingFactoryRuntimeCode, + keyRingFactoryCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - await tester.checkAndDeploy( - "DharmaDaiUpgrageBeaconController", - constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_ADDRESS, - constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_SALT, - dharmaDaiUpgradeBeaconControllerRuntimeCode, - dharmaDaiUpgradeBeaconControllerCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + await tester.runTest( + `DharmaKeyRingFactoryV2 contract deployment`, + DharmaKeyRingFactoryV2Deployer, + "", + "deploy", + [] + ); + // AdharmaSmartWalletImplementation + const adharmaSmartWalletImplementationRuntimeCode = swapMetadataHash( + AdharmaSmartWalletImplementationArtifact.deployedBytecode, + constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_METADATA + ); - // DharmaUSDCUpgrageBeaconController - const dharmaUSDCUpgradeBeaconControllerRuntimeCode = swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.deployedBytecode, - constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA - ); + const adharmaSmartWalletImplementationCreationCode = swapMetadataHash( + AdharmaSmartWalletImplementationArtifact.bytecode, + constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_METADATA + ); - const dharmaUSDCUpgradeBeaconControllerCreationCode = swapMetadataHash( - DharmaUpgradeBeaconControllerArtifact.bytecode, - constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA - ); + await tester.checkAndDeploy( + "AdharmaSmartWalletImplementation", + constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS, + constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_SALT, + adharmaSmartWalletImplementationRuntimeCode, + adharmaSmartWalletImplementationCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - await tester.checkAndDeploy( - "DharmaUSDCUpgrageBeaconController", - constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_ADDRESS, - constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_SALT, - dharmaUSDCUpgradeBeaconControllerRuntimeCode, - dharmaUSDCUpgradeBeaconControllerCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + // DharmaDaiUpgrageBeaconController + const dharmaDaiUpgradeBeaconControllerRuntimeCode = swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.deployedBytecode, + constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA + ); - // DharmaUSDCUpgrageBeacon - const dharmaDaiUpgradeBeaconRuntimeCode = swapMetadataHash( - DharmaDaiUpgradeBeaconArtifact.deployedBytecode, - constants.DHARMA_DAI_UPGRADE_BEACON_METADATA - ); + const dharmaDaiUpgradeBeaconControllerCreationCode = swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.bytecode, + constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_METADATA + ); - const dharmaDaiUpgradeBeaconCreationCode = swapMetadataHash( - DharmaDaiUpgradeBeaconArtifact.bytecode, - constants.DHARMA_DAI_UPGRADE_BEACON_METADATA - ); + await tester.checkAndDeploy( + "DharmaDaiUpgrageBeaconController", + constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_ADDRESS, + constants.DHARMA_DAI_UPGRADE_BEACON_CONTROLLER_SALT, + dharmaDaiUpgradeBeaconControllerRuntimeCode, + dharmaDaiUpgradeBeaconControllerCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - await tester.checkAndDeploy( - "DharmaDaiUpgrageBeacon", - constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS, - constants.DHARMA_DAI_UPGRADE_BEACON_SALT, - dharmaDaiUpgradeBeaconRuntimeCode, - dharmaDaiUpgradeBeaconCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + // DharmaUSDCUpgrageBeaconController + const dharmaUSDCUpgradeBeaconControllerRuntimeCode = swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.deployedBytecode, + constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA + ); - // DharmaUSDCUpgrageBeacon - const dharmaUSDCUpgradeBeaconRuntimeCode = swapMetadataHash( - DharmaUSDCUpgradeBeaconArtifact.deployedBytecode, - constants.DHARMA_USDC_UPGRADE_BEACON_METADATA - ); + const dharmaUSDCUpgradeBeaconControllerCreationCode = swapMetadataHash( + DharmaUpgradeBeaconControllerArtifact.bytecode, + constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_METADATA + ); - const dharmaUSDCUpgradeBeaconCreationCode = swapMetadataHash( - DharmaUSDCUpgradeBeaconArtifact.bytecode, - constants.DHARMA_USDC_UPGRADE_BEACON_METADATA - ); + await tester.checkAndDeploy( + "DharmaUSDCUpgrageBeaconController", + constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_ADDRESS, + constants.DHARMA_USDC_UPGRADE_BEACON_CONTROLLER_SALT, + dharmaUSDCUpgradeBeaconControllerRuntimeCode, + dharmaUSDCUpgradeBeaconControllerCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - await tester.checkAndDeploy( - "DharmaUSDCUpgrageBeacon", - constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS, - constants.DHARMA_USDC_UPGRADE_BEACON_SALT, - dharmaUSDCUpgradeBeaconRuntimeCode, - dharmaUSDCUpgradeBeaconCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + // DharmaUSDCUpgrageBeacon + const dharmaDaiUpgradeBeaconRuntimeCode = swapMetadataHash( + DharmaDaiUpgradeBeaconArtifact.deployedBytecode, + constants.DHARMA_DAI_UPGRADE_BEACON_METADATA + ); + const dharmaDaiUpgradeBeaconCreationCode = swapMetadataHash( + DharmaDaiUpgradeBeaconArtifact.bytecode, + constants.DHARMA_DAI_UPGRADE_BEACON_METADATA + ); - // DharmaDai - const dharmaDaiRuntimeCode = swapMetadataHash( - DharmaDaiArtifact.deployedBytecode, - constants.DHARMA_DAI_METADATA - ); + await tester.checkAndDeploy( + "DharmaDaiUpgrageBeacon", + constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS, + constants.DHARMA_DAI_UPGRADE_BEACON_SALT, + dharmaDaiUpgradeBeaconRuntimeCode, + dharmaDaiUpgradeBeaconCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - const dharmaDaiCreationCode = swapMetadataHash( - DharmaDaiArtifact.bytecode, - constants.DHARMA_DAI_METADATA - ); + // DharmaUSDCUpgrageBeacon + const dharmaUSDCUpgradeBeaconRuntimeCode = swapMetadataHash( + DharmaUSDCUpgradeBeaconArtifact.deployedBytecode, + constants.DHARMA_USDC_UPGRADE_BEACON_METADATA + ); - await tester.checkAndDeploy( - "DharmaDai", - constants.DHARMA_DAI_ADDRESS, - constants.DHARMA_DAI_SALT, - dharmaDaiRuntimeCode, - dharmaDaiCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + const dharmaUSDCUpgradeBeaconCreationCode = swapMetadataHash( + DharmaUSDCUpgradeBeaconArtifact.bytecode, + constants.DHARMA_USDC_UPGRADE_BEACON_METADATA + ); - // DharmaUSDC - const dharmaUSDCRuntimeCode = swapMetadataHash( - DharmaUSDCArtifact.deployedBytecode, - constants.DHARMA_USDC_METADATA - ); + await tester.checkAndDeploy( + "DharmaUSDCUpgrageBeacon", + constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS, + constants.DHARMA_USDC_UPGRADE_BEACON_SALT, + dharmaUSDCUpgradeBeaconRuntimeCode, + dharmaUSDCUpgradeBeaconCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - const dharmaUSDCCreationCode = swapMetadataHash( - DharmaUSDCArtifact.bytecode, - constants.DHARMA_USDC_METADATA - ); + // DharmaDai + const dharmaDaiRuntimeCode = swapMetadataHash( + DharmaDaiArtifact.deployedBytecode, + constants.DHARMA_DAI_METADATA + ); - await tester.checkAndDeploy( - "DharmaDai", - constants.DHARMA_USDC_ADDRESS, - constants.DHARMA_USDC_SALT, - dharmaUSDCRuntimeCode, - dharmaUSDCCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + const dharmaDaiCreationCode = swapMetadataHash( + DharmaDaiArtifact.bytecode, + constants.DHARMA_DAI_METADATA + ); + await tester.checkAndDeploy( + "DharmaDai", + constants.DHARMA_DAI_ADDRESS, + constants.DHARMA_DAI_SALT, + dharmaDaiRuntimeCode, + dharmaDaiCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - const DharmaDaiInitializerImplementation = await tester.runTest( - `DharmaDaiInitializer contract deployment`, - DharmaDaiInitializerDeployer, - '', - 'deploy' - ) + // DharmaUSDC + const dharmaUSDCRuntimeCode = swapMetadataHash( + DharmaUSDCArtifact.deployedBytecode, + constants.DHARMA_USDC_METADATA + ); - const DharmaUSDCInitializerImplementation = await tester.runTest( - `DharmaUSDCInitializer contract deployment`, - DharmaUSDCInitializerDeployer, - '', - 'deploy' - ) + const dharmaUSDCCreationCode = swapMetadataHash( + DharmaUSDCArtifact.bytecode, + constants.DHARMA_USDC_METADATA + ); - const DharmaDaiImplementationV1 = await tester.runTest( - `DharmaDaiImplementationV1 contract deployment`, - DharmaDaiImplementationV1Deployer, - '', - 'deploy' - ) + await tester.checkAndDeploy( + "DharmaDai", + constants.DHARMA_USDC_ADDRESS, + constants.DHARMA_USDC_SALT, + dharmaUSDCRuntimeCode, + dharmaUSDCCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - const DharmaUSDCImplementationV1 = await tester.runTest( - `DharmaUSDCImplementationV1 contract deployment`, - DharmaUSDCImplementationV1Deployer, - '', - 'deploy' - ) + const DharmaDaiInitializerImplementation = await tester.runTest( + `DharmaDaiInitializer contract deployment`, + DharmaDaiInitializerDeployer, + "", + "deploy" + ); - await tester.runTest( - 'DharmaDaiUpgradeBeaconController can set initializer implementation', - DharmaDaiUpgradeBeaconController, - 'upgrade', - 'send', - [constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS, DharmaDaiInitializerImplementation.options.address] - ) + const DharmaUSDCInitializerImplementation = await tester.runTest( + `DharmaUSDCInitializer contract deployment`, + DharmaUSDCInitializerDeployer, + "", + "deploy" + ); - await tester.runTest( - 'DharmaDai can be initialized', - DharmaDaiInitializer, - 'initialize' - ) + const DharmaDaiImplementationV1 = await tester.runTest( + `DharmaDaiImplementationV1 contract deployment`, + DharmaDaiImplementationV1Deployer, + "", + "deploy" + ); - await tester.runTest( - 'DharmaDaiUpgradeBeaconController can set implementation V1', - DharmaDaiUpgradeBeaconController, - 'upgrade', - 'send', - [constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS, DharmaDaiImplementationV1.options.address] - ) + const DharmaUSDCImplementationV1 = await tester.runTest( + `DharmaUSDCImplementationV1 contract deployment`, + DharmaUSDCImplementationV1Deployer, + "", + "deploy" + ); - await tester.runTest( - 'DharmaUSDCUpgradeBeaconController can set initializer implementation', - DharmaUSDCUpgradeBeaconController, - 'upgrade', - 'send', - [constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS, DharmaUSDCInitializerImplementation.options.address] - ) + await tester.runTest( + "DharmaDaiUpgradeBeaconController can set initializer implementation", + DharmaDaiUpgradeBeaconController, + "upgrade", + "send", + [ + constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS, + DharmaDaiInitializerImplementation.options.address + ] + ); - await tester.runTest( - 'DharmaUSDC can be initialized', - DharmaUSDCInitializer, - 'initialize' - ) + await tester.runTest( + "DharmaDai can be initialized", + DharmaDaiInitializer, + "initialize" + ); - await tester.runTest( - 'DharmaUSDCUpgradeBeaconController can set implementation V1', - DharmaUSDCUpgradeBeaconController, - 'upgrade', - 'send', - [constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS, DharmaUSDCImplementationV1.options.address] - ) + await tester.runTest( + "DharmaDaiUpgradeBeaconController can set implementation V1", + DharmaDaiUpgradeBeaconController, + "upgrade", + "send", + [ + constants.DHARMA_DAI_UPGRADE_BEACON_ADDRESS, + DharmaDaiImplementationV1.options.address + ] + ); - await tester.runTest( - `AdharmaSmartWalletImplementation contract deployment`, - AdharmaSmartWalletImplementationDeployer, - '', - 'deploy' - ) + await tester.runTest( + "DharmaUSDCUpgradeBeaconController can set initializer implementation", + DharmaUSDCUpgradeBeaconController, + "upgrade", + "send", + [ + constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS, + DharmaUSDCInitializerImplementation.options.address + ] + ); + await tester.runTest( + "DharmaUSDC can be initialized", + DharmaUSDCInitializer, + "initialize" + ); - // ADharmaKeyRingImplementation - const adharmaKeyRingImplementationRuntimeCode = swapMetadataHash( - AdharmaKeyRingImplementationArtifact.deployedBytecode, - constants.ADHARMA_KEY_RING_IMPLEMENTATION_METADATA - ); + await tester.runTest( + "DharmaUSDCUpgradeBeaconController can set implementation V1", + DharmaUSDCUpgradeBeaconController, + "upgrade", + "send", + [ + constants.DHARMA_USDC_UPGRADE_BEACON_ADDRESS, + DharmaUSDCImplementationV1.options.address + ] + ); - const adharmaKeyRingImplementationCreationCode = swapMetadataHash( - AdharmaKeyRingImplementationArtifact.bytecode, - constants.ADHARMA_KEY_RING_IMPLEMENTATION_METADATA - ); + await tester.runTest( + `AdharmaSmartWalletImplementation contract deployment`, + AdharmaSmartWalletImplementationDeployer, + "", + "deploy" + ); - await tester.checkAndDeploy( - "DharmaDai", - constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS, - constants.ADHARMA_KEY_RING_IMPLEMENTATION_SALT, - adharmaKeyRingImplementationRuntimeCode, - adharmaKeyRingImplementationCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + // ADharmaKeyRingImplementation + const adharmaKeyRingImplementationRuntimeCode = swapMetadataHash( + AdharmaKeyRingImplementationArtifact.deployedBytecode, + constants.ADHARMA_KEY_RING_IMPLEMENTATION_METADATA + ); + const adharmaKeyRingImplementationCreationCode = swapMetadataHash( + AdharmaKeyRingImplementationArtifact.bytecode, + constants.ADHARMA_KEY_RING_IMPLEMENTATION_METADATA + ); - await tester.runTest( - `AdharmaKeyRingImplementation contract deployment`, - AdharmaKeyRingImplementationDeployer, - '', - 'deploy' - ) + await tester.checkAndDeploy( + "DharmaDai", + constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS, + constants.ADHARMA_KEY_RING_IMPLEMENTATION_SALT, + adharmaKeyRingImplementationRuntimeCode, + adharmaKeyRingImplementationCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); - await testDharmaAccountRecoveryMultisigDeployer(tester, DharmaAccountRecoveryMultisigDeployer); + await tester.runTest( + `AdharmaKeyRingImplementation contract deployment`, + AdharmaKeyRingImplementationDeployer, + "", + "deploy" + ); - await testDharmaAccountRecoveryOperatorMultisigDeployer(tester, DharmaAccountRecoveryOperatorMultisigDeployer); + await testDharmaAccountRecoveryMultisigDeployer( + tester, + DharmaAccountRecoveryMultisigDeployer + ); - await testDharmaKeyRegistryMultisigDeployer(tester, DharmaKeyRegistryMultisigDeployer); + await testDharmaAccountRecoveryOperatorMultisigDeployer( + tester, + DharmaAccountRecoveryOperatorMultisigDeployer + ); -// - await tester.runTest( - `DharmaUpgradeBeaconControllerManager contract deployment fails before indestructible registration`, - DharmaUpgradeBeaconControllerManagerCoverageDeployer, - '', - 'deploy', - [], - false - ) + await testDharmaKeyRegistryMultisigDeployer( + tester, + DharmaKeyRegistryMultisigDeployer + ); - await tester.runTest( - '"actual" IndestructibleRegistry can register the upgrade beacon as indestructible', - ActualIndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.UPGRADE_BEACON_ADDRESS] - ) + // + await tester.runTest( + `DharmaUpgradeBeaconControllerManager contract deployment fails before indestructible registration`, + DharmaUpgradeBeaconControllerManagerCoverageDeployer, + "", + "deploy", + [], + false + ); - await tester.runTest( - '"actual" IndestructibleRegistry can register the upgrade beacon controller as indestructible', - ActualIndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.UPGRADE_BEACON_CONTROLLER_ADDRESS] - ) + await tester.runTest( + '"actual" IndestructibleRegistry can register the upgrade beacon as indestructible', + ActualIndestructibleRegistry, + "registerAsIndestructible", + "send", + [constants.UPGRADE_BEACON_ADDRESS] + ); - await tester.runTest( - '"actual" IndestructibleRegistry can register the key ring upgrade beacon as indestructible', - ActualIndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.KEY_RING_UPGRADE_BEACON_ADDRESS] - ) + await tester.runTest( + '"actual" IndestructibleRegistry can register the upgrade beacon controller as indestructible', + ActualIndestructibleRegistry, + "registerAsIndestructible", + "send", + [constants.UPGRADE_BEACON_CONTROLLER_ADDRESS] + ); - await tester.runTest( - '"actual" IndestructibleRegistry can register the key ring upgrade beacon controller as indestructible', - ActualIndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS] - ) + await tester.runTest( + '"actual" IndestructibleRegistry can register the key ring upgrade beacon as indestructible', + ActualIndestructibleRegistry, + "registerAsIndestructible", + "send", + [constants.KEY_RING_UPGRADE_BEACON_ADDRESS] + ); - await tester.runTest( - '"actual" IndestructibleRegistry can register the Adharma smart wallet implementation as indestructible', - ActualIndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS] - ) + await tester.runTest( + '"actual" IndestructibleRegistry can register the key ring upgrade beacon controller as indestructible', + ActualIndestructibleRegistry, + "registerAsIndestructible", + "send", + [constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS] + ); - await tester.runTest( - '"actual" IndestructibleRegistry can register the Adharma key ring implementation as indestructible', - ActualIndestructibleRegistry, - 'registerAsIndestructible', - 'send', - [constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS] - ) + await tester.runTest( + '"actual" IndestructibleRegistry can register the Adharma smart wallet implementation as indestructible', + ActualIndestructibleRegistry, + "registerAsIndestructible", + "send", + [constants.ADHARMA_SMART_WALLET_IMPLEMENTATION_ADDRESS] + ); + await tester.runTest( + '"actual" IndestructibleRegistry can register the Adharma key ring implementation as indestructible', + ActualIndestructibleRegistry, + "registerAsIndestructible", + "send", + [constants.ADHARMA_KEY_RING_IMPLEMENTATION_ADDRESS] + ); - const CodeHashCache = await tester.runTest( - `CodeHashCache contract deployment`, - CodeHashCacheDeployer, - '', - 'deploy' - ) + const CodeHashCache = await tester.runTest( + `CodeHashCache contract deployment`, + CodeHashCacheDeployer, + "", + "deploy" + ); - await tester.runTest( - 'CodeHashCache can register the runtime code hash of the smart wallet factory', - CodeHashCache, - 'registerCodeHash', - 'send', - [constants.FACTORY_ADDRESS] - ) + await tester.runTest( + "CodeHashCache can register the runtime code hash of the smart wallet factory", + CodeHashCache, + "registerCodeHash", + "send", + [constants.FACTORY_ADDRESS] + ); - // UpgradeBeaconControllerManager - const upgradeBeaconControllerManagerRuntimeCode = swapMetadataHash( - DharmaUpgradeBeaconControllerManagerArtifact.deployedBytecode, - constants.UPGRADE_BEACON_CONTROLLER_MANAGER_METADATA - ); + // UpgradeBeaconControllerManager + const upgradeBeaconControllerManagerRuntimeCode = swapMetadataHash( + DharmaUpgradeBeaconControllerManagerArtifact.deployedBytecode, + constants.UPGRADE_BEACON_CONTROLLER_MANAGER_METADATA + ); - const upgradeBeaconControllerManagerCreationCode = swapMetadataHash( - DharmaUpgradeBeaconControllerManagerArtifact.bytecode, - constants.UPGRADE_BEACON_CONTROLLER_MANAGER_METADATA - ); + const upgradeBeaconControllerManagerCreationCode = swapMetadataHash( + DharmaUpgradeBeaconControllerManagerArtifact.bytecode, + constants.UPGRADE_BEACON_CONTROLLER_MANAGER_METADATA + ); - await tester.checkAndDeploy( - "UpgradeBeaconControllerManager", - constants.UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS, - constants.UPGRADE_BEACON_CONTROLLER_MANAGER_SALT, - upgradeBeaconControllerManagerRuntimeCode, - upgradeBeaconControllerManagerCreationCode, - tester.MockCodeCheck, - ImmutableCreate2Factory - ); + await tester.checkAndDeploy( + "UpgradeBeaconControllerManager", + constants.UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS, + constants.UPGRADE_BEACON_CONTROLLER_MANAGER_SALT, + upgradeBeaconControllerManagerRuntimeCode, + upgradeBeaconControllerManagerCreationCode, + tester.MockCodeCheck, + ImmutableCreate2Factory + ); + const testIndestructibleRegistryContracts = { + DharmaSmartWalletImplementationV6, + DharmaSmartWalletImplementationV7, + DharmaKeyRingImplementationV1 + }; - const testIndestructibleRegistryContracts = { - DharmaSmartWalletImplementationV6, - DharmaSmartWalletImplementationV7, - DharmaKeyRingImplementationV1, - }; + await testIndestructibleRegistry( + tester, + testIndestructibleRegistryContracts + ); - await testIndestructibleRegistry(tester, testIndestructibleRegistryContracts); + await testDharmaUpgradeMultisigDeployer( + tester, + DharmaUpgradeMultisigDeployer + ); - await testDharmaUpgradeMultisigDeployer(tester, DharmaUpgradeMultisigDeployer); + await tester.runTest( + `DharmaUpgradeBeaconControllerManager contract deployment`, + DharmaUpgradeBeaconControllerManagerDeployer, + "", + "deploy" + ); - await tester.runTest( - `DharmaUpgradeBeaconControllerManager contract deployment`, - DharmaUpgradeBeaconControllerManagerDeployer, - '', - 'deploy' - ) + await tester.runTest( + `DharmaUpgradeBeaconControllerManager contract coverage deployment`, + DharmaUpgradeBeaconControllerManagerCoverageDeployer, + "", + "deploy" + ); - await tester.runTest( - `DharmaUpgradeBeaconControllerManager contract coverage deployment`, - DharmaUpgradeBeaconControllerManagerCoverageDeployer, - '', - 'deploy' - ) + let currentSaiCode; + await tester.runTest( + "Checking for required external contracts...", + tester.MockCodeCheck, + "code", + "call", + [constants.SAI_MAINNET_ADDRESS], + true, + value => { + currentSaiCode = value; + } + ); - let currentSaiCode; - await tester.runTest( - 'Checking for required external contracts...', - tester.MockCodeCheck, - 'code', - 'call', - [constants.SAI_MAINNET_ADDRESS], - true, - value => { - currentSaiCode = value; + if (!currentSaiCode) { + console.log( + `completed ${tester.passed + tester.failed} test${ + tester.passed + tester.failed === 1 ? "" : "s" + } ` + + `with ${tester.failed} failure${ + tester.failed === 1 ? "" : "s" + }.` + ); + + console.log( + "Note that the full test suite cannot be executed locally - instead, " + + "run against a fork of mainnet using `yarn forkStart` and `yarn test`." + ); + + if (tester.failed > 0) { + process.exit(1); + } + + // exit. + return 0; } - ) - - if (!currentSaiCode) { - console.log( - `completed ${tester.passed + tester.failed} test${tester.passed + tester.failed === 1 ? '' : 's'} ` + - `with ${tester.failed} failure${tester.failed === 1 ? '' : 's'}.` - ) console.log( - 'Note that the full test suite cannot be executed locally - instead, ' + - 'run against a fork of mainnet using `yarn forkStart` and `yarn test`.' - ) + `completed ${tester.passed + tester.failed} test${ + tester.passed + tester.failed === 1 ? "" : "s" + } ` + `with ${tester.failed} failure${tester.failed === 1 ? "" : "s"}.` + ); if (tester.failed > 0) { - process.exit(1) + process.exit(1); } // exit. - return 0 - } - - - console.log( - `completed ${tester.passed + tester.failed} test${tester.passed + tester.failed === 1 ? '' : 's'} ` + - `with ${tester.failed} failure${tester.failed === 1 ? '' : 's'}.` - ) - - if (tester.failed > 0) { - process.exit(1) - } - - // exit. - return 0 - + return 0; } module.exports = { - test, + test }; diff --git a/scripts/test/deployMockExternal.js b/scripts/test/deployMockExternal.js index 3f7590c..35dd357 100644 --- a/scripts/test/deployMockExternal.js +++ b/scripts/test/deployMockExternal.js @@ -1,5268 +1,5185 @@ -var assert = require('assert') -var fs = require('fs') -var util = require('ethereumjs-util') -const constants = require('./constants.js') +var assert = require("assert"); +var fs = require("fs"); +var util = require("ethereumjs-util"); +const constants = require("./constants.js"); -const IERC20Artifact = require('../../build/contracts/IERC20.json') -const MockSaiToDaiMigratorArtifact = require('../../build/contracts/MockSaiToDaiMigrator.json') +const IERC20Artifact = require("../../build/contracts/IERC20.json"); +const MockSaiToDaiMigratorArtifact = require("../../build/contracts/MockSaiToDaiMigrator.json"); const { web3 } = require("./web3"); -module.exports = {test: async function (testingContext) { - let passed = 0 - let failed = 0 - let gasUsage = {} - let counts = {} - - const SAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.SAI_MAINNET_ADDRESS - ) - - const DAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.DAI_MAINNET_ADDRESS - ) - - const USDC = new web3.eth.Contract( - IERC20Artifact.abi, constants.USDC_MAINNET_ADDRESS - ) - - const CDAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.CDAI_MAINNET_ADDRESS - ) - - const CSAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.CSAI_MAINNET_ADDRESS - ) - - const CUSDC = new web3.eth.Contract( - IERC20Artifact.abi, constants.CUSDC_MAINNET_ADDRESS - ) - - const MockSaiToDaiMigrator = new web3.eth.Contract( - MockSaiToDaiMigratorArtifact.abi, constants.DAI_MIGRATOR_MAINNET_ADDRESS - ) - - const UNITROLLER = new web3.eth.Contract( - [ - { - "constant": true, - "inputs": [ - - ], - "name": "pendingAdmin", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newPendingAdmin", - "type": "address" - } - ], - "name": "_setPendingAdmin", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "comptrollerImplementation", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - - ], - "name": "_acceptImplementation", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "pendingComptrollerImplementation", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newPendingImplementation", - "type": "address" - } - ], - "name": "_setPendingImplementation", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - - ], - "name": "_acceptAdmin", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "admin", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "payable": true, - "stateMutability": "payable", - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "oldPendingImplementation", - "type": "address" - }, - { - "indexed": false, - "name": "newPendingImplementation", - "type": "address" - } - ], - "name": "NewPendingImplementation", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "oldImplementation", - "type": "address" - }, - { - "indexed": false, - "name": "newImplementation", - "type": "address" - } - ], - "name": "NewImplementation", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "oldPendingAdmin", - "type": "address" - }, - { - "indexed": false, - "name": "newPendingAdmin", - "type": "address" - } - ], - "name": "NewPendingAdmin", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "oldAdmin", - "type": "address" - }, - { - "indexed": false, - "name": "newAdmin", - "type": "address" - } - ], - "name": "NewAdmin", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "error", - "type": "uint256" - }, - { - "indexed": false, - "name": "info", - "type": "uint256" - }, - { - "indexed": false, - "name": "detail", - "type": "uint256" - } - ], - "name": "Failure", - "type": "event" - } - ], - constants.COMPTROLLER_MAINNET_ADDRESS - ) - - const FIAT_TOKEN = new web3.eth.Contract( - [ - { - "constant": true, - "inputs": [ - - ], - "name": "name", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_spender", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_account", - "type": "address" - } - ], - "name": "unBlacklist", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_from", - "type": "address" - }, - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "minter", - "type": "address" - } - ], - "name": "removeMinter", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "decimals", - "outputs": [ - { - "name": "", - "type": "uint8" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_name", - "type": "string" - }, - { - "name": "_symbol", - "type": "string" - }, - { - "name": "_currency", - "type": "string" - }, - { - "name": "_decimals", - "type": "uint8" - }, - { - "name": "_masterMinter", - "type": "address" - }, - { - "name": "_pauser", - "type": "address" - }, - { - "name": "_blacklister", - "type": "address" - }, - { - "name": "_owner", - "type": "address" - } - ], - "name": "initialize", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "masterMinter", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - - ], - "name": "unpause", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_to", - "type": "address" - }, - { - "name": "_amount", - "type": "uint256" - } - ], - "name": "mint", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_amount", - "type": "uint256" - } - ], - "name": "burn", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "minter", - "type": "address" - }, - { - "name": "minterAllowedAmount", - "type": "uint256" - } - ], - "name": "configureMinter", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_newPauser", - "type": "address" - } - ], - "name": "updatePauser", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "paused", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "account", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - - ], - "name": "pause", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "minter", - "type": "address" - } - ], - "name": "minterAllowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "owner", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "symbol", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "pauser", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_newMasterMinter", - "type": "address" - } - ], - "name": "updateMasterMinter", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "account", - "type": "address" - } - ], - "name": "isMinter", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_newBlacklister", - "type": "address" - } - ], - "name": "updateBlacklister", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "blacklister", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "owner", - "type": "address" - }, - { - "name": "spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "currency", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_account", - "type": "address" - } - ], - "name": "blacklist", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_account", - "type": "address" - } - ], - "name": "isBlacklisted", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "minter", - "type": "address" - }, - { - "indexed": true, - "name": "to", - "type": "address" - }, - { - "indexed": false, - "name": "amount", - "type": "uint256" - } - ], - "name": "Mint", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "burner", - "type": "address" - }, - { - "indexed": false, - "name": "amount", - "type": "uint256" - } - ], - "name": "Burn", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "minter", - "type": "address" - }, - { - "indexed": false, - "name": "minterAllowedAmount", - "type": "uint256" - } - ], - "name": "MinterConfigured", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "oldMinter", - "type": "address" - } - ], - "name": "MinterRemoved", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "newMasterMinter", - "type": "address" - } - ], - "name": "MasterMinterChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_account", - "type": "address" - } - ], - "name": "Blacklisted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_account", - "type": "address" - } - ], - "name": "UnBlacklisted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "newBlacklister", - "type": "address" - } - ], - "name": "BlacklisterChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - - ], - "name": "Pause", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - - ], - "name": "Unpause", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "newAddress", - "type": "address" - } - ], - "name": "PauserChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "previousOwner", - "type": "address" - }, - { - "indexed": false, - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "from", - "type": "address" - }, - { - "indexed": true, - "name": "to", - "type": "address" - }, - { - "indexed": false, - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - } - ], - constants.USDC_MAINNET_ADDRESS - ) - - const COMPTROLLER_ABI = [ - { - "constant": true, - "inputs": [ - - ], - "name": "isComptroller", - "outputs": [ - { - "name": "", - "type": "bool" +module.exports = { + test: async function(testingContext) { + let passed = 0; + let failed = 0; + let gasUsage = {}; + let counts = {}; + + const SAI = new web3.eth.Contract( + IERC20Artifact.abi, + constants.SAI_MAINNET_ADDRESS + ); + + const DAI = new web3.eth.Contract( + IERC20Artifact.abi, + constants.DAI_MAINNET_ADDRESS + ); + + const USDC = new web3.eth.Contract( + IERC20Artifact.abi, + constants.USDC_MAINNET_ADDRESS + ); + + const CDAI = new web3.eth.Contract( + IERC20Artifact.abi, + constants.CDAI_MAINNET_ADDRESS + ); + + const CSAI = new web3.eth.Contract( + IERC20Artifact.abi, + constants.CSAI_MAINNET_ADDRESS + ); + + const CUSDC = new web3.eth.Contract( + IERC20Artifact.abi, + constants.CUSDC_MAINNET_ADDRESS + ); + + const MockSaiToDaiMigrator = new web3.eth.Contract( + MockSaiToDaiMigratorArtifact.abi, + constants.DAI_MIGRATOR_MAINNET_ADDRESS + ); + + const UNITROLLER = new web3.eth.Contract( + [ + { + constant: true, + inputs: [], + name: "pendingAdmin", + outputs: [ + { + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "newPendingAdmin", + type: "address" + } + ], + name: "_setPendingAdmin", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "comptrollerImplementation", + outputs: [ + { + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [], + name: "_acceptImplementation", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "pendingComptrollerImplementation", + outputs: [ + { + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "newPendingImplementation", + type: "address" + } + ], + name: "_setPendingImplementation", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [], + name: "_acceptAdmin", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "admin", + outputs: [ + { + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + inputs: [], + payable: false, + stateMutability: "nonpayable", + type: "constructor" + }, + { + payable: true, + stateMutability: "payable", + type: "fallback" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: "oldPendingImplementation", + type: "address" + }, + { + indexed: false, + name: "newPendingImplementation", + type: "address" + } + ], + name: "NewPendingImplementation", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: "oldImplementation", + type: "address" + }, + { + indexed: false, + name: "newImplementation", + type: "address" + } + ], + name: "NewImplementation", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: "oldPendingAdmin", + type: "address" + }, + { + indexed: false, + name: "newPendingAdmin", + type: "address" + } + ], + name: "NewPendingAdmin", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: "oldAdmin", + type: "address" + }, + { + indexed: false, + name: "newAdmin", + type: "address" + } + ], + name: "NewAdmin", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: "error", + type: "uint256" + }, + { + indexed: false, + name: "info", + type: "uint256" + }, + { + indexed: false, + name: "detail", + type: "uint256" + } + ], + name: "Failure", + type: "event" + } + ], + constants.COMPTROLLER_MAINNET_ADDRESS + ); + + const FIAT_TOKEN = new web3.eth.Contract( + [ + { + constant: true, + inputs: [], + name: "name", + outputs: [ + { + name: "", + type: "string" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_spender", + type: "address" + }, + { + name: "_value", + type: "uint256" + } + ], + name: "approve", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "totalSupply", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_account", + type: "address" + } + ], + name: "unBlacklist", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_from", + type: "address" + }, + { + name: "_to", + type: "address" + }, + { + name: "_value", + type: "uint256" + } + ], + name: "transferFrom", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "minter", + type: "address" + } + ], + name: "removeMinter", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "decimals", + outputs: [ + { + name: "", + type: "uint8" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_name", + type: "string" + }, + { + name: "_symbol", + type: "string" + }, + { + name: "_currency", + type: "string" + }, + { + name: "_decimals", + type: "uint8" + }, + { + name: "_masterMinter", + type: "address" + }, + { + name: "_pauser", + type: "address" + }, + { + name: "_blacklister", + type: "address" + }, + { + name: "_owner", + type: "address" + } + ], + name: "initialize", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "masterMinter", + outputs: [ + { + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [], + name: "unpause", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_to", + type: "address" + }, + { + name: "_amount", + type: "uint256" + } + ], + name: "mint", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_amount", + type: "uint256" + } + ], + name: "burn", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "minter", + type: "address" + }, + { + name: "minterAllowedAmount", + type: "uint256" + } + ], + name: "configureMinter", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_newPauser", + type: "address" + } + ], + name: "updatePauser", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "paused", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "account", + type: "address" + } + ], + name: "balanceOf", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [], + name: "pause", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "minter", + type: "address" + } + ], + name: "minterAllowance", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "owner", + outputs: [ + { + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "symbol", + outputs: [ + { + name: "", + type: "string" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "pauser", + outputs: [ + { + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_to", + type: "address" + }, + { + name: "_value", + type: "uint256" + } + ], + name: "transfer", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_newMasterMinter", + type: "address" + } + ], + name: "updateMasterMinter", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "account", + type: "address" + } + ], + name: "isMinter", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_newBlacklister", + type: "address" + } + ], + name: "updateBlacklister", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "blacklister", + outputs: [ + { + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "owner", + type: "address" + }, + { + name: "spender", + type: "address" + } + ], + name: "allowance", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "currency", + outputs: [ + { + name: "", + type: "string" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "newOwner", + type: "address" + } + ], + name: "transferOwnership", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "_account", + type: "address" + } + ], + name: "blacklist", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "_account", + type: "address" + } + ], + name: "isBlacklisted", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "minter", + type: "address" + }, + { + indexed: true, + name: "to", + type: "address" + }, + { + indexed: false, + name: "amount", + type: "uint256" + } + ], + name: "Mint", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "burner", + type: "address" + }, + { + indexed: false, + name: "amount", + type: "uint256" + } + ], + name: "Burn", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "minter", + type: "address" + }, + { + indexed: false, + name: "minterAllowedAmount", + type: "uint256" + } + ], + name: "MinterConfigured", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "oldMinter", + type: "address" + } + ], + name: "MinterRemoved", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "newMasterMinter", + type: "address" + } + ], + name: "MasterMinterChanged", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "_account", + type: "address" + } + ], + name: "Blacklisted", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "_account", + type: "address" + } + ], + name: "UnBlacklisted", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "newBlacklister", + type: "address" + } + ], + name: "BlacklisterChanged", + type: "event" + }, + { + anonymous: false, + inputs: [], + name: "Pause", + type: "event" + }, + { + anonymous: false, + inputs: [], + name: "Unpause", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "newAddress", + type: "address" + } + ], + name: "PauserChanged", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "owner", + type: "address" + }, + { + indexed: true, + name: "spender", + type: "address" + }, + { + indexed: false, + name: "value", + type: "uint256" + } + ], + name: "Approval", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: "previousOwner", + type: "address" + }, + { + indexed: false, + name: "newOwner", + type: "address" + } + ], + name: "OwnershipTransferred", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "from", + type: "address" + }, + { + indexed: true, + name: "to", + type: "address" + }, + { + indexed: false, + name: "value", + type: "uint256" + } + ], + name: "Transfer", + type: "event" + } + ], + constants.USDC_MAINNET_ADDRESS + ); + + const COMPTROLLER_ABI = [ + { + constant: true, + inputs: [], + name: "isComptroller", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cToken", + type: "address" + }, + { + name: "payer", + type: "address" + }, + { + name: "borrower", + type: "address" + }, + { + name: "repayAmount", + type: "uint256" + }, + { + name: "borrowerIndex", + type: "uint256" + } + ], + name: "repayBorrowVerify", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cToken", + type: "address" + }, + { + name: "payer", + type: "address" + }, + { + name: "borrower", + type: "address" + }, + { + name: "repayAmount", + type: "uint256" + } + ], + name: "repayBorrowAllowed", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "pendingAdmin", + outputs: [ + { + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "newCloseFactorMantissa", + type: "uint256" + } + ], + name: "_setCloseFactor", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "unitroller", + type: "address" + }, + { + name: "_oracle", + type: "address" + }, + { + name: "_closeFactorMantissa", + type: "uint256" + }, + { + name: "_maxAssets", + type: "uint256" + }, + { + name: "reinitializing", + type: "bool" + } + ], + name: "_become", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cToken", + type: "address" + }, + { + name: "minter", + type: "address" + }, + { + name: "mintAmount", + type: "uint256" + }, + { + name: "mintTokens", + type: "uint256" + } + ], + name: "mintVerify", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cTokenBorrowed", + type: "address" + }, + { + name: "cTokenCollateral", + type: "address" + }, + { + name: "liquidator", + type: "address" + }, + { + name: "borrower", + type: "address" + }, + { + name: "repayAmount", + type: "uint256" + }, + { + name: "seizeTokens", + type: "uint256" + } + ], + name: "liquidateBorrowVerify", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "liquidationIncentiveMantissa", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cToken", + type: "address" + }, + { + name: "minter", + type: "address" + }, + { + name: "mintAmount", + type: "uint256" + } + ], + name: "mintAllowed", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "newLiquidationIncentiveMantissa", + type: "uint256" + } + ], + name: "_setLiquidationIncentive", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cToken", + type: "address" + }, + { + name: "redeemer", + type: "address" + }, + { + name: "redeemAmount", + type: "uint256" + }, + { + name: "redeemTokens", + type: "uint256" + } + ], + name: "redeemVerify", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "newOracle", + type: "address" + } + ], + name: "_setPriceOracle", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cToken", + type: "address" + }, + { + name: "borrower", + type: "address" + }, + { + name: "borrowAmount", + type: "uint256" + } + ], + name: "borrowVerify", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "account", + type: "address" + } + ], + name: "getAccountLiquidity", + outputs: [ + { + name: "", + type: "uint256" + }, + { + name: "", + type: "uint256" + }, + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cTokenBorrowed", + type: "address" + }, + { + name: "cTokenCollateral", + type: "address" + }, + { + name: "liquidator", + type: "address" + }, + { + name: "borrower", + type: "address" + }, + { + name: "repayAmount", + type: "uint256" + } + ], + name: "liquidateBorrowAllowed", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cToken", + type: "address" + }, + { + name: "src", + type: "address" + }, + { + name: "dst", + type: "address" + }, + { + name: "transferTokens", + type: "uint256" + } + ], + name: "transferVerify", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cTokenCollateral", + type: "address" + }, + { + name: "cTokenBorrowed", + type: "address" + }, + { + name: "liquidator", + type: "address" + }, + { + name: "borrower", + type: "address" + }, + { + name: "seizeTokens", + type: "uint256" + } + ], + name: "seizeVerify", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "oracle", + outputs: [ + { + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "", + type: "address" + } + ], + name: "markets", + outputs: [ + { + name: "isListed", + type: "bool" + }, + { + name: "collateralFactorMantissa", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "account", + type: "address" + }, + { + name: "cToken", + type: "address" + } + ], + name: "checkMembership", + outputs: [ + { + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "maxAssets", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cToken", + type: "address" + } + ], + name: "_supportMarket", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "account", + type: "address" + } + ], + name: "getAssetsIn", + outputs: [ + { + name: "", + type: "address[]" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "comptrollerImplementation", + outputs: [ + { + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cToken", + type: "address" + }, + { + name: "src", + type: "address" + }, + { + name: "dst", + type: "address" + }, + { + name: "transferTokens", + type: "uint256" + } + ], + name: "transferAllowed", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cTokens", + type: "address[]" + } + ], + name: "enterMarkets", + outputs: [ + { + name: "", + type: "uint256[]" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "cTokenBorrowed", + type: "address" + }, + { + name: "cTokenCollateral", + type: "address" + }, + { + name: "repayAmount", + type: "uint256" + } + ], + name: "liquidateCalculateSeizeTokens", + outputs: [ + { + name: "", + type: "uint256" + }, + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cTokenCollateral", + type: "address" + }, + { + name: "cTokenBorrowed", + type: "address" + }, + { + name: "liquidator", + type: "address" + }, + { + name: "borrower", + type: "address" + }, + { + name: "seizeTokens", + type: "uint256" + } + ], + name: "seizeAllowed", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "newMaxAssets", + type: "uint256" + } + ], + name: "_setMaxAssets", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cToken", + type: "address" + }, + { + name: "borrower", + type: "address" + }, + { + name: "borrowAmount", + type: "uint256" + } + ], + name: "borrowAllowed", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + name: "", + type: "address" + }, + { + name: "", + type: "uint256" + } + ], + name: "accountAssets", + outputs: [ + { + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "pendingComptrollerImplementation", + outputs: [ + { + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cToken", + type: "address" + }, + { + name: "newCollateralFactorMantissa", + type: "uint256" + } + ], + name: "_setCollateralFactor", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "closeFactorMantissa", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cToken", + type: "address" + }, + { + name: "redeemer", + type: "address" + }, + { + name: "redeemTokens", + type: "uint256" + } + ], + name: "redeemAllowed", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + name: "cTokenAddress", + type: "address" + } + ], + name: "exitMarket", + outputs: [ + { + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "admin", + outputs: [ + { + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + inputs: [], + payable: false, + stateMutability: "nonpayable", + type: "constructor" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: "cToken", + type: "address" + } + ], + name: "MarketListed", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: "cToken", + type: "address" + }, + { + indexed: false, + name: "account", + type: "address" + } + ], + name: "MarketEntered", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: "cToken", + type: "address" + }, + { + indexed: false, + name: "account", + type: "address" + } + ], + name: "MarketExited", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: "oldCloseFactorMantissa", + type: "uint256" + }, + { + indexed: false, + name: "newCloseFactorMantissa", + type: "uint256" + } + ], + name: "NewCloseFactor", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: "cToken", + type: "address" + }, + { + indexed: false, + name: "oldCollateralFactorMantissa", + type: "uint256" + }, + { + indexed: false, + name: "newCollateralFactorMantissa", + type: "uint256" + } + ], + name: "NewCollateralFactor", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: "oldLiquidationIncentiveMantissa", + type: "uint256" + }, + { + indexed: false, + name: "newLiquidationIncentiveMantissa", + type: "uint256" + } + ], + name: "NewLiquidationIncentive", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: "oldMaxAssets", + type: "uint256" + }, + { + indexed: false, + name: "newMaxAssets", + type: "uint256" + } + ], + name: "NewMaxAssets", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: "oldPriceOracle", + type: "address" + }, + { + indexed: false, + name: "newPriceOracle", + type: "address" + } + ], + name: "NewPriceOracle", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + name: "error", + type: "uint256" + }, + { + indexed: false, + name: "info", + type: "uint256" + }, + { + indexed: false, + name: "detail", + type: "uint256" + } + ], + name: "Failure", + type: "event" + } + ]; + + // get available addresses and assign them to various roles + const addresses = await web3.eth.getAccounts(); + if (addresses.length < 1) { + console.log("cannot find enough addresses to run tests!"); + process.exit(1); } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cToken", - "type": "address" - }, - { - "name": "payer", - "type": "address" - }, - { - "name": "borrower", - "type": "address" - }, - { - "name": "repayAmount", - "type": "uint256" - }, - { - "name": "borrowerIndex", - "type": "uint256" - } - ], - "name": "repayBorrowVerify", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cToken", - "type": "address" - }, - { - "name": "payer", - "type": "address" - }, - { - "name": "borrower", - "type": "address" - }, - { - "name": "repayAmount", - "type": "uint256" - } - ], - "name": "repayBorrowAllowed", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "pendingAdmin", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newCloseFactorMantissa", - "type": "uint256" - } - ], - "name": "_setCloseFactor", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "unitroller", - "type": "address" - }, - { - "name": "_oracle", - "type": "address" - }, - { - "name": "_closeFactorMantissa", - "type": "uint256" - }, - { - "name": "_maxAssets", - "type": "uint256" - }, - { - "name": "reinitializing", - "type": "bool" - } - ], - "name": "_become", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cToken", - "type": "address" - }, - { - "name": "minter", - "type": "address" - }, - { - "name": "mintAmount", - "type": "uint256" - }, - { - "name": "mintTokens", - "type": "uint256" - } - ], - "name": "mintVerify", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cTokenBorrowed", - "type": "address" - }, - { - "name": "cTokenCollateral", - "type": "address" - }, - { - "name": "liquidator", - "type": "address" - }, - { - "name": "borrower", - "type": "address" - }, - { - "name": "repayAmount", - "type": "uint256" - }, - { - "name": "seizeTokens", - "type": "uint256" - } - ], - "name": "liquidateBorrowVerify", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "liquidationIncentiveMantissa", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cToken", - "type": "address" - }, - { - "name": "minter", - "type": "address" - }, - { - "name": "mintAmount", - "type": "uint256" - } - ], - "name": "mintAllowed", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newLiquidationIncentiveMantissa", - "type": "uint256" - } - ], - "name": "_setLiquidationIncentive", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cToken", - "type": "address" - }, - { - "name": "redeemer", - "type": "address" - }, - { - "name": "redeemAmount", - "type": "uint256" - }, - { - "name": "redeemTokens", - "type": "uint256" - } - ], - "name": "redeemVerify", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newOracle", - "type": "address" - } - ], - "name": "_setPriceOracle", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cToken", - "type": "address" - }, - { - "name": "borrower", - "type": "address" - }, - { - "name": "borrowAmount", - "type": "uint256" - } - ], - "name": "borrowVerify", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "account", - "type": "address" - } - ], - "name": "getAccountLiquidity", - "outputs": [ - { - "name": "", - "type": "uint256" - }, - { - "name": "", - "type": "uint256" - }, - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cTokenBorrowed", - "type": "address" - }, - { - "name": "cTokenCollateral", - "type": "address" - }, - { - "name": "liquidator", - "type": "address" - }, - { - "name": "borrower", - "type": "address" - }, - { - "name": "repayAmount", - "type": "uint256" - } - ], - "name": "liquidateBorrowAllowed", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cToken", - "type": "address" - }, - { - "name": "src", - "type": "address" - }, - { - "name": "dst", - "type": "address" - }, - { - "name": "transferTokens", - "type": "uint256" - } - ], - "name": "transferVerify", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cTokenCollateral", - "type": "address" - }, - { - "name": "cTokenBorrowed", - "type": "address" - }, - { - "name": "liquidator", - "type": "address" - }, - { - "name": "borrower", - "type": "address" - }, - { - "name": "seizeTokens", - "type": "uint256" - } - ], - "name": "seizeVerify", - "outputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "oracle", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "markets", - "outputs": [ - { - "name": "isListed", - "type": "bool" - }, - { - "name": "collateralFactorMantissa", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "account", - "type": "address" - }, - { - "name": "cToken", - "type": "address" - } - ], - "name": "checkMembership", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "maxAssets", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cToken", - "type": "address" - } - ], - "name": "_supportMarket", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "account", - "type": "address" - } - ], - "name": "getAssetsIn", - "outputs": [ - { - "name": "", - "type": "address[]" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "comptrollerImplementation", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cToken", - "type": "address" - }, - { - "name": "src", - "type": "address" - }, - { - "name": "dst", - "type": "address" - }, - { - "name": "transferTokens", - "type": "uint256" - } - ], - "name": "transferAllowed", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cTokens", - "type": "address[]" - } - ], - "name": "enterMarkets", - "outputs": [ - { - "name": "", - "type": "uint256[]" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "cTokenBorrowed", - "type": "address" - }, - { - "name": "cTokenCollateral", - "type": "address" - }, - { - "name": "repayAmount", - "type": "uint256" - } - ], - "name": "liquidateCalculateSeizeTokens", - "outputs": [ - { - "name": "", - "type": "uint256" - }, - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cTokenCollateral", - "type": "address" - }, - { - "name": "cTokenBorrowed", - "type": "address" - }, - { - "name": "liquidator", - "type": "address" - }, - { - "name": "borrower", - "type": "address" - }, - { - "name": "seizeTokens", - "type": "uint256" - } - ], - "name": "seizeAllowed", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newMaxAssets", - "type": "uint256" - } - ], - "name": "_setMaxAssets", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cToken", - "type": "address" - }, - { - "name": "borrower", - "type": "address" - }, - { - "name": "borrowAmount", - "type": "uint256" - } - ], - "name": "borrowAllowed", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "uint256" - } - ], - "name": "accountAssets", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "pendingComptrollerImplementation", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cToken", - "type": "address" - }, - { - "name": "newCollateralFactorMantissa", - "type": "uint256" - } - ], - "name": "_setCollateralFactor", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "closeFactorMantissa", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cToken", - "type": "address" - }, - { - "name": "redeemer", - "type": "address" - }, - { - "name": "redeemTokens", - "type": "uint256" - } - ], - "name": "redeemAllowed", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "cTokenAddress", - "type": "address" - } - ], - "name": "exitMarket", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - - ], - "name": "admin", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "cToken", - "type": "address" - } - ], - "name": "MarketListed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "cToken", - "type": "address" - }, - { - "indexed": false, - "name": "account", - "type": "address" - } - ], - "name": "MarketEntered", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "cToken", - "type": "address" - }, - { - "indexed": false, - "name": "account", - "type": "address" - } - ], - "name": "MarketExited", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "oldCloseFactorMantissa", - "type": "uint256" - }, - { - "indexed": false, - "name": "newCloseFactorMantissa", - "type": "uint256" - } - ], - "name": "NewCloseFactor", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "cToken", - "type": "address" - }, - { - "indexed": false, - "name": "oldCollateralFactorMantissa", - "type": "uint256" - }, - { - "indexed": false, - "name": "newCollateralFactorMantissa", - "type": "uint256" - } - ], - "name": "NewCollateralFactor", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "oldLiquidationIncentiveMantissa", - "type": "uint256" - }, - { - "indexed": false, - "name": "newLiquidationIncentiveMantissa", - "type": "uint256" - } - ], - "name": "NewLiquidationIncentive", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "oldMaxAssets", - "type": "uint256" - }, - { - "indexed": false, - "name": "newMaxAssets", - "type": "uint256" - } - ], - "name": "NewMaxAssets", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "oldPriceOracle", - "type": "address" - }, - { - "indexed": false, - "name": "newPriceOracle", - "type": "address" - } - ], - "name": "NewPriceOracle", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "error", - "type": "uint256" - }, - { - "indexed": false, - "name": "info", - "type": "uint256" - }, - { - "indexed": false, - "name": "detail", - "type": "uint256" + + let latestBlock = await web3.eth.getBlock("latest"); + + const originalAddress = addresses[0]; + + let address = await setupNewDefaultAddress( + "0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed" + ); + + let addressTwo = await setupNewDefaultAddress( + "0xf00df00df00df00df00df00df00df00df00df00df00df00df00df00df00df00d" + ); + + const gasLimit = latestBlock.gasLimit; + + // 0x43Af172dFC1017c775D789f5B6cDD375E3D8Fe14 + // primary address, nonce: 0 + const mockPriceOracleDeploymentData = + "0x608060405234801561001057600080fd5b5060cd8061001f6000396000f3fe60806040" + + "52348015600f57600080fd5b506004361060325760003560e01c806366331bba14603757" + + "8063fc57d4df146051575b600080fd5b603d6086565b6040805191151582525190819003" + + "60200190f35b607460048036036020811015606557600080fd5b50356001600160a01b03" + + "16608b565b60408051918252519081900360200190f35b600190565b50670de0b6b3a764" + + "00009056fea265627a7a72315820cf3b4d1c8f3041ebb02fbc6b404dd54636a41af89e8a" + + "04ea19bf35f04b48fae764736f6c634300050b0032"; + + // 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359 + // nonce: 4 + const mockDaiDeploymentData = + "0x608060405234801561001057600080fd5b5060405160208061085d8339810180604052" + + "810190808051906020019092919050505080600160003373ffffffffffffffffffffffff" + + "ffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001" + + "9081526020016000208190555080600081905550506107cf8061008e6000396000f30060" + + "8060405260043610610078576000357c0100000000000000000000000000000000000000" + + "000000000000000000900463ffffffff168063095ea7b31461007d57806318160ddd1461" + + "00e257806323b872dd1461010d57806370a0823114610192578063a9059cbb146101e957" + + "8063dd62ed3e1461024e575b600080fd5b34801561008957600080fd5b506100c8600480" + + "360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092" + + "9190803590602001909291905050506102c5565b60405180821515151581526020019150" + + "5060405180910390f35b3480156100ee57600080fd5b506100f76103b7565b6040518082" + + "815260200191505060405180910390f35b34801561011957600080fd5b50610178600480" + + "360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092" + + "9190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035" + + "90602001909291905050506103c0565b6040518082151515158152602001915050604051" + + "80910390f35b34801561019e57600080fd5b506101d3600480360381019080803573ffff" + + "ffffffffffffffffffffffffffffffffffff169060200190929190505050610686565b60" + + "40518082815260200191505060405180910390f35b3480156101f557600080fd5b506102" + + "34600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060" + + "200190929190803590602001909291905050506106cf565b604051808215151515815260" + + "200191505060405180910390f35b34801561025a57600080fd5b506102af600480360381" + + "019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080" + + "3573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506106" + + "e4565b6040518082815260200191505060405180910390f35b600081600260003373ffff" + + "ffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffff" + + "ffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffff" + + "ffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190" + + "8152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff1633" + + "73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d" + + "1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405180828152602001915050604051" + + "80910390a36001905092915050565b60008054905090565b60003373ffffffffffffffff" + + "ffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16" + + "1415156104fe5761047d600260008673ffffffffffffffffffffffffffffffffffffffff" + + "1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000" + + "2060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffff" + + "ffffffffffffffffffffff168152602001908152602001600020548361076b565b600260" + + "008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffff" + + "ffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffff" + + "ffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681" + + "52602001908152602001600020819055505b610547600160008673ffffffffffffffffff" + + "ffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152" + + "602001908152602001600020548361076b565b600160008673ffffffffffffffffffffff" + + "ffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020" + + "01908152602001600020819055506105d3600160008573ffffffffffffffffffffffffff" + + "ffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190" + + "81526020016000205483610787565b600160008573ffffffffffffffffffffffffffffff" + + "ffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152" + + "602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ff" + + "ffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378d" + + "aa952ba7f163c4a11628f55a4df523b3ef84604051808281526020019150506040518091" + + "0390a3600190509392505050565b6000600160008373ffffffffffffffffffffffffffff" + + "ffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081" + + "52602001600020549050919050565b60006106dc3384846103c0565b905092915050565b" + + "6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffff" + + "ffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffff" + + "ffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffff" + + "ffffff16815260200190815260200160002054905092915050565b600082828403915081" + + "1115151561078157600080fd5b92915050565b6000828284019150811015151561079d57" + + "600080fd5b929150505600a165627a7a72305820b4ab3c13e840dd08d9787883bde3458d" + + "cbab9a56f185c55a59574286095eb6e80029f00000000000000000000000000000000000" + + "0000000000000000000000000000"; + + // 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 + // nonce: 20 + const mockUSDCDeploymentData = + "0x60806040526000600460146101000a81548160ff021916908315150217905550600060" + + "0e5561003c33610041640100000000026401000000009004565b610084565b8060008061" + + "01000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffff" + + "ffffffffffffffffffffffffffffffffff16021790555050565b6135c580620000946000" + + "396000f3006080604052600436106101a1576000357c0100000000000000000000000000" + + "000000000000000000000000000000900463ffffffff16806306fdde03146101a6578063" + + "095ea7b31461023657806318160ddd1461029b5780631a895266146102c657806323b872" + + "dd146103095780633092afd51461038e578063313ce567146103e95780633357162b1461" + + "041a57806335d99f351461059c57806339509351146105f35780633f4ba83a1461065857" + + "806340c10f191461066f57806342966c68146106d45780634e44d9561461070157806355" + + "4bab3c146107665780635c975abb146107a957806370a08231146107d85780638456cb59" + + "1461082f5780638a6db9c3146108465780638da5cb5b1461089d57806395d89b41146108" + + "f45780639fd0506d14610984578063a457c2d7146109db578063a9059cbb14610a405780" + + "63aa20e1e414610aa5578063aa271e1a14610ae8578063ad38bf2214610b43578063bd10" + + "243014610b86578063dd62ed3e14610bdd578063e5a6b10f14610c54578063f2fde38b14" + + "610ce4578063f9f92be414610d27578063fe575a8714610d6a575b600080fd5b34801561" + + "01b257600080fd5b506101bb610dc5565b60405180806020018281038252838181518152" + + "60200191508051906020019080838360005b838110156101fb5780820151818401526020" + + "810190506101e0565b50505050905090810190601f168015610228578082038051600183" + + "6020036101000a031916815260200191505b509250505060405180910390f35b34801561" + + "024257600080fd5b50610281600480360381019080803573ffffffffffffffffffffffff" + + "ffffffffffffffff16906020019092919080359060200190929190505050610e63565b60" + + "4051808215151515815260200191505060405180910390f35b3480156102a757600080fd" + + "5b506102b0611033565b6040518082815260200191505060405180910390f35b34801561" + + "02d257600080fd5b50610307600480360381019080803573ffffffffffffffffffffffff" + + "ffffffffffffffff16906020019092919050505061103d565b005b348015610315576000" + + "80fd5b50610374600480360381019080803573ffffffffffffffffffffffffffffffffff" + + "ffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16" + + "906020019092919080359060200190929190505050611137565b60405180821515151581" + + "5260200191505060405180910390f35b34801561039a57600080fd5b506103cf60048036" + + "0381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291" + + "90505050611636565b604051808215151515815260200191505060405180910390f35b34" + + "80156103f557600080fd5b506103fe61177d565b604051808260ff1660ff168152602001" + + "91505060405180910390f35b34801561042657600080fd5b5061059a6004803603810190" + + "80803590602001908201803590602001908080601f016020809104026020016040519081" + + "016040528093929190818152602001838380828437820191505050505050919291929080" + + "3590602001908201803590602001908080601f0160208091040260200160405190810160" + + "405280939291908181526020018383808284378201915050505050509192919290803590" + + "602001908201803590602001908080601f01602080910402602001604051908101604052" + + "80939291908181526020018383808284378201915050505050509192919290803560ff16" + + "9060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001" + + "90929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190" + + "803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ff" + + "ffffffffffffffffffffffffffffffffffffff169060200190929190505050611790565b" + + "005b3480156105a857600080fd5b506105b16119ed565b604051808273ffffffffffffff" + + "ffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16" + + "815260200191505060405180910390f35b3480156105ff57600080fd5b5061063e600480" + + "360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092" + + "919080359060200190929190505050611a13565b60405180821515151581526020019150" + + "5060405180910390f35b34801561066457600080fd5b5061066d611ab8565b005b348015" + + "61067b57600080fd5b506106ba600480360381019080803573ffffffffffffffffffffff" + + "ffffffffffffffffff16906020019092919080359060200190929190505050611b5d565b" + + "604051808215151515815260200191505060405180910390f35b3480156106e057600080" + + "fd5b506106ff60048036038101908080359060200190929190505050611eff565b005b34" + + "801561070d57600080fd5b5061074c600480360381019080803573ffffffffffffffffff" + + "ffffffffffffffffffffff16906020019092919080359060200190929190505050612166" + + "565b604051808215151515815260200191505060405180910390f35b3480156107725760" + + "0080fd5b506107a7600480360381019080803573ffffffffffffffffffffffffffffffff" + + "ffffffff1690602001909291905050506122d4565b005b3480156107b557600080fd5b50" + + "6107be6123fa565b604051808215151515815260200191505060405180910390f35b3480" + + "156107e457600080fd5b50610819600480360381019080803573ffffffffffffffffffff" + + "ffffffffffffffffffff16906020019092919050505061240d565b604051808281526020" + + "0191505060405180910390f35b34801561083b57600080fd5b50610844612456565b005b" + + "34801561085257600080fd5b50610887600480360381019080803573ffffffffffffffff" + + "ffffffffffffffffffffffff1690602001909291905050506124fb565b60405180828152" + + "60200191505060405180910390f35b3480156108a957600080fd5b506108b2612544565b" + + "604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffff" + + "ffffffffffffffffffffffff16815260200191505060405180910390f35b348015610900" + + "57600080fd5b5061090961256d565b604051808060200182810382528381815181526020" + + "0191508051906020019080838360005b8381101561094957808201518184015260208101" + + "905061092e565b50505050905090810190601f1680156109765780820380516001836020" + + "036101000a031916815260200191505b509250505060405180910390f35b348015610990" + + "57600080fd5b5061099961260b565b604051808273ffffffffffffffffffffffffffffff" + + "ffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050" + + "60405180910390f35b3480156109e757600080fd5b50610a266004803603810190808035" + + "73ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001" + + "90929190505050612631565b604051808215151515815260200191505060405180910390" + + "f35b348015610a4c57600080fd5b50610a8b600480360381019080803573ffffffffffff" + + "ffffffffffffffffffffffffffff16906020019092919080359060200190929190505050" + + "612734565b604051808215151515815260200191505060405180910390f35b348015610a" + + "b157600080fd5b50610ae6600480360381019080803573ffffffffffffffffffffffffff" + + "ffffffffffffff169060200190929190505050612a37565b005b348015610af457600080" + + "fd5b50610b29600480360381019080803573ffffffffffffffffffffffffffffffffffff" + + "ffff169060200190929190505050612b5d565b6040518082151515158152602001915050" + + "60405180910390f35b348015610b4f57600080fd5b50610b846004803603810190808035" + + "73ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612bb3" + + "565b005b348015610b9257600080fd5b50610b9b612cd9565b604051808273ffffffffff" + + "ffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffff" + + "ff16815260200191505060405180910390f35b348015610be957600080fd5b50610c3e60" + + "0480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001" + + "90929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190" + + "505050612cff565b6040518082815260200191505060405180910390f35b348015610c60" + + "57600080fd5b50610c69612d86565b604051808060200182810382528381815181526020" + + "0191508051906020019080838360005b83811015610ca957808201518184015260208101" + + "9050610c8e565b50505050905090810190601f168015610cd65780820380516001836020" + + "036101000a031916815260200191505b509250505060405180910390f35b348015610cf0" + + "57600080fd5b50610d25600480360381019080803573ffffffffffffffffffffffffffff" + + "ffffffffffff169060200190929190505050612e24565b005b348015610d3357600080fd" + + "5b50610d68600480360381019080803573ffffffffffffffffffffffffffffffffffffff" + + "ff169060200190929190505050612f4b565b005b348015610d7657600080fd5b50610dab" + + "600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020" + + "0190929190505050613045565b6040518082151515158152602001915050604051809103" + + "90f35b60078054600181600116156101000203166002900480601f016020809104026020" + + "016040519081016040528092919081815260200182805460018160011615610100020316" + + "600290048015610e5b5780601f10610e3057610100808354040283529160200191610e5b" + + "565b820191906000526020600020905b815481529060010190602001808311610e3e5782" + + "9003601f168201915b505050505081565b6000600460149054906101000a900460ff1615" + + "1515610e8157600080fd5b3360001515600660008373ffffffffffffffffffffffffffff" + + "ffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081" + + "5260200160002060009054906101000a900460ff161515141515610ee157600080fd5b83" + + "60001515600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffff" + + "ffffffffffffffffffffffffffffffff1681526020019081526020016000206000905490" + + "6101000a900460ff161515141515610f4157600080fd5b83600d60003373ffffffffffff" + + "ffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff" + + "16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffff" + + "ffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020" + + "01600020819055508473ffffffffffffffffffffffffffffffffffffffff163373ffffff" + + "ffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd" + + "0314c0f7b2291e5b200ac8c7c3b925866040518082815260200191505060405180910390" + + "a360019250505092915050565b6000600e54905090565b600560009054906101000a9004" + + "73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffff" + + "ffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156110" + + "9957600080fd5b6000600660008373ffffffffffffffffffffffffffffffffffffffff16" + + "73ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020" + + "60006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffff" + + "ffffffffffffffffff167f117e3210bb9aa7d9baff172026820255c6f6c30ba8999d1c2f" + + "d88e2848137c4e60405160405180910390a250565b6000600460149054906101000a9004" + + "60ff1615151561115557600080fd5b8260001515600660008373ffffffffffffffffffff" + + "ffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260" + + "200190815260200160002060009054906101000a900460ff1615151415156111b5576000" + + "80fd5b3360001515600660008373ffffffffffffffffffffffffffffffffffffffff1673" + + "ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060" + + "009054906101000a900460ff16151514151561121557600080fd5b856000151560066000" + + "8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffff" + + "ffffffffffffffff16815260200190815260200160002060009054906101000a900460ff" + + "16151514151561127557600080fd5b600073ffffffffffffffffffffffffffffffffffff" + + "ffff168673ffffffffffffffffffffffffffffffffffffffff16141515156112b1576000" + + "80fd5b600c60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffff" + + "ffffffffffffffffffffffffffffff168152602001908152602001600020548511151515" + + "6112ff57600080fd5b600d60008873ffffffffffffffffffffffffffffffffffffffff16" + + "73ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020" + + "60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffff" + + "ffffffffffffffffffff16815260200190815260200160002054851115151561138a5760" + + "0080fd5b6113dc85600c60008a73ffffffffffffffffffffffffffffffffffffffff1673" + + "ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054" + + "61309b90919063ffffffff16565b600c60008973ffffffffffffffffffffffffffffffff" + + "ffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260" + + "20016000208190555061147185600c60008973ffffffffffffffffffffffffffffffffff" + + "ffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020" + + "01600020546130e590919063ffffffff16565b600c60008873ffffffffffffffffffffff" + + "ffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020" + + "019081526020016000208190555061154385600d60008a73ffffffffffffffffffffffff" + + "ffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001" + + "90815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ff" + + "ffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461" + + "309b90919063ffffffff16565b600d60008973ffffffffffffffffffffffffffffffffff" + + "ffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020" + + "0160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffff" + + "ffffffffffffffffffffffffffff168152602001908152602001600020819055508573ff" + + "ffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffff" + + "ffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4d" + + "f523b3ef876040518082815260200191505060405180910390a360019350505050939250" + + "5050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffff" + + "ffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffff" + + "ffffffffffffffffffffffffff1614151561169457600080fd5b6000600f60008473ffff" + + "ffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffff" + + "ffffffff16815260200190815260200160002060006101000a81548160ff021916908315" + + "1502179055506000601060008473ffffffffffffffffffffffffffffffffffffffff1673" + + "ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081" + + "9055508173ffffffffffffffffffffffffffffffffffffffff167fe94479a9f7e1952cc7" + + "8f2d6baab678adc1b772d936c6583def489e524cb6669260405160405180910390a26001" + + "9050919050565b600960009054906101000a900460ff1681565b600b6014905490610100" + + "0a900460ff161515156117ac57600080fd5b600073ffffffffffffffffffffffffffffff" + + "ffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141515156117e8" + + "57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffff" + + "ffffffffffffffffffffffffffffffff161415151561182457600080fd5b600073ffffff" + + "ffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffff" + + "ffffffff161415151561186057600080fd5b600073ffffffffffffffffffffffffffffff" + + "ffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561189c" + + "57600080fd5b87600790805190602001906118b29291906134f4565b5086600890805190" + + "602001906118c99291906134f4565b5085600a90805190602001906118e09291906134f4" + + "565b5084600960006101000a81548160ff021916908360ff16021790555083600b600061" + + "01000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffff" + + "ffffffffffffffffffffffffffffffffff16021790555082600460006101000a81548173" + + "ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffff" + + "ffffffffffffffffffff16021790555081600560006101000a81548173ffffffffffffff" + + "ffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffff" + + "ffffff1602179055506119c88161316f565b6001600b60146101000a81548160ff021916" + + "9083151502179055505050505050505050565b600b60009054906101000a900473ffffff" + + "ffffffffffffffffffffffffffffffffff1681565b6000611aae3384611aa98560026000" + + "3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffff" + + "ffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffff" + + "ffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152" + + "602001908152602001600020546130e590919063ffffffff16565b6131b2565b60019050" + + "92915050565b600460009054906101000a900473ffffffffffffffffffffffffffffffff" + + "ffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffff" + + "ffffffffffffffffffffffffff16141515611b1457600080fd5b6000600460146101000a" + + "81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112" + + "aca9e0847911ed832e158c525b3360405160405180910390a1565b600080600460149054" + + "906101000a900460ff16151515611b7c57600080fd5b60011515600f60003373ffffffff" + + "ffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffff" + + "ffff16815260200190815260200160002060009054906101000a900460ff161515141515" + + "611bdb57600080fd5b3360001515600660008373ffffffffffffffffffffffffffffffff" + + "ffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260" + + "200160002060009054906101000a900460ff161515141515611c3b57600080fd5b846000" + + "1515600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffff" + + "ffffffffffffffffffffffffffff16815260200190815260200160002060009054906101" + + "000a900460ff161515141515611c9b57600080fd5b600073ffffffffffffffffffffffff" + + "ffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614151515" + + "611cd757600080fd5b600085111515611ce657600080fd5b601060003373ffffffffffff" + + "ffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff" + + "168152602001908152602001600020549250828511151515611d3757600080fd5b611d4c" + + "85600e546130e590919063ffffffff16565b600e81905550611da485600c60008973ffff" + + "ffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffff" + + "ffffffff168152602001908152602001600020546130e590919063ffffffff16565b600c" + + "60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffff" + + "ffffffffffffffffffff16815260200190815260200160002081905550611dfa85846130" + + "9b90919063ffffffff16565b601060003373ffffffffffffffffffffffffffffffffffff" + + "ffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001" + + "600020819055508573ffffffffffffffffffffffffffffffffffffffff163373ffffffff" + + "ffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb253" + + "6d647574c8e7e5da92c2ede0c9f8876040518082815260200191505060405180910390a3" + + "8573ffffffffffffffffffffffffffffffffffffffff1660007fddf252ad1be2c89b69c2" + + "b068fc378daa952ba7f163c4a11628f55a4df523b3ef8760405180828152602001915050" + + "60405180910390a36001935050505092915050565b6000600460149054906101000a9004" + + "60ff16151515611f1d57600080fd5b60011515600f60003373ffffffffffffffffffffff" + + "ffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020" + + "0190815260200160002060009054906101000a900460ff161515141515611f7c57600080" + + "fd5b3360001515600660008373ffffffffffffffffffffffffffffffffffffffff1673ff" + + "ffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000" + + "9054906101000a900460ff161515141515611fdc57600080fd5b600c60003373ffffffff" + + "ffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffff" + + "ffff16815260200190815260200160002054915060008311151561202d57600080fd5b82" + + "821015151561203c57600080fd5b61205183600e5461309b90919063ffffffff16565b60" + + "0e8190555061206a838361309b90919063ffffffff16565b600c60003373ffffffffffff" + + "ffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff" + + "168152602001908152602001600020819055503373ffffffffffffffffffffffffffffff" + + "ffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d" + + "397ca5846040518082815260200191505060405180910390a2600073ffffffffffffffff" + + "ffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16" + + "7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040" + + "518082815260200191505060405180910390a3505050565b600060046014905490610100" + + "0a900460ff1615151561218457600080fd5b600b60009054906101000a900473ffffffff" + + "ffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffff" + + "ffff163373ffffffffffffffffffffffffffffffffffffffff161415156121e057600080" + + "fd5b6001600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffff" + + "ffffffffffffffffffffffffffffffff1681526020019081526020016000206000610100" + + "0a81548160ff02191690831515021790555081601060008573ffffffffffffffffffffff" + + "ffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020" + + "01908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff" + + "167f46980fca912ef9bcdbd36877427b6b90e860769f604e89c0e67720cece530d208360" + + "40518082815260200191505060405180910390a26001905092915050565b6122dc612544" + + "565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffff" + + "ffffffffffffffffffff1614151561231557600080fd5b600073ffffffffffffffffffff" + + "ffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415" + + "151561235157600080fd5b80600460006101000a81548173ffffffffffffffffffffffff" + + "ffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602" + + "17905550600460009054906101000a900473ffffffffffffffffffffffffffffffffffff" + + "ffff1673ffffffffffffffffffffffffffffffffffffffff167fb80482a293ca2e013eda" + + "8683c9bd7fc8347cfdaeea5ede58cba46df502c2a60460405160405180910390a250565b" + + "600460149054906101000a900460ff1681565b6000600c60008373ffffffffffffffffff" + + "ffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152" + + "602001908152602001600020549050919050565b600460009054906101000a900473ffff" + + "ffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffff" + + "ffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156124b25760" + + "0080fd5b6001600460146101000a81548160ff0219169083151502179055507f6985a022" + + "10a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff6256040516040518091" + + "0390a1565b6000601060008373ffffffffffffffffffffffffffffffffffffffff1673ff" + + "ffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490" + + "50919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffff" + + "ffffffffff16905090565b60088054600181600116156101000203166002900480601f01" + + "602080910402602001604051908101604052809291908181526020018280546001816001" + + "16156101000203166002900480156126035780601f106125d85761010080835404028352" + + "9160200191612603565b820191906000526020600020905b815481529060010190602001" + + "8083116125e657829003601f168201915b505050505081565b600460009054906101000a" + + "900473ffffffffffffffffffffffffffffffffffffffff1681565b600061272a33846127" + + "2585606060405190810160405280602581526020017f45524332303a2064656372656173" + + "656420616c6c6f77616e63652062656c6f7781526020017f207a65726f00000000000000" + + "0000000000000000000000000000000000000000815250600260003373ffffffffffffff" + + "ffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16" + + "815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffff" + + "ffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001" + + "600020546134339092919063ffffffff16565b6131b2565b6001905092915050565b6000" + + "600460149054906101000a900460ff1615151561275257600080fd5b3360001515600660" + + "008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffff" + + "ffffffffffffffffff16815260200190815260200160002060009054906101000a900460" + + "ff1615151415156127b257600080fd5b8360001515600660008373ffffffffffffffffff" + + "ffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152" + + "60200190815260200160002060009054906101000a900460ff1615151415156128125760" + + "0080fd5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffff" + + "ffffffffffffffffffffffffffff161415151561284e57600080fd5b600c60003373ffff" + + "ffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffff" + + "ffffffff16815260200190815260200160002054841115151561289c57600080fd5b6128" + + "ee84600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffff" + + "ffffffffffffffffffffffffffff1681526020019081526020016000205461309b909190" + + "63ffffffff16565b600c60003373ffffffffffffffffffffffffffffffffffffffff1673" + + "ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081" + + "90555061298384600c60008873ffffffffffffffffffffffffffffffffffffffff1673ff" + + "ffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461" + + "30e590919063ffffffff16565b600c60008773ffffffffffffffffffffffffffffffffff" + + "ffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020" + + "01600020819055508473ffffffffffffffffffffffffffffffffffffffff163373ffffff" + + "ffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa95" + + "2ba7f163c4a11628f55a4df523b3ef866040518082815260200191505060405180910390" + + "a360019250505092915050565b612a3f612544565b73ffffffffffffffffffffffffffff" + + "ffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612a78" + + "57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffff" + + "ffffffffffffffffffffffffffffffff1614151515612ab457600080fd5b80600b600061" + + "01000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffff" + + "ffffffffffffffffffffffffffffffffff160217905550600b60009054906101000a9004" + + "73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffff" + + "ffffffffffffff167fdb66dfa9c6b8f5226fe9aac7e51897ae8ee94ac31dc70bb6c9900b" + + "2574b707e660405160405180910390a250565b6000600f60008373ffffffffffffffffff" + + "ffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152" + + "60200190815260200160002060009054906101000a900460ff169050919050565b612bbb" + + "612544565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffff" + + "ffffffffffffffffffffffffff16141515612bf457600080fd5b600073ffffffffffffff" + + "ffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff" + + "1614151515612c3057600080fd5b80600560006101000a81548173ffffffffffffffffff" + + "ffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffff" + + "ff160217905550600560009054906101000a900473ffffffffffffffffffffffffffffff" + + "ffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fc67398012c111c" + + "e95ecb7429b933096c977380ee6c421175a71a4a4c6c88c06e60405160405180910390a2" + + "50565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffff" + + "ff1681565b6000600d60008473ffffffffffffffffffffffffffffffffffffffff1673ff" + + "ffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000" + + "8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffff" + + "ffffffffffffffff16815260200190815260200160002054905092915050565b600a8054" + + "600181600116156101000203166002900480601f01602080910402602001604051908101" + + "604052809291908181526020018280546001816001161561010002031660029004801561" + + "2e1c5780601f10612df157610100808354040283529160200191612e1c565b8201919060" + + "00526020600020905b815481529060010190602001808311612dff57829003601f168201" + + "915b505050505081565b612e2c612544565b73ffffffffffffffffffffffffffffffffff" + + "ffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612e65576000" + + "80fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffff" + + "ffffffffffffffffffffffffff1614151515612ea157600080fd5b7f8be0079c53165914" + + "1344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0612eca612544565b82604051" + + "808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffff" + + "ffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffff" + + "ff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050604051" + + "80910390a1612f488161316f565b50565b600560009054906101000a900473ffffffffff" + + "ffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffff" + + "ff163373ffffffffffffffffffffffffffffffffffffffff16141515612fa757600080fd" + + "5b6001600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffff" + + "ffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a" + + "81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffff" + + "ffffff167fffa4e6181777692565cf28528fc88fd1516ea86b56da075235fa575af6a4b8" + + "5560405160405180910390a250565b6000600660008373ffffffffffffffffffffffffff" + + "ffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190" + + "815260200160002060009054906101000a900460ff169050919050565b60006130dd8383" + + "6040805190810160405280601e81526020017f536166654d6174683a2073756274726163" + + "74696f6e206f766572666c6f770000815250613433565b905092915050565b6000808284" + + "019050838110151515613165576040517f08c379a0000000000000000000000000000000" + + "00000000000000000000000000815260040180806020018281038252601b815260200180" + + "7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815250" + + "60200191505060405180910390fd5b8091505092915050565b806000806101000a815481" + + "73ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffff" + + "ffffffffffffffffffffff16021790555050565b600073ffffffffffffffffffffffffff" + + "ffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151561" + + "327d576040517f08c379a000000000000000000000000000000000000000000000000000" + + "00000081526004018080602001828103825260248152602001807f45524332303a206170" + + "70726f76652066726f6d20746865207a65726f2061646481526020017f72657373000000" + + "000000000000000000000000000000000000000000000000008152506040019150506040" + + "5180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffff" + + "ffffffffffffffffffffffffffffffffff1614151515613348576040517f08c379a00000" + + "000000000000000000000000000000000000000000000000000081526004018080602001" + + "828103825260228152602001807f45524332303a20617070726f766520746f2074686520" + + "7a65726f20616464726581526020017f7373000000000000000000000000000000000000" + + "00000000000000000000000081525060400191505060405180910390fd5b806002600085" + + "73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffff" + + "ffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffff" + + "ffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260" + + "2001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffff" + + "ff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f" + + "71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405180828152602001915050" + + "60405180910390a3505050565b60008084841115839015156134e3576040517f08c379a0" + + "000000000000000000000000000000000000000000000000000000008152600401808060" + + "2001828103825283818151815260200191508051906020019080838360005b8381101561" + + "34a857808201518184015260208101905061348d565b50505050905090810190601f1680" + + "156134d55780820380516001836020036101000a031916815260200191505b5092505050" + + "60405180910390fd5b508385039050809150509392505050565b82805460018160011615" + + "6101000203166002900490600052602060002090601f016020900481019282601f106135" + + "3557805160ff1916838001178555613563565b8280016001018555821561356357918201" + + "5b82811115613562578251825591602001919060010190613547565b5b50905061357091" + + "90613574565b5090565b61359691905b8082111561359257600081600090555060010161" + + "357a565b5090565b905600a165627a7a72305820e15de5c992fd476a4778192f1e437474" + + "d0da61a53e449a2db2ec25213f4be8620029"; + + // 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B + // nonce: 0 + const mockUnitrollerDeploymentData = + "0x608060405234801561001057600080fd5b50600080546001600160a01b031916331790" + + "556105db806100326000396000f3fe60806040526004361061007b5760003560e01c8063" + + "dcfbc0c71161004e578063dcfbc0c71461019e578063e992a041146101b3578063e9c714" + + "f2146101e6578063f851a440146101fb5761007b565b806326782247146100fe578063b7" + + "1d1a0c1461012f578063bb82aa5e14610174578063c1e8033414610189575b6002546040" + + "516000916001600160a01b03169082903690808383808284376040519201945060009350" + + "9091505080830381855af49150503d80600081146100de576040519150601f19603f3d01" + + "1682016040523d82523d6000602084013e6100e3565b606091505b505090506040513d60" + + "00823e8180156100fa573d82f35b3d82fd5b34801561010a57600080fd5b506101136102" + + "10565b604080516001600160a01b039092168252519081900360200190f35b3480156101" + + "3b57600080fd5b506101626004803603602081101561015257600080fd5b503560016001" + + "60a01b031661021f565b60408051918252519081900360200190f35b3480156101805760" + + "0080fd5b506101136102b0565b34801561019557600080fd5b506101626102bf565b3480" + + "156101aa57600080fd5b506101136103ba565b3480156101bf57600080fd5b5061016260" + + "0480360360208110156101d657600080fd5b50356001600160a01b03166103c9565b3480" + + "156101f257600080fd5b5061016261044d565b34801561020757600080fd5b5061011361" + + "0533565b6001546001600160a01b031681565b600080546001600160a01b031633146102" + + "455761023e6001600e610542565b90506102ab565b600180546001600160a01b03848116" + + "6001600160a01b0319831681179093556040805191909216808252602082019390935281" + + "517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99291" + + "81900390910190a160005b9150505b919050565b6002546001600160a01b031681565b60" + + "03546000906001600160a01b0316331415806102e557506003546001600160a01b031615" + + "5b156102fc576102f5600180610542565b90506103b7565b600280546003805460016001" + + "60a01b038082166001600160a01b03198086168217968790559092169092556040805193" + + "8316808552949092166020840152815190927fd604de94d45953f9138079ec1b82d533cb" + + "2160c906d1076d1f7ed54befbca97a92908290030190a1600354604080516001600160a0" + + "1b038085168252909216602083015280517fe945ccee5d701fc83f9b8aa8ca94ea4219ec" + + "1fcbd4f4cab4f0ea57c5c3e1d8159281900390910190a160005b925050505b90565b6003" + + "546001600160a01b031681565b600080546001600160a01b031633146103e85761023e60" + + "01600f610542565b600380546001600160a01b038481166001600160a01b031983161792" + + "8390556040805192821680845293909116602083015280517fe945ccee5d701fc83f9b8a" + + "a8ca94ea4219ec1fcbd4f4cab4f0ea57c5c3e1d8159281900390910190a160006102a756" + + "5b6001546000906001600160a01b031633141580610468575033155b15610479576102f5" + + "60016000610542565b60008054600180546001600160a01b038082166001600160a01b03" + + "198086168217968790559092169092556040805193831680855294909216602084015281" + + "5190927ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc" + + "92908290030190a1600154604080516001600160a01b0380851682529092166020830152" + + "80517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a992" + + "81900390910190a160006103b2565b6000546001600160a01b031681565b60007f45b96f" + + "e442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601181111561" + + "057157fe5b83601381111561057d57fe5b60408051928352602083019190915260008282" + + "0152519081900360600190a18260118111156105a857fe5b939250505056fea165627a7a" + + "72305820deb1fa7c9392a8cb5591582fb6e4b04575db52ce8ef799b0a7a5140ae6ff75d8" + + "0029"; + + // 0x178053c06006e67e09879C09Ff012fF9d263dF29 + // nonce: 68 + const mockCurrentComptrollerDeploymentData = + "0x608060405234801561001057600080fd5b50600080546001600160a01b031916331790" + + "55612d15806100326000396000f3fe608060405234801561001057600080fd5b50600436" + + "106102315760003560e01c80638e8f294b11610130578063d02f7351116100b8578063e4" + + "028eee1161007c578063e4028eee1461090e578063e87554461461093a578063eabe7d91" + + "14610942578063ede4edd014610978578063f851a4401461099e57610231565b8063d02f" + + "735114610841578063d9226ced14610887578063da3d454c146108a4578063dce1544914" + + "6108da578063dcfbc0c71461090657610231565b8063abfceffc116100ff578063abfcef" + + "fc14610695578063bb82aa5e1461070b578063bdcdc25814610713578063c29982381461" + + "074f578063c488847b146107f257610231565b80638e8f294b146105f8578063929fe9a1" + + "1461063957806394b2294b14610667578063a76b3fda1461066f57610231565b80634ef4" + + "c3e1116101be5780635ec88c79116101825780635ec88c79146104e45780635fc7e71e14" + + "6105285780636a56947e1461056e5780636d35bf91146105aa5780637dc0d1d0146105f0" + + "57610231565b80634ef4c3e1146103f95780634fd42e171461042f57806351dff9891461" + + "044c57806355ee1fe1146104885780635c778605146104ae57610231565b8063317b0b77" + + "11610205578063317b0b771461030857806332000e001461032557806341c728b9146103" + + "6957806347ef3b3b146103a55780634ada90af146103f157610231565b80627e3dd21461" + + "02365780631ededc911461025257806324008a621461029657806326782247146102e457" + + "5b600080fd5b61023e6109a6565b604080519115158252519081900360200190f35b6102" + + "94600480360360a081101561026857600080fd5b506001600160a01b0381358116916020" + + "81013582169160408201351690606081013590608001356109ab565b005b6102d2600480" + + "360360808110156102ac57600080fd5b506001600160a01b038135811691602081013582" + + "169160408201351690606001356109b2565b60408051918252519081900360200190f35b" + + "6102ec6109e8565b604080516001600160a01b039092168252519081900360200190f35b" + + "6102d26004803603602081101561031e57600080fd5b50356109f7565b61029460048036" + + "0360a081101561033b57600080fd5b506001600160a01b03813581169160208101359091" + + "1690604081013590606081013590608001351515610b05565b6102946004803603608081" + + "101561037f57600080fd5b506001600160a01b0381358116916020810135909116906040" + + "8101359060600135610fcd565b610294600480360360c08110156103bb57600080fd5b50" + + "6001600160a01b0381358116916020810135821691604082013581169160608101359091" + + "169060808101359060a00135610fd3565b6102d2610fd8565b6102d26004803603606081" + + "101561040f57600080fd5b506001600160a01b0381358116916020810135909116906040" + + "0135610fde565b6102d26004803603602081101561044557600080fd5b5035611015565b" + + "6102946004803603608081101561046257600080fd5b506001600160a01b038135811691" + + "60208101359091169060408101359060600135611104565b6102d2600480360360208110" + + "1561049e57600080fd5b50356001600160a01b0316611167565b61029460048036036060" + + "8110156104c457600080fd5b506001600160a01b03813581169160208101359091169060" + + "4001356111e9565b61050a600480360360208110156104fa57600080fd5b503560016001" + + "60a01b03166111ee565b6040805193845260208401929092528282015251908190036060" + + "0190f35b6102d2600480360360a081101561053e57600080fd5b506001600160a01b0381" + + "358116916020810135821691604082013581169160608101359091169060800135611223" + + "565b6102946004803603608081101561058457600080fd5b506001600160a01b03813581" + + "169160208101358216916040820135169060600135610fcd565b610294600480360360a0" + + "8110156105c057600080fd5b506001600160a01b03813581169160208101358216916040" + + "820135811691606081013590911690608001356109ab565b6102ec6113aa565b61061e60" + + "04803603602081101561060e57600080fd5b50356001600160a01b03166113b9565b6040" + + "8051921515835260208301919091528051918290030190f35b61023e6004803603604081" + + "101561064f57600080fd5b506001600160a01b03813581169160200135166113d8565b61" + + "02d261140c565b6102d26004803603602081101561068557600080fd5b50356001600160" + + "a01b0316611412565b6106bb600480360360208110156106ab57600080fd5b5035600160" + + "0160a01b0316611541565b60408051602080825283518183015283519192839290830191" + + "858101910280838360005b838110156106f75781810151838201526020016106df565b50" + + "5050509050019250505060405180910390f35b6102ec6115ca565b6102d2600480360360" + + "8081101561072957600080fd5b506001600160a01b038135811691602081013582169160" + + "408201351690606001356115d9565b6106bb6004803603602081101561076557600080fd" + + "5b81019060208101813564010000000081111561078057600080fd5b8201836020820111" + + "1561079257600080fd5b8035906020019184602083028401116401000000008311171561" + + "07b457600080fd5b91908080602002602001604051908101604052809392919081815260" + + "20018383602002808284376000920191909152509295506115e6945050505050565b6108" + + "286004803603606081101561080857600080fd5b506001600160a01b0381358116916020" + + "810135909116906040013561178a565b6040805192835260208301919091528051918290" + + "030190f35b6102d2600480360360a081101561085757600080fd5b506001600160a01b03" + + "81358116916020810135821691604082013581169160608101359091169060800135611a" + + "05565b6102d26004803603602081101561089d57600080fd5b5035611b4b565b6102d260" + + "0480360360608110156108ba57600080fd5b506001600160a01b03813581169160208101" + + "359091169060400135611baf565b6102ec600480360360408110156108f057600080fd5b" + + "506001600160a01b038135169060200135611ce6565b6102ec611d1b565b6102d2600480" + + "3603604081101561092457600080fd5b506001600160a01b038135169060200135611d2a" + + "565b6102d2611edd565b6102d26004803603606081101561095857600080fd5b50600160" + + "0160a01b03813581169160208101359091169060400135611ee3565b6102d26004803603" + + "602081101561098e57600080fd5b50356001600160a01b0316611ef0565b6102ec612206" + + "565b600181565b5050505050565b6001600160a01b038416600090815260096020526040" + + "81205460ff166109da575060096109e0565b60005b90505b949350505050565b60015460" + + "01600160a01b031681565b6000610a01612215565b610a1857610a116001600461226056" + + "5b9050610b00565b610a20612bde565b506040805160208101909152828152610a37612b" + + "de565b50604080516020810190915266b1a2bc2ec500008152610a5782826122c6565b15" + + "610a7057610a67600580612260565b92505050610b00565b610a78612bde565b50604080" + + "5160208101909152670c7d713b49da00008152610a9981846122ce565b15610ab357610a" + + "a9600580612260565b9350505050610b00565b6005805490869055604080518281526020" + + "810188905281517f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f3" + + "46110fd9929181900390910190a160005b9450505050505b919050565b846001600160a0" + + "1b031663f851a4406040518163ffffffff1660e01b815260040160206040518083038186" + + "803b158015610b3e57600080fd5b505afa158015610b52573d6000803e3d6000fd5b5050" + + "50506040513d6020811015610b6857600080fd5b50516001600160a01b03163314610bb3" + + "57604051600160e51b62461bcd0281526004018080602001828103825260278152602001" + + "80612cc36027913960400191505060405180910390fd5b6000856001600160a01b031663" + + "c1e803346040518163ffffffff1660e01b8152600401602060405180830381600087803b" + + "158015610bf057600080fd5b505af1158015610c04573d6000803e3d6000fd5b50505050" + + "6040513d6020811015610c1a57600080fd5b505190508015610c745760408051600160e5" + + "1b62461bcd02815260206004820152601560248201527f6368616e6765206e6f74206175" + + "74686f72697a65640000000000000000000000604482015290519081900360640190fd5b" + + "81610fc55760008690506000816001600160a01b03166355ee1fe1886040518263ffffff" + + "ff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191" + + "5050602060405180830381600087803b158015610cd857600080fd5b505af1158015610c" + + "ec573d6000803e3d6000fd5b505050506040513d6020811015610d0257600080fd5b5051" + + "90508015610d5c5760408051600160e51b62461bcd028152602060048201526016602482" + + "01527f736574207072696365206f7261636c65206572726f720000000000000000000060" + + "4482015290519081900360640190fd5b816001600160a01b031663317b0b778760405182" + + "63ffffffff1660e01b815260040180828152602001915050602060405180830381600087" + + "803b158015610da257600080fd5b505af1158015610db6573d6000803e3d6000fd5b5050" + + "50506040513d6020811015610dcc57600080fd5b505190508015610e2657604080516001" + + "60e51b62461bcd02815260206004820152601660248201527f73657420636c6f73652066" + + "6163746f72206572726f7200000000000000000000604482015290519081900360640190" + + "fd5b816001600160a01b031663d9226ced866040518263ffffffff1660e01b8152600401" + + "80828152602001915050602060405180830381600087803b158015610e6c57600080fd5b" + + "505af1158015610e80573d6000803e3d6000fd5b505050506040513d6020811015610e96" + + "57600080fd5b505190508015610ef05760408051600160e51b62461bcd02815260206004" + + "820152601560248201527f736574206d61782061737373657473206572726f7200000000" + + "00000000000000604482015290519081900360640190fd5b816001600160a01b0316634f" + + "d42e17670de0b6b3a76400006040518263ffffffff1660e01b8152600401808281526020" + + "01915050602060405180830381600087803b158015610f3e57600080fd5b505af1158015" + + "610f52573d6000803e3d6000fd5b505050506040513d6020811015610f6857600080fd5b" + + "505190508015610fc25760408051600160e51b62461bcd02815260206004820152601f60" + + "248201527f736574206c69717569646174696f6e20696e63656e74697665206572726f72" + + "00604482015290519081900360640190fd5b50505b505050505050565b50505050565b61" + + "0fc5565b60065481565b6001600160a01b03831660009081526009602052604081205460" + + "ff166110085760095b905061100e565b60005b90505b9392505050565b600061101f6122" + + "15565b61102f57610a116001600b612260565b611037612bde565b506040805160208101" + + "90915282815261104e612bde565b506040805160208101909152670de0b6b3a764000081" + + "5261106f82826122ce565b1561108057610a676007600c612260565b611088612bde565b" + + "5060408051602081019091526714d1120d7b16000081526110a981846122ce565b156110" + + "ba57610aa96007600c612260565b60068054908690556040805182815260208101889052" + + "81517faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec131692" + + "9181900390910190a16000610af9565b801580156111125750600082115b15610fcd5760" + + "408051600160e51b62461bcd02815260206004820152601160248201527f72656465656d" + + "546f6b656e73207a65726f00000000000000000000000000000060448201529051908190" + + "0360640190fd5b6000611171612215565b61118157610a1160016010612260565b600480" + + "546001600160a01b038481166001600160a01b0319831681179093556040805191909216" + + "808252602082019390935281517fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d" + + "2d0ea78402d576d22e22929181900390910190a160009392505050565b505050565b6000" + + "806000806000806112058760008060006122d5565b925092509250826011811115611217" + + "57fe5b97919650945092505050565b6001600160a01b0385166000908152600960205260" + + "4081205460ff16158061126457506001600160a01b038516600090815260096020526040" + + "90205460ff16155b156112735760095b90506113a1565b60008061127f856126fd565b91" + + "93509091506000905082601181111561129557fe5b146112af578160118111156112a657" + + "fe5b925050506113a1565b806112bb5760036112a6565b6000886001600160a01b031663" + + "95dd9193876040518263ffffffff1660e01b815260040180826001600160a01b03166001" + + "600160a01b0316815260200191505060206040518083038186803b158015611313576000" + + "80fd5b505afa158015611327573d6000803e3d6000fd5b505050506040513d6020811015" + + "61133d57600080fd5b505160408051602081019091526005548152909150600090819061" + + "1361908461271d565b9092509050600082600381111561137457fe5b1461138857600b5b" + + "955050505050506113a1565b8087111561139757601161137c565b600095505050505050" + + "5b95945050505050565b6004546001600160a01b031681565b6009602052600090815260" + + "409020805460019091015460ff9091169082565b6001600160a01b038082166000908152" + + "600960209081526040808320938616835260029093019052205460ff165b92915050565b" + + "60075481565b600080546001600160a01b0316331461143157610a116001601261226056" + + "5b6001600160a01b03821660009081526009602052604090205460ff161561145e57610a" + + "11600a6011612260565b816001600160a01b031663fe9c44ae6040518163ffffffff1660" + + "e01b815260040160206040518083038186803b15801561149757600080fd5b505afa1580" + + "156114ab573d6000803e3d6000fd5b505050506040513d60208110156114c157600080fd" + + "5b50506040805180820182526001808252600060208084018281526001600160a01b0388" + + "1680845260098352928690209451855460ff191690151517855551939092019290925582" + + "5191825291517fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f2" + + "12321f929181900390910190a1600092915050565b60608060086000846001600160a01b" + + "03166001600160a01b031681526020019081526020016000208054806020026020016040" + + "519081016040528092919081815260200182805480156115bd5760200282019190600052" + + "6020600020905b81546001600160a01b0316815260019091019060200180831161159f57" + + "5b5093979650505050505050565b6002546001600160a01b031681565b60006109dd8585" + + "84612771565b606060008251905060608160405190808252806020026020018201604052" + + "801561161a578160200160208202803883390190505b50905060005b8281101561178257" + + "600085828151811061163657fe5b6020908102919091018101516001600160a01b038116" + + "60009081526009909252604090912080549192509060ff1661168a5760095b8484815181" + + "1061167757fe5b602002602001018181525050505061177a565b33600090815260028201" + + "602052604090205460ff161515600114156116b057600061166b565b6007543360009081" + + "5260086020526040902054106116cf57601061166b565b33600081815260028301602090" + + "81526040808320805460ff19166001908117909155600883528184208054918201815584" + + "529282902090920180546001600160a01b0387166001600160a01b031990911681179091" + + "5582519081529081019290925280517f3ab23ab0d51cccc0c3085aec51f99228625aa1a9" + + "22b3a8ca89a26b0f2027a1a59281900390910190a1600084848151811061176b57fe5b60" + + "200260200101818152505050505b600101611620565b509392505050565b600480546040" + + "8051600160e01b63fc57d4df0281526001600160a01b0387811694820194909452905160" + + "00938493849391169163fc57d4df91602480820192602092909190829003018186803b15" + + "80156117e357600080fd5b505afa1580156117f7573d6000803e3d6000fd5b5050505060" + + "40513d602081101561180d57600080fd5b50516004805460408051600160e01b63fc57d4" + + "df0281526001600160a01b038a8116948201949094529051939450600093929091169163" + + "fc57d4df91602480820192602092909190829003018186803b15801561186957600080fd" + + "5b505afa15801561187d573d6000803e3d6000fd5b505050506040513d60208110156118" + + "9357600080fd5b505190508115806118a2575080155b156118b757600d93506000925061" + + "19fd915050565b6000866001600160a01b031663182df0f56040518163ffffffff1660e0" + + "1b815260040160206040518083038186803b1580156118f257600080fd5b505afa158015" + + "611906573d6000803e3d6000fd5b505050506040513d602081101561191c57600080fd5b" + + "50519050600061192a612bde565b611932612bde565b61193a612bde565b600061194860" + + "0654896127e0565b94509050600081600381111561195a57fe5b1461197657600b5b9950" + + "600098506119fd975050505050505050565b61198087876127e0565b9350905060008160" + + "0381111561199257fe5b1461199e57600b611962565b6119a8848461281b565b92509050" + + "60008160038111156119ba57fe5b146119c657600b611962565b6119d0828c61271d565b" + + "9550905060008160038111156119e257fe5b146119ee57600b611962565b600099509397" + + "50505050505050505b935093915050565b6001600160a01b038516600090815260096020" + + "52604081205460ff161580611a4657506001600160a01b03851660009081526009602052" + + "604090205460ff16155b15611a5257600961126c565b846001600160a01b0316635fe3b5" + + "676040518163ffffffff1660e01b815260040160206040518083038186803b158015611a" + + "8b57600080fd5b505afa158015611a9f573d6000803e3d6000fd5b505050506040513d60" + + "20811015611ab557600080fd5b505160408051600160e01b635fe3b56702815290516001" + + "600160a01b0392831692891691635fe3b567916004808301926020929190829003018186" + + "803b158015611afe57600080fd5b505afa158015611b12573d6000803e3d6000fd5b5050" + + "50506040513d6020811015611b2857600080fd5b50516001600160a01b031614611b3f57" + + "600261126c565b60009695505050505050565b6000611b55612215565b611b6557610a11" + + "6001600d612260565b6007805490839055604080518281526020810185905281517f7093" + + "cf1eb653f749c3ff531d6df7f92764536a7fa0d13530cd26e070780c32ea929181900390" + + "910190a1600061100e565b6001600160a01b038316600090815260096020526040812054" + + "60ff16611bd6576009611001565b6001600160a01b038085166000908152600960209081" + + "526040808320938716835260029093019052205460ff16611c0e576008611001565b6004" + + "805460408051600160e01b63fc57d4df0281526001600160a01b03888116948201949094" + + "529051929091169163fc57d4df91602480820192602092909190829003018186803b1580" + + "15611c6257600080fd5b505afa158015611c76573d6000803e3d6000fd5b505050506040" + + "513d6020811015611c8c57600080fd5b5051611c9957600d611001565b600080611ca985" + + "876000876122d5565b91935090915060009050826011811115611cbf57fe5b14611cd957" + + "816011811115611cd057fe5b9250505061100e565b8015611b3f576004611cd0565b6008" + + "6020528160005260406000208181548110611cff57fe5b60009182526020909120015460" + + "01600160a01b03169150829050565b6003546001600160a01b031681565b600080546001" + + "600160a01b03163314611d5057611d4960016006612260565b9050611406565b60016001" + + "60a01b0383166000908152600960205260409020805460ff16611d8557611d7d60096007" + + "612260565b915050611406565b611d8d612bde565b506040805160208101909152838152" + + "611da4612bde565b506040805160208101909152670c7d713b49da00008152611dc58183" + + "6122ce565b15611de057611dd660066008612260565b9350505050611406565b84158015" + + "90611e6c57506004805460408051600160e01b63fc57d4df0281526001600160a01b038a" + + "8116948201949094529051929091169163fc57d4df916024808201926020929091908290" + + "03018186803b158015611e3e57600080fd5b505afa158015611e52573d6000803e3d6000" + + "fd5b505050506040513d6020811015611e6857600080fd5b5051155b15611e7d57611dd6" + + "600d6009612260565b60018301805490869055604080516001600160a01b038916815260" + + "20810183905280820188905290517f70483e6592cd5182d45ac970e05bc62cdcc90e9d8e" + + "f2c2dbe686cf383bcd7fc59181900360600190a16000979650505050505050565b600554" + + "81565b600061100b848484612771565b6000808290506000806000836001600160a01b03" + + "1663c37f68e2336040518263ffffffff1660e01b815260040180826001600160a01b0316" + + "6001600160a01b0316815260200191505060806040518083038186803b158015611f5157" + + "600080fd5b505afa158015611f65573d6000803e3d6000fd5b505050506040513d608081" + + "1015611f7b57600080fd5b50805160208201516040909201519094509092509050821561" + + "1fd157604051600160e51b62461bcd028152600401808060200182810382526025815260" + + "200180612c9e6025913960400191505060405180910390fd5b8015611fee57611fe3600c" + + "6002612260565b945050505050610b00565b6000611ffb873385612771565b9050801561" + + "201c57612010600e600383612833565b95505050505050610b00565b6001600160a01b03" + + "85166000908152600960209081526040808320338452600281019092529091205460ff16" + + "61205b5760009650505050505050610b00565b3360009081526002820160209081526040" + + "808320805460ff1916905560088252918290208054835181840281018401909452808452" + + "606093928301828280156120cd57602002820191906000526020600020905b8154600160" + + "0160a01b031681526001909101906020018083116120af575b5050835193945083925060" + + "009150505b8281101561212257896001600160a01b03168482815181106120fb57fe5b60" + + "200260200101516001600160a01b0316141561211a57809150612122565b6001016120dd" + + "565b5081811061212c57fe5b336000908152600860205260409020805481906000198101" + + "90811061214d57fe5b9060005260206000200160009054906101000a90046001600160a0" + + "1b031681838154811061217757fe5b600091825260209091200180546001600160a01b03" + + "19166001600160a01b039290921691909117905580546121b0826000198301612bf1565b" + + "50604080516001600160a01b038c16815233602082015281517fe699a64c18b07ac5b730" + + "1aa273f36a2287239eb9501d81950672794afba29a0d929181900390910190a160009c9b" + + "505050505050505050505050565b6000546001600160a01b031681565b60025460009081" + + "906001600160a01b03163314801561223e57506000546001600160a01b031632145b6000" + + "549091506001600160a01b0316331480806122585750815b925050505b90565b60007f45" + + "b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08360118111" + + "1561228f57fe5b83601381111561229b57fe5b6040805192835260208301919091526000" + + "82820152519081900360600190a182601181111561100e57fe5b519051111590565b5190" + + "511090565b60008060006122e2612c15565b6001600160a01b0388166000908152600860" + + "209081526040808320805482518185028101850190935280835284936060939291908301" + + "8282801561234f57602002820191906000526020600020905b81546001600160a01b0316" + + "8152600190910190602001808311612331575b50939450600093505050505b8151811015" + + "6126ae57600082828151811061237257fe5b60200260200101519050806001600160a01b" + + "031663c37f68e28e6040518263ffffffff1660e01b815260040180826001600160a01b03" + + "166001600160a01b0316815260200191505060806040518083038186803b1580156123d2" + + "57600080fd5b505afa1580156123e6573d6000803e3d6000fd5b505050506040513d6080" + + "8110156123fc57600080fd5b508051602082015160408084015160609485015160808c01" + + "52938a019390935291880191909152945084156124425750600f97506000965086955061" + + "26f3945050505050565b60408051602080820183526001600160a01b0380851660008181" + + "526009845285902060010154845260c08b01939093528351808301855260808b01518152" + + "60e08b0152600480548551600160e01b63fc57d4df028152918201949094529351921692" + + "63fc57d4df9260248083019392829003018186803b1580156124c557600080fd5b505afa" + + "1580156124d9573d6000803e3d6000fd5b505050506040513d60208110156124ef576000" + + "80fd5b505160a087018190526125135750600d9750600096508695506126f39450505050" + + "50565b604080516020810190915260a08701518152610100870181905260c087015160e0" + + "88015161254092612899565b6101208801529350600084600381111561255657fe5b1461" + + "25725750600b9750600096508695506126f3945050505050565b61258a86610120015187" + + "6040015188600001516128f1565b87529350600084600381111561259c57fe5b146125b8" + + "5750600b9750600096508695506126f3945050505050565b6125d0866101000151876060" + + "015188602001516128f1565b6020880152935060008460038111156125e557fe5b146126" + + "015750600b9750600096508695506126f3945050505050565b8b6001600160a01b031681" + + "6001600160a01b031614156126a55761262f8661012001518c88602001516128f1565b60" + + "208801529350600084600381111561264457fe5b146126605750600b9750600096508695" + + "506126f3945050505050565b6126748661010001518b88602001516128f1565b60208801" + + "529350600084600381111561268957fe5b146126a55750600b9750600096508695506126" + + "f3945050505050565b5060010161235b565b506020840151845111156126d55750505060" + + "208101519051600094500391508290506126f3565b505081516020909201516000955085" + + "94509190910391506126f39050565b9450945094915050565b6000806000612710846000" + + "8060006122d5565b9250925092509193909250565b600080600061272a612bde565b6127" + + "34868661293e565b9092509050600082600381111561274757fe5b146127585750915060" + + "00905061276a565b6000612763826129a6565b9350935050505b9250929050565b600160" + + "0160a01b03831660009081526009602052604081205460ff16612798576009611001565b" + + "6001600160a01b0380851660009081526009602090815260408083209387168352600290" + + "93019052205460ff166127d0576000611001565b600080611ca985878660006122d5565b" + + "60006127ea612bde565b6128106040518060200160405280868152506040518060200160" + + "405280868152506129b5565b915091509250929050565b6000612825612bde565b835183" + + "516128109190612a9e565b60007f45b96fe442630264581b197e84bbada861235052c5a1" + + "aadfff9ea4e40a969aa084601181111561286257fe5b84601381111561286e57fe5b6040" + + "80519283526020830191909152818101859052519081900360600190a183601181111561" + + "100b57fe5b60006128a3612bde565b60006128ad612bde565b6128b787876129b5565b90" + + "9250905060008260038111156128ca57fe5b146128d95790925090506119fd565b6128e3" + + "81866129b5565b935093505050935093915050565b60008060006128fe612bde565b6129" + + "08878761293e565b9092509050600082600381111561291b57fe5b1461292c5750915060" + + "0090506119fd565b6128e3612938826129a6565b86612b4e565b6000612948612bde565b" + + "600080612959866000015186612b74565b9092509050600082600381111561296c57fe5b" + + "1461298b5750604080516020810190915260008152909250905061276a565b6040805160" + + "2081019091529081526000969095509350505050565b51670de0b6b3a764000090049056" + + "5b60006129bf612bde565b6000806129d486600001518660000151612b74565b90925090" + + "5060008260038111156129e757fe5b14612a065750604080516020810190915260008152" + + "909250905061276a565b600080612a1b6706f05b59d3b2000084612b4e565b9092509050" + + "6000826003811115612a2e57fe5b14612a50575060408051602081019091526000815290" + + "9450925061276a915050565b600080612a6583670de0b6b3a7640000612bb3565b909250" + + "90506000826003811115612a7857fe5b14612a7f57fe5b60408051602081019091529081" + + "5260009a909950975050505050505050565b6000612aa8612bde565b600080612abd8667" + + "0de0b6b3a7640000612b74565b90925090506000826003811115612ad057fe5b14612aef" + + "5750604080516020810190915260008152909250905061276a565b600080612afc838861" + + "2bb3565b90925090506000826003811115612b0f57fe5b14612b31575060408051602081" + + "0190915260008152909450925061276a915050565b604080516020810190915290815260" + + "009890975095505050505050565b600080838301848110612b665760009250905061276a" + + "565b50600291506000905061276a565b60008083612b875750600090508061276a565b83" + + "830283858281612b9457fe5b0414612ba85750600291506000905061276a565b60009250" + + "905061276a565b60008082612bc7575060019050600061276a565b6000838581612bd257" + + "fe5b04915091509250929050565b6040518060200160405280600081525090565b815481" + + "8355818111156111e9576000838152602090206111e9918101908301612c7f565b604051" + + "806101400160405280600081526020016000815260200160008152602001600081526020" + + "016000815260200160008152602001612c53612bde565b8152602001612c60612bde565b" + + "8152602001612c6d612bde565b8152602001612c7a612bde565b905290565b61225d9190" + + "5b80821115612c995760008155600101612c85565b509056fe657869744d61726b65743a" + + "206765744163636f756e74536e617073686f74206661696c65646f6e6c7920756e697472" + + "6f6c6c65722061646d696e2063616e206368616e676520627261696e73a165627a7a7230" + + "582075d92d0e96eb01957b794704a02af0b7e3c5efe630de7186f3688639d7128e900029"; + + // 0xa1046abfc2598F48C44Fb320d281d3F3c0733c9a + // nonce: 7 + const mockCDaiIRMDeploymentData = + "0x608060405234801561001057600080fd5b506040516040806106638339810180604052" + + "604081101561003057600080fd5b50805160209091015160019190915560005561061280" + + "6100516000396000f3fe608060405234801561001057600080fd5b506004361061005757" + + "60003560e01c806315f240531461005c5780631b3ed7221461009e5780631f68f20a1461" + + "00b85780632191f92a146100c0578063a385fb96146100dc575b600080fd5b6100856004" + + "803603606081101561007257600080fd5b50803590602081013590604001356100e4565b" + + "6040805192835260208301919091528051918290030190f35b6100a661017d565b604080" + + "51918252519081900360200190f35b6100a6610183565b6100c8610189565b6040805191" + + "15158252519081900360200190f35b6100a661018e565b60008060006100f16105d3565b" + + "6100f96105d3565b6101038888610195565b919450925090506000836004811115610118" + + "57fe5b146101385782600481111561012957fe5b94506000935061017592505050565b60" + + "006101426105d3565b61014f8362201480610312565b9092509050600082600381111561" + + "016257fe5b1461016957fe5b51600096509450505050505b935093915050565b60005481" + + "565b60015481565b600181565b6220148081565b600061019f6105d3565b6101a76105d3" + + "565b60006101b16105d3565b6101bb878761037c565b9092509050600082600481111561" + + "01ce57fe5b146101fc575060408051602080820183526000808352835191820190935291" + + "8252919450909250905061030b565b60006102066105d3565b6102128360005461043e56" + + "5b9092509050600082600381111561022557fe5b14610257575050604080516020808201" + + "835260008083528351918201909352918252600396509450925061030b915050565b6000" + + "6102616105d3565b61027383670de0b6b3a7640000610312565b90925090506000826003" + + "81111561028657fe5b1461028d57fe5b60006102976105d3565b6102b183604051806020" + + "0160405280600154815250610459565b909250905060008260038111156102c457fe5b14" + + "6102fa57505060408051602080820183526000808352835191820190935291825260049a" + + "509850965061030b95505050505050565b60009a509598509496505050505050505b9250" + + "925092565b600061031c6105d3565b60008061032d866000015186610493565b90925090" + + "50600082600381111561034057fe5b1461035f5750604080516020810190915260008152" + + "9092509050610375565b6040805160208101909152908152600093509150505b92509290" + + "50565b60006103866105d3565b826103a357505060408051602081019091526000808252" + + "90610375565b6000806103b086866104be565b909250905060008260038111156103c357" + + "fe5b146103e4575050604080516020810190915260008152600192509050610375565b60" + + "006103ee6105d3565b6103f887846104e4565b9092509050600082600381111561040b57" + + "fe5b1461042f575050604080516020810190915260008152600294509250610375915050" + + "565b60009890975095505050505050565b60006104486105d3565b60008061032d866000" + + "015186610594565b60006104636105d3565b600080610478866000015186600001516104" + + "be565b60408051602081019091529081529097909650945050505050565b600080826104" + + "a75750600190506000610375565b60008385816104b257fe5b0491509150925092905056" + + "5b6000808383018481106104d657600092509050610375565b5060029150600090506103" + + "75565b60006104ee6105d3565b60008061050386670de0b6b3a7640000610594565b9092" + + "509050600082600381111561051657fe5b14610535575060408051602081019091526000" + + "81529092509050610375565b6000806105428388610493565b9092509050600082600381" + + "111561055557fe5b14610577575060408051602081019091526000815290945092506103" + + "75915050565b604080516020810190915290815260009890975095505050505050565b60" + + "0080836105a757506000905080610375565b838302838582816105b457fe5b04146105c8" + + "57506002915060009050610375565b600092509050610375565b60405180602001604052" + + "8060008152509056fea165627a7a7230582021d1e96de1a54e5aaf17c19ae397dd393fa0" + + "cd21afedd016b0e6d1fb0e4c749600290000000000000000000000000000000000000000" + + "0000000000b1a2bc2ec50000000000000000000000000000000000000000000000000000" + + "01aa535d3d0c0000"; + + // 0xc64C4cBA055eFA614CE01F4BAD8A9F519C4f8FaB + // nonce: 8 + const mockCUSDCIRMDeploymentData = + "0x608060405234801561001057600080fd5b506040516040806106638339810180604052" + + "604081101561003057600080fd5b50805160209091015160019190915560005561061280" + + "6100516000396000f3fe608060405234801561001057600080fd5b506004361061005757" + + "60003560e01c806315f240531461005c5780631b3ed7221461009e5780631f68f20a1461" + + "00b85780632191f92a146100c0578063a385fb96146100dc575b600080fd5b6100856004" + + "803603606081101561007257600080fd5b50803590602081013590604001356100e4565b" + + "6040805192835260208301919091528051918290030190f35b6100a661017d565b604080" + + "51918252519081900360200190f35b6100a6610183565b6100c8610189565b6040805191" + + "15158252519081900360200190f35b6100a661018e565b60008060006100f16105d3565b" + + "6100f96105d3565b6101038888610195565b919450925090506000836004811115610118" + + "57fe5b146101385782600481111561012957fe5b94506000935061017592505050565b60" + + "006101426105d3565b61014f8362201480610312565b9092509050600082600381111561" + + "016257fe5b1461016957fe5b51600096509450505050505b935093915050565b60005481" + + "565b60015481565b600181565b6220148081565b600061019f6105d3565b6101a76105d3" + + "565b60006101b16105d3565b6101bb878761037c565b9092509050600082600481111561" + + "01ce57fe5b146101fc575060408051602080820183526000808352835191820190935291" + + "8252919450909250905061030b565b60006102066105d3565b6102128360005461043e56" + + "5b9092509050600082600381111561022557fe5b14610257575050604080516020808201" + + "835260008083528351918201909352918252600396509450925061030b915050565b6000" + + "6102616105d3565b61027383670de0b6b3a7640000610312565b90925090506000826003" + + "81111561028657fe5b1461028d57fe5b60006102976105d3565b6102b183604051806020" + + "0160405280600154815250610459565b909250905060008260038111156102c457fe5b14" + + "6102fa57505060408051602080820183526000808352835191820190935291825260049a" + + "509850965061030b95505050505050565b60009a509598509496505050505050505b9250" + + "925092565b600061031c6105d3565b60008061032d866000015186610493565b90925090" + + "50600082600381111561034057fe5b1461035f5750604080516020810190915260008152" + + "9092509050610375565b6040805160208101909152908152600093509150505b92509290" + + "50565b60006103866105d3565b826103a357505060408051602081019091526000808252" + + "90610375565b6000806103b086866104be565b909250905060008260038111156103c357" + + "fe5b146103e4575050604080516020810190915260008152600192509050610375565b60" + + "006103ee6105d3565b6103f887846104e4565b9092509050600082600381111561040b57" + + "fe5b1461042f575050604080516020810190915260008152600294509250610375915050" + + "565b60009890975095505050505050565b60006104486105d3565b60008061032d866000" + + "015186610594565b60006104636105d3565b600080610478866000015186600001516104" + + "be565b60408051602081019091529081529097909650945050505050565b600080826104" + + "a75750600190506000610375565b60008385816104b257fe5b0491509150925092905056" + + "5b6000808383018481106104d657600092509050610375565b5060029150600090506103" + + "75565b60006104ee6105d3565b60008061050386670de0b6b3a7640000610594565b9092" + + "509050600082600381111561051657fe5b14610535575060408051602081019091526000" + + "81529092509050610375565b6000806105428388610493565b9092509050600082600381" + + "111561055557fe5b14610577575060408051602081019091526000815290945092506103" + + "75915050565b604080516020810190915290815260009890975095505050505050565b60" + + "0080836105a757506000905080610375565b838302838582816105b457fe5b04146105c8" + + "57506002915060009050610375565b600092509050610375565b60405180602001604052" + + "8060008152509056fea165627a7a7230582021d1e96de1a54e5aaf17c19ae397dd393fa0" + + "cd21afedd016b0e6d1fb0e4c749600290000000000000000000000000000000000000000" + + "000000000000000000000000000000000000000000000000000000000000000000000000" + + "02c68af0bb140000"; + + // 0xF5DCe57282A584D2746FaF1593d3121Fcac444dC + // nonce: 14 + const mockCDaiDeploymentData = + "0x60806040523480156200001157600080fd5b506040516200523c3803806200523c8339" + + "81018060405260e08110156200003757600080fd5b815160208301516040840151606085" + + "0151608086018051949693959294919392830192916401000000008111156200006e5760" + + "0080fd5b820160208101848111156200008257600080fd5b815164010000000081118282" + + "01871017156200009d57600080fd5b505092919060200180516401000000008111156200" + + "00ba57600080fd5b82016020810184811115620000ce57600080fd5b8151640100000000" + + "811182820187101715620000e957600080fd5b5050602090910151600160005560048054" + + "6001600160a01b0319163317905560088690559092509050858585858585836200017057" + + "6040517f08c379a000000000000000000000000000000000000000000000000000000000" + + "81526004018080602001828103825260308152602001806200520c603091396040019150" + + "5060405180910390fd5b600062000183876200036460201b60201c565b90508015620001" + + "f357604080517f08c379a000000000000000000000000000000000000000000000000000" + + "000000815260206004820152601a60248201527f53657474696e6720636f6d7074726f6c" + + "6c6572206661696c6564000000000000604482015290519081900360640190fd5b620002" + + "03620004f760201b60201c565b600a55670de0b6b3a7640000600b556200022486620004" + + "fc602090811b901c565b905080156200027f576040517f08c379a0000000000000000000" + + "000000000000000000000000000000000000008152600401808060200182810382526022" + + "815260200180620051ea6022913960400191505060405180910390fd5b83516200029490" + + "60019060208701906200071e565b508251620002aa9060029060208601906200071e565b" + + "50506003555050601280546001600160a01b0319166001600160a01b038c811691909117" + + "91829055604080517f18160ddd0000000000000000000000000000000000000000000000" + + "0000000000815290519290911694506318160ddd93506004808201935060209291829003" + + "018186803b1580156200032857600080fd5b505afa1580156200033d573d6000803e3d60" + + "00fd5b505050506040513d60208110156200035457600080fd5b50620007c09750505050" + + "50505050565b6004546000906001600160a01b0316331462000396576200038e6001603f" + + "620006ae60201b60201c565b9050620004f2565b600654604080517e7e3dd20000000000" + + "0000000000000000000000000000000000000000000000815290516001600160a01b0392" + + "831692851691627e3dd2916004808301926020929190829003018186803b158015620003" + + "f557600080fd5b505afa1580156200040a573d6000803e3d6000fd5b505050506040513d" + + "60208110156200042157600080fd5b50516200048f57604080517f08c379a00000000000" + + "0000000000000000000000000000000000000000000000815260206004820152601c6024" + + "8201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000" + + "604482015290519081900360640190fd5b600680546001600160a01b0319166001600160" + + "a01b03858116918217909255604080519284168352602083019190915280517f7ac369db" + + "d14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d9281900390910190" + + "a160005b9150505b919050565b435b90565b60045460009081906001600160a01b031633" + + "1462000531576200052860016042620006ae60201b60201c565b915050620004f2565b62" + + "000541620004f760201b60201c565b600a54146200055e5762000528600a6041620006ae" + + "60201b60201c565b600760009054906101000a90046001600160a01b0316905082600160" + + "0160a01b0316632191f92a6040518163ffffffff1660e01b815260040160206040518083" + + "038186803b158015620005b057600080fd5b505afa158015620005c5573d6000803e3d60" + + "00fd5b505050506040513d6020811015620005dc57600080fd5b50516200064a57604080" + + "517f08c379a0000000000000000000000000000000000000000000000000000000008152" + + "60206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65" + + "642066616c736500000000604482015290519081900360640190fd5b6007805460016001" + + "60a01b0319166001600160a01b0385811691821790925560408051928416835260208301" + + "9190915280517fedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d" + + "72f9269281900390910190a16000620004ee565b60007f45b96fe442630264581b197e84" + + "bbada861235052c5a1aadfff9ea4e40a969aa0836010811115620006de57fe5b83604d81" + + "1115620006eb57fe5b604080519283526020830191909152600082820152519081900360" + + "600190a18260108111156200071757fe5b9392505050565b828054600181600116156101" + + "000203166002900490600052602060002090601f016020900481019282601f1062000761" + + "57805160ff191683800117855562000791565b8280016001018555821562000791579182" + + "015b828111156200079157825182559160200191906001019062000774565b506200079f" + + "929150620007a3565b5090565b620004f991905b808211156200079f5760008155600101" + + "620007aa565b614a1a80620007d06000396000f3fe608060405234801561001057600080" + + "fd5b506004361061028a5760003560e01c80638f840ddd1161015c578063c37f68e21161" + + "00ce578063f3fdb15a11610087578063f3fdb15a14610708578063f5e3c4621461071057" + + "8063f851a44014610746578063f8f9da281461074e578063fca7820b14610756578063fe" + + "9c44ae146107735761028a565b8063c37f68e214610626578063c5ebeaec146106725780" + + "63db006a751461068f578063dd62ed3e146106ac578063e9c714f2146106da578063f2b3" + + "abbd146106e25761028a565b8063a9059cbb11610120578063a9059cbb14610586578063" + + "aa5af0fd146105b2578063ae9d70b0146105ba578063b2a02ff1146105c2578063b71d1a" + + "0c146105f8578063bd6d894d1461061e5761028a565b80638f840ddd1461052b57806395" + + "d89b411461053357806395dd91931461053b578063a0712d6814610561578063a6afed95" + + "1461057e5761028a565b80633af9e66911610200578063675d972c116101b9578063675d" + + "972c146104c85780636c540baf146104d05780636f307dc3146104d857806370a0823114" + + "6104e057806373acee9814610506578063852a12e31461050e5761028a565b80633af9e6" + + "69146104475780633b1d21a21461046d5780634576b5db1461047557806347bd37181461" + + "049b5780635fe3b567146104a3578063601a0bf1146104ab5761028a565b806318160ddd" + + "1161025257806318160ddd146103a9578063182df0f5146103b157806323b872dd146103" + + "b95780632608f818146103ef578063267822471461041b578063313ce5671461043f5761" + + "028a565b806306fdde031461028f578063095ea7b31461030c5780630e7527021461034c" + + "578063173b99041461037b57806317bfdfbc14610383575b600080fd5b61029761077b56" + + "5b6040805160208082528351818301528351919283929083019185019080838360005b83" + + "8110156102d15781810151838201526020016102b9565b50505050905090810190601f16" + + "80156102fe5780820380516001836020036101000a031916815260200191505b50925050" + + "5060405180910390f35b6103386004803603604081101561032257600080fd5b50600160" + + "0160a01b038135169060200135610808565b604080519115158252519081900360200190" + + "f35b6103696004803603602081101561036257600080fd5b5035610875565b6040805191" + + "8252519081900360200190f35b610369610888565b610369600480360360208110156103" + + "9957600080fd5b50356001600160a01b031661088e565b610369610951565b6103696109" + + "57565b610338600480360360608110156103cf57600080fd5b506001600160a01b038135" + + "811691602081013590911690604001356109bd565b610369600480360360408110156104" + + "0557600080fd5b506001600160a01b038135169060200135610a29565b610423610a3c56" + + "5b604080516001600160a01b039092168252519081900360200190f35b610369610a4b56" + + "5b6103696004803603602081101561045d57600080fd5b50356001600160a01b0316610a" + + "51565b610369610abf565b6103696004803603602081101561048b57600080fd5b503560" + + "01600160a01b0316610ace565b610369610c23565b610423610c29565b61036960048036" + + "0360208110156104c157600080fd5b5035610c38565b610369610cc6565b610369610ccc" + + "565b610423610cd2565b610369600480360360208110156104f657600080fd5b50356001" + + "600160a01b0316610ce1565b610369610cfc565b61036960048036036020811015610524" + + "57600080fd5b5035610db6565b610369610dc1565b610297610dc7565b61036960048036" + + "03602081101561055157600080fd5b50356001600160a01b0316610e1f565b6103696004" + + "803603602081101561057757600080fd5b5035610e7f565b610369610e8a565b61033860" + + "04803603604081101561059c57600080fd5b506001600160a01b03813516906020013561" + + "1286565b6103696112f1565b6103696112f7565b610369600480360360608110156105d8" + + "57600080fd5b506001600160a01b038135811691602081013590911690604001356115d1" + + "565b6103696004803603602081101561060e57600080fd5b50356001600160a01b031661" + + "188e565b610369611915565b61064c6004803603602081101561063c57600080fd5b5035" + + "6001600160a01b03166119d0565b60408051948552602085019390935283830191909152" + + "6060830152519081900360800190f35b6103696004803603602081101561068857600080" + + "fd5b5035611a65565b610369600480360360208110156106a557600080fd5b5035611a70" + + "565b610369600480360360408110156106c257600080fd5b506001600160a01b03813581" + + "16916020013516611a7b565b610369611aa6565b610369600480360360208110156106f8" + + "57600080fd5b50356001600160a01b0316611b95565b610423611bcf565b610369600480" + + "3603606081101561072657600080fd5b506001600160a01b038135811691602081013591" + + "60409091013516611bde565b610423611beb565b610369611bfa565b6103696004803603" + + "602081101561076c57600080fd5b5035611cd9565b610338611d13565b60018054604080" + + "516020600284861615610100026000190190941693909304601f81018490048402820184" + + "0190925281815292918301828280156108005780601f106107d557610100808354040283" + + "529160200191610800565b820191906000526020600020905b8154815290600101906020" + + "018083116107e357829003601f168201915b505050505081565b33600081815260106020" + + "90815260408083206001600160a01b038716808552908352818420869055815186815291" + + "51939493909284927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200a" + + "c8c7c3b925929081900390910190a360019150505b92915050565b600061088082611d18" + + "565b90505b919050565b60095481565b60008054600101808255816108a1610e8a565b14" + + "6108f65760408051600160e51b62461bcd02815260206004820152601660248201527f61" + + "636372756520696e746572657374206661696c6564000000000000000000006044820152" + + "90519081900360640190fd5b6108ff83610e1f565b91505b600054811461094b57604080" + + "51600160e51b62461bcd02815260206004820152600a6024820152600160b21b691c994b" + + "595b9d195c995902604482015290519081900360640190fd5b50919050565b600e548156" + + "5b6000806000610964611d54565b9092509050600082600381111561097757fe5b146109" + + "b657604051600160e51b62461bcd02815260040180806020018281038252603581526020" + + "01806149626035913960400191505060405180910390fd5b9150505b90565b6000805460" + + "0101808255816109d433878787611e02565b1491505b6000548114610a21576040805160" + + "0160e51b62461bcd02815260206004820152600a6024820152600160b21b691c994b595b" + + "9d195c995902604482015290519081900360640190fd5b509392505050565b6000610a35" + + "8383612116565b9392505050565b6005546001600160a01b031681565b60035481565b60" + + "00610a5b6146bb565b6040518060200160405280610a6e611915565b90526001600160a0" + + "1b0384166000908152600f6020526040812054919250908190610a9a9084906121a6565b" + + "90925090506000826003811115610aad57fe5b14610ab757600080fd5b94935050505056" + + "5b6000610ac96121fa565b905090565b6004546000906001600160a01b03163314610af6" + + "57610aef6001603f61227d565b9050610883565b60065460408051600160e11b623f1ee9" + + "02815290516001600160a01b0392831692851691627e3dd2916004808301926020929190" + + "829003018186803b158015610b3e57600080fd5b505afa158015610b52573d6000803e3d" + + "6000fd5b505050506040513d6020811015610b6857600080fd5b5051610bbe5760408051" + + "600160e51b62461bcd02815260206004820152601c60248201527f6d61726b6572206d65" + + "74686f642072657475726e65642066616c73650000000060448201529051908190036064" + + "0190fd5b600680546001600160a01b0319166001600160a01b0385811691821790925560" + + "4080519284168352602083019190915280517f7ac369dbd14fa5ea3f473ed67cc9d59896" + + "4a77501540ba6751eb0b3decf5870d9281900390910190a160009392505050565b600c54" + + "81565b6006546001600160a01b031681565b6000805460010180825581610c4b610e8a56" + + "5b90508015610c7157610c69816010811115610c6257fe5b603061227d565b9250506109" + + "02565b610c7a846122e3565b925050600054811461094b5760408051600160e51b62461b" + + "cd02815260206004820152600a6024820152600160b21b691c994b595b9d195c99590260" + + "4482015290519081900360640190fd5b60085481565b600a5481565b6012546001600160" + + "a01b031681565b6001600160a01b03166000908152600f602052604090205490565b6000" + + "805460010180825581610d0f610e8a565b14610d645760408051600160e51b62461bcd02" + + "815260206004820152601660248201527f61636372756520696e74657265737420666169" + + "6c656400000000000000000000604482015290519081900360640190fd5b600c54915060" + + "00548114610db25760408051600160e51b62461bcd02815260206004820152600a602482" + + "0152600160b21b691c994b595b9d195c995902604482015290519081900360640190fd5b" + + "5090565b600061088082612467565b600d5481565b600280546040805160206001841615" + + "6101000260001901909316849004601f8101849004840282018401909252818152929183" + + "01828280156108005780601f106107d55761010080835404028352916020019161080056" + + "5b6000806000610e2d846124a4565b90925090506000826003811115610e4057fe5b1461" + + "0a3557604051600160e51b62461bcd028152600401808060200182810382526037815260" + + "2001806148366037913960400191505060405180910390fd5b600061088082612558565b" + + "6000610e946146ce565b6007546001600160a01b03166315f24053610ead6121fa565b60" + + "0c54600d546040518463ffffffff1660e01b815260040180848152602001838152602001" + + "8281526020019350505050604080518083038186803b158015610ef457600080fd5b505a" + + "fa158015610f08573d6000803e3d6000fd5b505050506040513d6040811015610f1e5760" + + "0080fd5b50805160209182015160408401819052918301526601c6bf526340001015610f" + + "905760408051600160e51b62461bcd02815260206004820152601c60248201527f626f72" + + "726f772072617465206973206162737572646c7920686967680000000060448201529051" + + "9081900360640190fd5b602081015115610fb357610fab60056002836020015161259356" + + "5b9150506109ba565b610fbb6125f9565b60608201819052600a54610fcf91906125fd56" + + "5b6080830181905282826003811115610fe357fe5b6003811115610fee57fe5b90525060" + + "0090508151600381111561100257fe5b1461100957fe5b61102960405180602001604052" + + "8083604001518152508260800151612620565b60a083018190528282600381111561103d" + + "57fe5b600381111561104857fe5b905250600090508151600381111561105c57fe5b1461" + + "107d57610fab600960068360000151600381111561107857fe5b612593565b61108d8160" + + "a00151600c546121a6565b60c08301819052828260038111156110a157fe5b6003811115" + + "6110ac57fe5b90525060009050815160038111156110c057fe5b146110dc57610fab6009" + + "60018360000151600381111561107857fe5b6110ec8160c00151600c54612688565b60e0" + + "83018190528282600381111561110057fe5b600381111561110b57fe5b90525060009050" + + "8151600381111561111f57fe5b1461113b57610fab600960048360000151600381111561" + + "107857fe5b61115c60405180602001604052806009548152508260c00151600d546126ae" + + "565b61010083018190528282600381111561117157fe5b600381111561117c57fe5b9052" + + "50600090508151600381111561119057fe5b146111ac57610fab60096005836000015160" + + "0381111561107857fe5b6111bf8160a00151600b54600b546126ae565b61012083018190" + + "52828260038111156111d457fe5b60038111156111df57fe5b9052506000905081516003" + + "8111156111f357fe5b1461120f57610fab600960038360000151600381111561107857fe" + + "5b606080820151600a55610120820151600b81905560e0830151600c8190556101008401" + + "51600d5560c08401516040805191825260208201939093528083019190915290517f8753" + + "52fb3fadeb8c0be7cbbe8ff761b308fa7033470cd0287f02f3436fd76cb9929181900390" + + "910190a1600091505090565b600080546001018082558161129d33338787611e02565b14" + + "91505b60005481146112ea5760408051600160e51b62461bcd0281526020600482015260" + + "0a6024820152600160b21b691c994b595b9d195c99590260448201529051908190036064" + + "0190fd5b5092915050565b600b5481565b600080611302610957565b6007549091506000" + + "9081906001600160a01b03166315f240536113236121fa565b600c54600d546040518463" + + "ffffffff1660e01b81526004018084815260200183815260200182815260200193505050" + + "50604080518083038186803b15801561136a57600080fd5b505afa15801561137e573d60" + + "00803e3d6000fd5b505050506040513d604081101561139457600080fd5b508051602090" + + "910151909250905081156113e257604051600160e51b62461bcd02815260040180806020" + + "01828103825260318152602001806148d56031913960400191505060405180910390fd5b" + + "60006113ec6146bb565b611406604051806020016040528087815250600e54612620565b" + + "9092509050600082600381111561141957fe5b1461145857604051600160e51b62461bcd" + + "02815260040180806020018281038252603181526020018061486d603191396040019150" + + "5060405180910390fd5b60006114626146bb565b61146e600c548461270a565b90925090" + + "50600082600381111561148157fe5b146114c057604051600160e51b62461bcd02815260" + + "04018080602001828103825260318152602001806147b160319139604001915050604051" + + "80910390fd5b60006114ca6146bb565b6114fa6040518060200160405280670de0b6b3a7" + + "6400008152506040518060200160405280600954815250612769565b9092509050600082" + + "600381111561150d57fe5b1461154c57604051600160e51b62461bcd0281526004018080" + + "6020018281038252603c815260200180614926603c913960400191505060405180910390" + + "fd5b60006115566146bb565b61156f60405180602001604052808b81525084876127a356" + + "5b9092509050600082600381111561158257fe5b146115c157604051600160e51b62461b" + + "cd0281526004018080602001828103825260318152602001806148056031913960400191" + + "505060405180910390fd5b519a505050505050505050505090565b600080546001018082" + + "5560065460408051600160e01b63d02f7351028152306004820152336024820152600160" + + "0160a01b0388811660448301528781166064830152608482018790529151859392909216" + + "9163d02f73519160a48082019260209290919082900301818787803b15801561164a5760" + + "0080fd5b505af115801561165e573d6000803e3d6000fd5b505050506040513d60208110" + + "1561167457600080fd5b5051905080156116935761168b6003601b83612593565b925050" + + "6109d8565b856001600160a01b0316856001600160a01b031614156116b95761168b6006" + + "601c61227d565b6001600160a01b0385166000908152600f602052604081205481908190" + + "6116e090886125fd565b909350915060008360038111156116f357fe5b14611716576117" + + "0b6009601a85600381111561107857fe5b9550505050506109d8565b6001600160a01b03" + + "89166000908152600f60205260409020546117399088612688565b909350905060008360" + + "0381111561174c57fe5b146117645761170b6009601985600381111561107857fe5b6001" + + "600160a01b038089166000818152600f60209081526040808320879055938d1680835291" + + "84902085905583518b815293519193600080516020614906833981519152929081900390" + + "910190a360065460408051600160e01b636d35bf91028152306004820152336024820152" + + "6001600160a01b038c811660448301528b81166064830152608482018b90529151919092" + + "1691636d35bf919160a480830192600092919082900301818387803b15801561181e5760" + + "0080fd5b505af1158015611832573d6000803e3d6000fd5b506000925061183f91505056" + + "5b9550505050506000548114610a215760408051600160e51b62461bcd02815260206004" + + "820152600a6024820152600160b21b691c994b595b9d195c995902604482015290519081" + + "900360640190fd5b6004546000906001600160a01b031633146118af57610aef60016045" + + "61227d565b600580546001600160a01b038481166001600160a01b031983168117909355" + + "6040805191909216808252602082019390935281517fca4f2f25d0898edd99413412fb94" + + "012f9e54ec8142f9b093e7720646a95b16a9929181900390910190a16000610a35565b60" + + "00805460010180825581611928610e8a565b1461197d5760408051600160e51b62461bcd" + + "02815260206004820152601660248201527f61636372756520696e746572657374206661" + + "696c656400000000000000000000604482015290519081900360640190fd5b6119856109" + + "57565b91506000548114610db25760408051600160e51b62461bcd028152602060048201" + + "52600a6024820152600160b21b691c994b595b9d195c9959026044820152905190819003" + + "60640190fd5b6001600160a01b0381166000908152600f60205260408120548190819081" + + "908180806119fb896124a4565b935090506000816003811115611a0d57fe5b14611a2b57" + + "60095b975060009650869550859450611a5e9350505050565b611a33611d54565b925090" + + "506000816003811115611a4557fe5b14611a51576009611a15565b506000965091945092" + + "5090505b9193509193565b6000610880826127ed565b600061088082612828565b600160" + + "0160a01b0391821660009081526010602090815260408083209390941682529190915220" + + "5490565b6005546000906001600160a01b031633141580611ac1575033155b15611ad957" + + "611ad26001600061227d565b90506109ba565b60048054600580546001600160a01b0380" + + "82166001600160a01b031980861682179687905590921690925560408051938316808552" + + "949092166020840152815190927ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f" + + "21c4e8146d8519b417dc92908290030190a1600554604080516001600160a01b03808516" + + "8252909216602083015280517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b0" + + "93e7720646a95b16a99281900390910190a160009250505090565b600080611ba0610e8a" + + "565b90508015611bc657611bbe816010811115611bb757fe5b604061227d565b91505061" + + "0883565b610a358361285e565b6007546001600160a01b031681565b6000610ab7848484" + + "6129d1565b6004546001600160a01b031681565b600754600090819081906001600160a0" + + "1b03166315f24053611c1a6121fa565b600c54600d546040518463ffffffff1660e01b81" + + "526004018084815260200183815260200182815260200193505050506040805180830381" + + "86803b158015611c6157600080fd5b505afa158015611c75573d6000803e3d6000fd5b50" + + "5050506040513d6040811015611c8b57600080fd5b508051602090910151909250905081" + + "156109b657604051600160e51b62461bcd02815260040180806020018281038252603781" + + "526020018061489e6037913960400191505060405180910390fd5b600080546001018082" + + "5581611cec610e8a565b90508015611d0a57610c69816010811115611d0357fe5b604661" + + "227d565b610c7a84612adf565b600181565b6000805460010180825581611d2b610e8a56" + + "5b90508015611d4957610c69816010811115611d4257fe5b603661227d565b610c7a3333" + + "86612b82565b600080600e5460001415611d6f575050600854600090611dfe565b600061" + + "1d796121fa565b90506000611d856146bb565b6000611d9684600c54600d54612fde565b" + + "935090506000816003811115611da857fe5b14611dbc57945060009350611dfe92505050" + + "565b611dc883600e5461301c565b925090506000816003811115611dda57fe5b14611dee" + + "57945060009350611dfe92505050565b5051600094509250611dfe915050565b9091565b" + + "60065460408051600160e31b6317b9b84b0281523060048201526001600160a01b038681" + + "16602483015285811660448301526064820185905291516000938493169163bdcdc25891" + + "608480830192602092919082900301818787803b158015611e6a57600080fd5b505af115" + + "8015611e7e573d6000803e3d6000fd5b505050506040513d6020811015611e9457600080" + + "fd5b505190508015611eb357611eab6003604a83612593565b915050610ab7565b836001" + + "600160a01b0316856001600160a01b03161415611ed957611eab6002604b61227d565b60" + + "006001600160a01b038781169087161415611ef85750600019611f20565b506001600160" + + "a01b038086166000908152601060209081526040808320938a16835292905220545b6000" + + "80600080611f3085896125fd565b90945092506000846003811115611f4357fe5b14611f" + + "6157611f546009604b61227d565b9650505050505050610ab7565b6001600160a01b038a" + + "166000908152600f6020526040902054611f8490896125fd565b90945091506000846003" + + "811115611f9757fe5b14611fa857611f546009604c61227d565b6001600160a01b038916" + + "6000908152600f6020526040902054611fcb9089612688565b9094509050600084600381" + + "1115611fde57fe5b14611fef57611f546009604d61227d565b6001600160a01b03808b16" + + "6000908152600f6020526040808220859055918b16815220819055600019851461204757" + + "6001600160a01b03808b166000908152601060209081526040808320938f168352929052" + + "208390555b886001600160a01b03168a6001600160a01b03166000805160206149068339" + + "815191528a6040518082815260200191505060405180910390a360065460408051600160" + + "e11b63352b4a3f0281523060048201526001600160a01b038d811660248301528c811660" + + "44830152606482018c905291519190921691636a56947e91608480830192600092919082" + + "900301818387803b1580156120e657600080fd5b505af11580156120fa573d6000803e3d" + + "6000fd5b5060009250612107915050565b9b9a5050505050505050505050565b60008054" + + "60010180825581612129610e8a565b9050801561214f5761214781601081111561214057" + + "fe5b603561227d565b9250506112a1565b61215a338686612b82565b9250506000548114" + + "6112ea5760408051600160e51b62461bcd02815260206004820152600a60248201526001" + + "60b21b691c994b595b9d195c995902604482015290519081900360640190fd5b60008060" + + "006121b36146bb565b6121bd8686612620565b909250905060008260038111156121d057" + + "fe5b146121e157509150600090506121f3565b60006121ec826130cc565b935093505050" + + "5b9250929050565b60125460408051600160e01b6370a082310281523060048201529051" + + "6000926001600160a01b03169182916370a0823191602480820192602092909190829003" + + "018186803b15801561224b57600080fd5b505afa15801561225f573d6000803e3d6000fd" + + "5b505050506040513d602081101561227557600080fd5b505191505090565b60007f45b9" + + "6fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0836010811115" + + "6122ac57fe5b83604d8111156122b857fe5b604080519283526020830191909152600082" + + "820152519081900360600190a1826010811115610a3557fe5b6004546000908190819060" + + "01600160a01b03163314612311576123086001603161227d565b92505050610883565b61" + + "23196125f9565b600a541461232d57612308600a603361227d565b836123366121fa565b" + + "101561234857612308600e603261227d565b600d5484111561235e576123086002603461" + + "227d565b50600d54838103908111156123a757604051600160e51b62461bcd0281526004" + + "018080602001828103825260248152602001806149cb6024913960400191505060405180" + + "910390fd5b600d8190556004546123c2906001600160a01b0316856130db565b91506000" + + "8260108111156123d257fe5b1461241157604051600160e51b62461bcd02815260040180" + + "80602001828103825260238152602001806147e260239139604001915050604051809103" + + "90fd5b600454604080516001600160a01b03909216825260208201869052818101839052" + + "517f3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e9181" + + "900360600190a16000949350505050565b600080546001018082558161247a610e8a565b" + + "9050801561249857610c6981601081111561249157fe5b602761227d565b610c7a336000" + + "8661319a565b6001600160a01b0381166000908152601160205260408120805482918291" + + "829182916124db57506000945084935061255392505050565b6124eb8160000154600b54" + + "6136af565b909450925060008460038111156124fe57fe5b146125135750919350600092" + + "50612553915050565b6125218382600101546136ee565b90945091506000846003811115" + + "61253457fe5b14612549575091935060009250612553915050565b506000945092505050" + + "5b915091565b600080546001018082558161256b610e8a565b9050801561258957610c69" + + "81601081111561258257fe5b601e61227d565b610c7a3385613719565b60007f45b96fe4" + + "42630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08460108111156125" + + "c257fe5b84604d8111156125ce57fe5b6040805192835260208301919091528181018590" + + "52519081900360600190a1836010811115610ab757fe5b4390565b600080838311612614" + + "5750600090508183036121f3565b506003905060006121f3565b600061262a6146bb565b" + + "60008061263b8660000151866136af565b9092509050600082600381111561264e57fe5b" + + "1461266d575060408051602081019091526000815290925090506121f3565b6040805160" + + "2081019091529081526000969095509350505050565b6000808383018481106126a05760" + + "00925090506121f3565b5060029150600090506121f3565b60008060006126bb6146bb56" + + "5b6126c58787612620565b909250905060008260038111156126d857fe5b146126e95750" + + "915060009050612702565b6126fb6126f5826130cc565b86612688565b9350935050505b" + + "935093915050565b60006127146146bb565b600080612729670de0b6b3a7640000876136" + + "af565b9092509050600082600381111561273c57fe5b1461275b57506040805160208101" + + "9091526000815290925090506121f3565b6121ec81866000015161301c565b6000612773" + + "6146bb565b600080612788866000015186600001516125fd565b60408051602081019091" + + "529081529097909650945050505050565b60006127ad6146bb565b60006127b76146bb56" + + "5b6127c18787613b67565b909250905060008260038111156127d457fe5b146127e35790" + + "92509050612702565b6126fb8186613b67565b6000805460010180825581612800610e8a" + + "565b9050801561281e57610c6981601081111561281757fe5b600861227d565b610c7a33" + + "85613c50565b600080546001018082558161283b610e8a565b9050801561285257610c69" + + "81601081111561249157fe5b610c7a3385600061319a565b600454600090819060016001" + + "60a01b0316331461288157611bbe6001604261227d565b6128896125f9565b600a541461" + + "289d57611bbe600a604161227d565b600760009054906101000a90046001600160a01b03" + + "169050826001600160a01b0316632191f92a6040518163ffffffff1660e01b8152600401" + + "60206040518083038186803b1580156128ee57600080fd5b505afa158015612902573d60" + + "00803e3d6000fd5b505050506040513d602081101561291857600080fd5b505161296e57" + + "60408051600160e51b62461bcd02815260206004820152601c60248201527f6d61726b65" + + "72206d6574686f642072657475726e65642066616c736500000000604482015290519081" + + "900360640190fd5b600780546001600160a01b0319166001600160a01b03858116918217" + + "909255604080519284168352602083019190915280517fedffc32e068c7c95dfd4bdfd5c" + + "4d939a084d6b11c4199eac8436ed234d72f9269281900390910190a16000610a35565b60" + + "008054600101808255816129e4610e8a565b90508015612a025761168b81601081111561" + + "29fb57fe5b600f61227d565b836001600160a01b031663a6afed956040518163ffffffff" + + "1660e01b8152600401602060405180830381600087803b158015612a3d57600080fd5b50" + + "5af1158015612a51573d6000803e3d6000fd5b505050506040513d6020811015612a6757" + + "600080fd5b505190508015612a875761168b816010811115612a8057fe5b601061227d56" + + "5b612a9333878787613fbf565b9250506000548114610a215760408051600160e51b6246" + + "1bcd02815260206004820152600a6024820152600160b21b691c994b595b9d195c995902" + + "604482015290519081900360640190fd5b6004546000906001600160a01b03163314612b" + + "0057610aef6001604761227d565b612b086125f9565b600a5414612b1c57610aef600a60" + + "4861227d565b670de0b6b3a7640000821115612b3857610aef6002604961227d565b6009" + + "805490839055604080518281526020810185905281517faaa68312e2ea9d50e16af50684" + + "10ab56e1a1fd06037b1a35664812c30f821460929181900390910190a16000610a35565b" + + "60065460408051600160e11b63120045310281523060048201526001600160a01b038681" + + "1660248301528581166044830152606482018590529151600093849316916324008a6291" + + "608480830192602092919082900301818787803b158015612bea57600080fd5b505af115" + + "8015612bfe573d6000803e3d6000fd5b505050506040513d6020811015612c1457600080" + + "fd5b505190508015612c3357612c2b6003603883612593565b915050610a35565b612c3b" + + "6125f9565b600a5414612c4f57612c2b600a603961227d565b612c57614728565b600160" + + "0160a01b0385166000908152601160205260409020600101546060820152612c81856124" + + "a4565b6080830181905260208301826003811115612c9857fe5b6003811115612ca357fe" + + "5b9052506000905081602001516003811115612cba57fe5b14612cdf57612cd660096037" + + "8360200151600381111561107857fe5b92505050610a35565b600019841415612cf85760" + + "808101516040820152612d00565b604081018490525b612d0e8682604001516144b3565b" + + "81906010811115612d1b57fe5b90816010811115612d2857fe5b90525060008151601081" + + "1115612d3a57fe5b14612d4c578051612cd690603c61227d565b612d5e81608001518260" + + "4001516125fd565b60a0830181905260208301826003811115612d7557fe5b6003811115" + + "612d8057fe5b9052506000905081602001516003811115612d9757fe5b14612db357612c" + + "d66009603a8360200151600381111561107857fe5b612dc3600c5482604001516125fd56" + + "5b60c0830181905260208301826003811115612dda57fe5b6003811115612de557fe5b90" + + "52506000905081602001516003811115612dfc57fe5b14612e1857612cd66009603b8360" + + "200151600381111561107857fe5b612e268682604001516145ea565b8190601081111561" + + "2e3357fe5b90816010811115612e4057fe5b905250600081516010811115612e5257fe5b" + + "14612ea75760408051600160e51b62461bcd02815260206004820152601f60248201527f" + + "726570617920626f72726f77207472616e7366657220696e206661696c65640060448201" + + "5290519081900360640190fd5b60a080820180516001600160a01b038089166000818152" + + "60116020908152604091829020948555600b5460019095019490945560c0870151600c81" + + "90558188015195518251948e168552948401929092528281019490945260608201929092" + + "52608081019190915290517f1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0" + + "355478d6f5c362a1929181900390910190a1600654604080830151606084015182516001" + + "60e01b631ededc910281523060048201526001600160a01b038b811660248301528a8116" + + "6044830152606482019390935260848101919091529151921691631ededc919160a48082" + + "019260009290919082900301818387803b158015612fb357600080fd5b505af115801561" + + "2fc7573d6000803e3d6000fd5b5060009250612fd4915050565b9695505050505050565b" + + "600080600080612fee8787612688565b9092509050600082600381111561300157fe5b14" + + "6130125750915060009050612702565b6126fb81866125fd565b60006130266146bb565b" + + "60008061303b86670de0b6b3a76400006136af565b909250905060008260038111156130" + + "4e57fe5b1461306d575060408051602081019091526000815290925090506121f3565b60" + + "008061307a83886136ee565b9092509050600082600381111561308d57fe5b146130af57" + + "5060408051602081019091526000815290945092506121f3915050565b60408051602081" + + "0190915290815260009890975095505050505050565b51670de0b6b3a764000090049056" + + "5b60125460408051600160e01b63a9059cbb0281526001600160a01b0385811660048301" + + "5260248201859052915160009392909216918391839163a9059cbb916044808201928692" + + "90919082900301818387803b15801561313a57600080fd5b505af115801561314e573d60" + + "00803e3d6000fd5b505050503d60008114613168576020811461317257600080fd5b6000" + + "19915061317e565b60206000803e60005191505b508061318f5760109250505061086f56" + + "5b506000949350505050565b60008215806131a7575081155b6131e557604051600160e5" + + "1b62461bcd02815260040180806020018281038252603481526020018061499760349139" + + "60400191505060405180910390fd5b6131ed614728565b6131f5611d54565b6040830181" + + "90526020830182600381111561320c57fe5b600381111561321757fe5b90525060009050" + + "8160200151600381111561322e57fe5b1461324a57612c2b6009602b8360200151600381" + + "111561107857fe5b83156132cb5760608101849052604080516020810182529082015181" + + "5261327190856121a6565b608083018190526020830182600381111561328857fe5b6003" + + "81111561329357fe5b90525060009050816020015160038111156132aa57fe5b146132c6" + + "57612c2b600960298360200151600381111561107857fe5b613344565b6132e783604051" + + "806020016040528084604001518152506146a4565b606083018190526020830182600381" + + "11156132fe57fe5b600381111561330957fe5b9052506000905081602001516003811115" + + "61332057fe5b1461333c57612c2b6009602a8360200151600381111561107857fe5b6080" + + "81018390525b600654606082015160408051600160e01b63eabe7d910281523060048201" + + "526001600160a01b03898116602483015260448201939093529051600093929092169163" + + "eabe7d919160648082019260209290919082900301818787803b1580156133ac57600080" + + "fd5b505af11580156133c0573d6000803e3d6000fd5b505050506040513d602081101561" + + "33d657600080fd5b5051905080156133ed57612cd66003602883612593565b6133f56125" + + "f9565b600a541461340957612cd6600a602c61227d565b613419600e5483606001516125" + + "fd565b60a084018190526020840182600381111561343057fe5b600381111561343b57fe" + + "5b905250600090508260200151600381111561345257fe5b1461346e57612cd66009602e" + + "8460200151600381111561107857fe5b6001600160a01b0386166000908152600f602052" + + "6040902054606083015161349691906125fd565b60c08401819052602084018260038111" + + "156134ad57fe5b60038111156134b857fe5b905250600090508260200151600381111561" + + "34cf57fe5b146134eb57612cd66009602d8460200151600381111561107857fe5b816080" + + "01516134f86121fa565b101561350a57612cd6600e602f61227d565b6135188683608001" + + "516130db565b8290601081111561352557fe5b9081601081111561353257fe5b90525060" + + "008251601081111561354457fe5b146135995760408051600160e51b62461bcd02815260" + + "206004820152601a60248201527f72656465656d207472616e73666572206f7574206661" + + "696c6564000000000000604482015290519081900360640190fd5b60a0820151600e5560" + + "c08201516001600160a01b0387166000818152600f602090815260409182902093909355" + + "6060850151815190815290513093600080516020614906833981519152928290030190a3" + + "6080820151606080840151604080516001600160a01b038b168152602081019490945283" + + "810191909152517fe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4" + + "ec31a9299281900390910190a16006546080830151606084015160408051600160e01b63" + + "51dff9890281523060048201526001600160a01b038b8116602483015260448201949094" + + "5260648101929092525191909216916351dff98991608480830192600092919082900301" + + "818387803b158015612fb357600080fd5b600080836136c2575060009050806121f3565b" + + "838302838582816136cf57fe5b04146136e3575060029150600090506121f3565b600092" + + "5090506121f3565b6000808261370257506001905060006121f3565b600083858161370d" + + "57fe5b04915091509250929050565b60065460408051600160e01b634ef4c3e102815230" + + "60048201526001600160a01b038581166024830152604482018590529151600093849316" + + "91634ef4c3e191606480830192602092919082900301818787803b158015613779576000" + + "80fd5b505af115801561378d573d6000803e3d6000fd5b505050506040513d6020811015" + + "6137a357600080fd5b5051905080156137c2576137ba6003601f83612593565b91505061" + + "086f565b6137ca6125f9565b600a54146137de576137ba600a602261227d565b6137e661" + + "4766565b6137f085856144b3565b819060108111156137fd57fe5b908160108111156138" + + "0a57fe5b90525060008151601081111561381c57fe5b1461383757805161382e90602661" + + "227d565b9250505061086f565b61383f611d54565b604083018190526020830182600381" + + "111561385657fe5b600381111561386157fe5b9052506000905081602001516003811115" + + "61387857fe5b146138945761382e600960218360200151600381111561107857fe5b6138" + + "b084604051806020016040528084604001518152506146a4565b60608301819052602083" + + "018260038111156138c757fe5b60038111156138d257fe5b905250600090508160200151" + + "60038111156138e957fe5b146139055761382e6009602083602001516003811115611078" + + "57fe5b613915600e548260600151612688565b6080830181905260208301826003811115" + + "61392c57fe5b600381111561393757fe5b90525060009050816020015160038111156139" + + "4e57fe5b1461396a5761382e600960248360200151600381111561107857fe5b60016001" + + "60a01b0385166000908152600f602052604090205460608201516139929190612688565b" + + "60a08301819052602083018260038111156139a957fe5b60038111156139b457fe5b9052" + + "5060009050816020015160038111156139cb57fe5b146139e75761382e60096023836020" + + "0151600381111561107857fe5b6139f185856145ea565b819060108111156139fe57fe5b" + + "90816010811115613a0b57fe5b905250600081516010811115613a1d57fe5b14613a2f57" + + "805161382e90602561227d565b6080810151600e5560a08101516001600160a01b038616" + + "6000818152600f6020908152604091829020939093556060808501518251938452938301" + + "88905282820193909352517f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef" + + "26394f4c03821c4f929181900390910190a1606081015160408051918252516001600160" + + "a01b0387169130916000805160206149068339815191529181900360200190a360065460" + + "6082015160408051600160e01b6341c728b90281523060048201526001600160a01b0389" + + "81166024830152604482018990526064820193909352905191909216916341c728b99160" + + "8480830192600092919082900301818387803b158015613b3d57600080fd5b505af11580" + + "15613b51573d6000803e3d6000fd5b5060009250613b5e915050565b9594505050505056" + + "5b6000613b716146bb565b600080613b86866000015186600001516136af565b90925090" + + "506000826003811115613b9957fe5b14613bb85750604080516020810190915260008152" + + "90925090506121f3565b600080613bcd6706f05b59d3b2000084612688565b9092509050" + + "6000826003811115613be057fe5b14613c02575060408051602081019091526000815290" + + "945092506121f3915050565b600080613c1783670de0b6b3a76400006136ee565b909250" + + "90506000826003811115613c2a57fe5b14613c3157fe5b60408051602081019091529081" + + "5260009a909950975050505050505050565b60065460408051600160e21b63368f515302" + + "81523060048201526001600160a01b038581166024830152604482018590529151600093" + + "8493169163da3d454c91606480830192602092919082900301818787803b158015613cb0" + + "57600080fd5b505af1158015613cc4573d6000803e3d6000fd5b505050506040513d6020" + + "811015613cda57600080fd5b505190508015613cf1576137ba6003600e83612593565b61" + + "3cf96125f9565b600a5414613d0c576137ba600a8061227d565b82613d156121fa565b10" + + "15613d27576137ba600e600961227d565b613d2f614780565b613d38856124a4565b6040" + + "830181905260208301826003811115613d4f57fe5b6003811115613d5a57fe5b90525060" + + "00905081602001516003811115613d7157fe5b14613d8d5761382e600960078360200151" + + "600381111561107857fe5b613d9b816040015185612688565b6060830181905260208301" + + "826003811115613db257fe5b6003811115613dbd57fe5b90525060009050816020015160" + + "03811115613dd457fe5b14613df05761382e6009600c8360200151600381111561107857" + + "fe5b613dfc600c5485612688565b6080830181905260208301826003811115613e1357fe" + + "5b6003811115613e1e57fe5b9052506000905081602001516003811115613e3557fe5b14" + + "613e515761382e6009600b8360200151600381111561107857fe5b613e5b85856130db56" + + "5b81906010811115613e6857fe5b90816010811115613e7557fe5b905250600081516010" + + "811115613e8757fe5b14613edc5760408051600160e51b62461bcd028152602060048201" + + "52601a60248201527f626f72726f77207472616e73666572206f7574206661696c656400" + + "0000000000604482015290519081900360640190fd5b606080820180516001600160a01b" + + "038816600081815260116020908152604091829020938455600b54600190940193909355" + + "608080870151600c819055945182519384529383018a9052828201939093529381019290" + + "925291517f13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab" + + "80929181900390910190a160065460408051600160e01b635c7786050281523060048201" + + "526001600160a01b0388811660248301526044820188905291519190921691635c778605" + + "91606480830192600092919082900301818387803b158015613b3d57600080fd5b600654" + + "60408051600160e11b632fe3f38f0281523060048201526001600160a01b038481166024" + + "830152878116604483015286811660648301526084820186905291516000938493169163" + + "5fc7e71e9160a480830192602092919082900301818787803b15801561402f57600080fd" + + "5b505af1158015614043573d6000803e3d6000fd5b505050506040513d60208110156140" + + "5957600080fd5b50519050801561407057611eab6003601283612593565b6140786125f9" + + "565b600a541461408c57611eab600a601661227d565b6140946125f9565b836001600160" + + "a01b0316636c540baf6040518163ffffffff1660e01b8152600401602060405180830381" + + "86803b1580156140cd57600080fd5b505afa1580156140e1573d6000803e3d6000fd5b50" + + "5050506040513d60208110156140f757600080fd5b50511461410a57611eab600a601161" + + "227d565b856001600160a01b0316856001600160a01b0316141561413057611eab600660" + + "1761227d565b8361414157611eab6007601561227d565b60001984141561415757611eab" + + "6007601461227d565b60065460408051600160e01b63c488847b02815230600482015260" + + "01600160a01b038681166024830152604482018890528251600094859492169263c48884" + + "7b926064808301939192829003018186803b1580156141b457600080fd5b505afa158015" + + "6141c8573d6000803e3d6000fd5b505050506040513d60408110156141de57600080fd5b" + + "50805160209091015190925090508115614209576141ff6004601384612593565b935050" + + "5050610ab7565b846001600160a01b03166370a08231886040518263ffffffff1660e01b" + + "815260040180826001600160a01b03166001600160a01b03168152602001915050602060" + + "40518083038186803b15801561425f57600080fd5b505afa158015614273573d6000803e" + + "3d6000fd5b505050506040513d602081101561428957600080fd5b505181111561429e57" + + "6141ff600d601d61227d565b60006142ab898989612b82565b905080156142d4576142c9" + + "8160108111156142c257fe5b601861227d565b945050505050610ab7565b604080516001" + + "60e01b63b2a02ff10281526001600160a01b038b811660048301528a8116602483015260" + + "448201859052915160009289169163b2a02ff19160648083019260209291908290030181" + + "8787803b15801561433257600080fd5b505af1158015614346573d6000803e3d6000fd5b" + + "505050506040513d602081101561435c57600080fd5b5051905080156143b65760408051" + + "600160e51b62461bcd02815260206004820152601460248201527f746f6b656e20736569" + + "7a757265206661696c656400000000000000000000000060448201529051908190036064" + + "0190fd5b604080516001600160a01b03808d168252808c1660208301528183018b905289" + + "1660608201526080810185905290517f298637f684da70674f26509b10f07ec2fbc77a33" + + "5ab1e7d6215a4b2484d8bb529181900360a00190a160065460408051600160e01b6347ef" + + "3b3b0281523060048201526001600160a01b038a811660248301528d811660448301528c" + + "81166064830152608482018c905260a48201879052915191909216916347ef3b3b9160c4" + + "80830192600092919082900301818387803b15801561448457600080fd5b505af1158015" + + "614498573d6000803e3d6000fd5b50600092506144a5915050565b9a9950505050505050" + + "505050565b60125460408051600160e11b636eb1769f0281526001600160a01b03858116" + + "6004830152306024830152915160009392909216918491839163dd62ed3e916044808201" + + "92602092909190829003018186803b15801561451157600080fd5b505afa158015614525" + + "573d6000803e3d6000fd5b505050506040513d602081101561453b57600080fd5b505110" + + "1561454d57600c91505061086f565b82816001600160a01b03166370a082318660405182" + + "63ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152" + + "60200191505060206040518083038186803b1580156145a457600080fd5b505afa158015" + + "6145b8573d6000803e3d6000fd5b505050506040513d60208110156145ce57600080fd5b" + + "505110156145e057600d91505061086f565b5060009392505050565b6012546040805160" + + "0160e01b6323b872dd0281526001600160a01b0385811660048301523060248301526044" + + "820185905291516000939290921691839183916323b872dd916064808201928692909190" + + "82900301818387803b15801561464f57600080fd5b505af1158015614663573d6000803e" + + "3d6000fd5b505050503d6000811461467d576020811461468757600080fd5b6000199150" + + "614693565b60206000803e60005191505b508061318f57600f9250505061086f565b6000" + + "8060006146b16146bb565b6121bd868661270a565b604051806020016040528060008152" + + "5090565b6040805161014081019091528060008152602001600081526020016000815260" + + "200160008152602001600081526020016147066146bb565b815260200160008152602001" + + "6000815260200160008152602001600081525090565b6040805160e08101909152806000" + + "815260200160008152602001600081526020016000815260200160008152602001600081" + + "52602001600081525090565b6040805160c0810190915280600081526020016000614706" + + "565b6040805160a081019091528060008152602001600081526020016000815260200160" + + "00815260200160008152509056fe737570706c7952617465506572426c6f636b3a206361" + + "6c63756c6174696e6720626f72726f7773506572206661696c6564726564756365207265" + + "736572766573207472616e73666572206f7574206661696c6564737570706c7952617465" + + "506572426c6f636b3a2063616c63756c6174696e6720737570706c795261746520666169" + + "6c6564626f72726f7742616c616e636553746f7265643a20626f72726f7742616c616e63" + + "6553746f726564496e7465726e616c206661696c6564737570706c795261746550657242" + + "6c6f636b3a2063616c63756c6174696e6720756e6465726c79696e67206661696c656462" + + "6f72726f7752617465506572426c6f636b3a20696e746572657374526174654d6f64656c" + + "2e626f72726f7752617465206661696c6564737570706c7952617465506572426c6f636b" + + "3a2063616c63756c6174696e6720626f72726f7752617465206661696c6564ddf252ad1b" + + "e2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef737570706c79526174" + + "65506572426c6f636b3a2063616c63756c6174696e67206f6e654d696e75735265736572" + + "7665466163746f72206661696c656465786368616e67655261746553746f7265643a2065" + + "786368616e67655261746553746f726564496e7465726e616c206661696c65646f6e6520" + + "6f662072656465656d546f6b656e73496e206f722072656465656d416d6f756e74496e20" + + "6d757374206265207a65726f72656475636520726573657276657320756e657870656374" + + "656420756e646572666c6f77a165627a7a72305820ae92d0e3e70b657d01891c7457bc6c" + + "8a5ce2401a1a8857f346a2fa9af4627145002953657474696e6720696e74657265737420" + + "72617465206d6f64656c206661696c6564496e697469616c2065786368616e6765207261" + + "7465206d7573742062652067726561746572207468616e207a65726f2e" + + "00000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359" + // dai + "0000000000000000000000003d9819210a31b4961b30ef54be2aed79b9c9cd3b" + // troll + "000000000000000000000000a1046abfc2598f48c44fb320d281d3f3c0733c9a" + // IRM + "000000000000000000000000000000000000000000a56fa5b99019a5c8000000" + + "00000000000000000000000000000000000000000000000000000000000000e0" + + "0000000000000000000000000000000000000000000000000000000000000120" + + "0000000000000000000000000000000000000000000000000000000000000008" + + "000000000000000000000000000000000000000000000000000000000000000c" + + "436f6d706f756e64204461690000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000004" + + "6344414900000000000000000000000000000000000000000000000000000000"; + + // 0x39AA39c021dfbaE8faC545936693aC917d5E7563 + // nonce: 17 + const mockCUSDCDeploymentData = + "0x60806040523480156200001157600080fd5b506040516200523c3803806200523c8339" + + "81018060405260e08110156200003757600080fd5b815160208301516040840151606085" + + "0151608086018051949693959294919392830192916401000000008111156200006e5760" + + "0080fd5b820160208101848111156200008257600080fd5b815164010000000081118282" + + "01871017156200009d57600080fd5b505092919060200180516401000000008111156200" + + "00ba57600080fd5b82016020810184811115620000ce57600080fd5b8151640100000000" + + "811182820187101715620000e957600080fd5b5050602090910151600160005560048054" + + "6001600160a01b0319163317905560088690559092509050858585858585836200017057" + + "6040517f08c379a000000000000000000000000000000000000000000000000000000000" + + "81526004018080602001828103825260308152602001806200520c603091396040019150" + + "5060405180910390fd5b600062000183876200036460201b60201c565b90508015620001" + + "f357604080517f08c379a000000000000000000000000000000000000000000000000000" + + "000000815260206004820152601a60248201527f53657474696e6720636f6d7074726f6c" + + "6c6572206661696c6564000000000000604482015290519081900360640190fd5b620002" + + "03620004f760201b60201c565b600a55670de0b6b3a7640000600b556200022486620004" + + "fc602090811b901c565b905080156200027f576040517f08c379a0000000000000000000" + + "000000000000000000000000000000000000008152600401808060200182810382526022" + + "815260200180620051ea6022913960400191505060405180910390fd5b83516200029490" + + "60019060208701906200071e565b508251620002aa9060029060208601906200071e565b" + + "50506003555050601280546001600160a01b0319166001600160a01b038c811691909117" + + "91829055604080517f18160ddd0000000000000000000000000000000000000000000000" + + "0000000000815290519290911694506318160ddd93506004808201935060209291829003" + + "018186803b1580156200032857600080fd5b505afa1580156200033d573d6000803e3d60" + + "00fd5b505050506040513d60208110156200035457600080fd5b50620007c09750505050" + + "50505050565b6004546000906001600160a01b0316331462000396576200038e6001603f" + + "620006ae60201b60201c565b9050620004f2565b600654604080517e7e3dd20000000000" + + "0000000000000000000000000000000000000000000000815290516001600160a01b0392" + + "831692851691627e3dd2916004808301926020929190829003018186803b158015620003" + + "f557600080fd5b505afa1580156200040a573d6000803e3d6000fd5b505050506040513d" + + "60208110156200042157600080fd5b50516200048f57604080517f08c379a00000000000" + + "0000000000000000000000000000000000000000000000815260206004820152601c6024" + + "8201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000" + + "604482015290519081900360640190fd5b600680546001600160a01b0319166001600160" + + "a01b03858116918217909255604080519284168352602083019190915280517f7ac369db" + + "d14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d9281900390910190" + + "a160005b9150505b919050565b435b90565b60045460009081906001600160a01b031633" + + "1462000531576200052860016042620006ae60201b60201c565b915050620004f2565b62" + + "000541620004f760201b60201c565b600a54146200055e5762000528600a6041620006ae" + + "60201b60201c565b600760009054906101000a90046001600160a01b0316905082600160" + + "0160a01b0316632191f92a6040518163ffffffff1660e01b815260040160206040518083" + + "038186803b158015620005b057600080fd5b505afa158015620005c5573d6000803e3d60" + + "00fd5b505050506040513d6020811015620005dc57600080fd5b50516200064a57604080" + + "517f08c379a0000000000000000000000000000000000000000000000000000000008152" + + "60206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65" + + "642066616c736500000000604482015290519081900360640190fd5b6007805460016001" + + "60a01b0319166001600160a01b0385811691821790925560408051928416835260208301" + + "9190915280517fedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d" + + "72f9269281900390910190a16000620004ee565b60007f45b96fe442630264581b197e84" + + "bbada861235052c5a1aadfff9ea4e40a969aa0836010811115620006de57fe5b83604d81" + + "1115620006eb57fe5b604080519283526020830191909152600082820152519081900360" + + "600190a18260108111156200071757fe5b9392505050565b828054600181600116156101" + + "000203166002900490600052602060002090601f016020900481019282601f1062000761" + + "57805160ff191683800117855562000791565b8280016001018555821562000791579182" + + "015b828111156200079157825182559160200191906001019062000774565b506200079f" + + "929150620007a3565b5090565b620004f991905b808211156200079f5760008155600101" + + "620007aa565b614a1a80620007d06000396000f3fe608060405234801561001057600080" + + "fd5b506004361061028a5760003560e01c80638f840ddd1161015c578063c37f68e21161" + + "00ce578063f3fdb15a11610087578063f3fdb15a14610708578063f5e3c4621461071057" + + "8063f851a44014610746578063f8f9da281461074e578063fca7820b14610756578063fe" + + "9c44ae146107735761028a565b8063c37f68e214610626578063c5ebeaec146106725780" + + "63db006a751461068f578063dd62ed3e146106ac578063e9c714f2146106da578063f2b3" + + "abbd146106e25761028a565b8063a9059cbb11610120578063a9059cbb14610586578063" + + "aa5af0fd146105b2578063ae9d70b0146105ba578063b2a02ff1146105c2578063b71d1a" + + "0c146105f8578063bd6d894d1461061e5761028a565b80638f840ddd1461052b57806395" + + "d89b411461053357806395dd91931461053b578063a0712d6814610561578063a6afed95" + + "1461057e5761028a565b80633af9e66911610200578063675d972c116101b9578063675d" + + "972c146104c85780636c540baf146104d05780636f307dc3146104d857806370a0823114" + + "6104e057806373acee9814610506578063852a12e31461050e5761028a565b80633af9e6" + + "69146104475780633b1d21a21461046d5780634576b5db1461047557806347bd37181461" + + "049b5780635fe3b567146104a3578063601a0bf1146104ab5761028a565b806318160ddd" + + "1161025257806318160ddd146103a9578063182df0f5146103b157806323b872dd146103" + + "b95780632608f818146103ef578063267822471461041b578063313ce5671461043f5761" + + "028a565b806306fdde031461028f578063095ea7b31461030c5780630e7527021461034c" + + "578063173b99041461037b57806317bfdfbc14610383575b600080fd5b61029761077b56" + + "5b6040805160208082528351818301528351919283929083019185019080838360005b83" + + "8110156102d15781810151838201526020016102b9565b50505050905090810190601f16" + + "80156102fe5780820380516001836020036101000a031916815260200191505b50925050" + + "5060405180910390f35b6103386004803603604081101561032257600080fd5b50600160" + + "0160a01b038135169060200135610808565b604080519115158252519081900360200190" + + "f35b6103696004803603602081101561036257600080fd5b5035610875565b6040805191" + + "8252519081900360200190f35b610369610888565b610369600480360360208110156103" + + "9957600080fd5b50356001600160a01b031661088e565b610369610951565b6103696109" + + "57565b610338600480360360608110156103cf57600080fd5b506001600160a01b038135" + + "811691602081013590911690604001356109bd565b610369600480360360408110156104" + + "0557600080fd5b506001600160a01b038135169060200135610a29565b610423610a3c56" + + "5b604080516001600160a01b039092168252519081900360200190f35b610369610a4b56" + + "5b6103696004803603602081101561045d57600080fd5b50356001600160a01b0316610a" + + "51565b610369610abf565b6103696004803603602081101561048b57600080fd5b503560" + + "01600160a01b0316610ace565b610369610c23565b610423610c29565b61036960048036" + + "0360208110156104c157600080fd5b5035610c38565b610369610cc6565b610369610ccc" + + "565b610423610cd2565b610369600480360360208110156104f657600080fd5b50356001" + + "600160a01b0316610ce1565b610369610cfc565b61036960048036036020811015610524" + + "57600080fd5b5035610db6565b610369610dc1565b610297610dc7565b61036960048036" + + "03602081101561055157600080fd5b50356001600160a01b0316610e1f565b6103696004" + + "803603602081101561057757600080fd5b5035610e7f565b610369610e8a565b61033860" + + "04803603604081101561059c57600080fd5b506001600160a01b03813516906020013561" + + "1286565b6103696112f1565b6103696112f7565b610369600480360360608110156105d8" + + "57600080fd5b506001600160a01b038135811691602081013590911690604001356115d1" + + "565b6103696004803603602081101561060e57600080fd5b50356001600160a01b031661" + + "188e565b610369611915565b61064c6004803603602081101561063c57600080fd5b5035" + + "6001600160a01b03166119d0565b60408051948552602085019390935283830191909152" + + "6060830152519081900360800190f35b6103696004803603602081101561068857600080" + + "fd5b5035611a65565b610369600480360360208110156106a557600080fd5b5035611a70" + + "565b610369600480360360408110156106c257600080fd5b506001600160a01b03813581" + + "16916020013516611a7b565b610369611aa6565b610369600480360360208110156106f8" + + "57600080fd5b50356001600160a01b0316611b95565b610423611bcf565b610369600480" + + "3603606081101561072657600080fd5b506001600160a01b038135811691602081013591" + + "60409091013516611bde565b610423611beb565b610369611bfa565b6103696004803603" + + "602081101561076c57600080fd5b5035611cd9565b610338611d13565b60018054604080" + + "516020600284861615610100026000190190941693909304601f81018490048402820184" + + "0190925281815292918301828280156108005780601f106107d557610100808354040283" + + "529160200191610800565b820191906000526020600020905b8154815290600101906020" + + "018083116107e357829003601f168201915b505050505081565b33600081815260106020" + + "90815260408083206001600160a01b038716808552908352818420869055815186815291" + + "51939493909284927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200a" + + "c8c7c3b925929081900390910190a360019150505b92915050565b600061088082611d18" + + "565b90505b919050565b60095481565b60008054600101808255816108a1610e8a565b14" + + "6108f65760408051600160e51b62461bcd02815260206004820152601660248201527f61" + + "636372756520696e746572657374206661696c6564000000000000000000006044820152" + + "90519081900360640190fd5b6108ff83610e1f565b91505b600054811461094b57604080" + + "51600160e51b62461bcd02815260206004820152600a6024820152600160b21b691c994b" + + "595b9d195c995902604482015290519081900360640190fd5b50919050565b600e548156" + + "5b6000806000610964611d54565b9092509050600082600381111561097757fe5b146109" + + "b657604051600160e51b62461bcd02815260040180806020018281038252603581526020" + + "01806149626035913960400191505060405180910390fd5b9150505b90565b6000805460" + + "0101808255816109d433878787611e02565b1491505b6000548114610a21576040805160" + + "0160e51b62461bcd02815260206004820152600a6024820152600160b21b691c994b595b" + + "9d195c995902604482015290519081900360640190fd5b509392505050565b6000610a35" + + "8383612116565b9392505050565b6005546001600160a01b031681565b60035481565b60" + + "00610a5b6146bb565b6040518060200160405280610a6e611915565b90526001600160a0" + + "1b0384166000908152600f6020526040812054919250908190610a9a9084906121a6565b" + + "90925090506000826003811115610aad57fe5b14610ab757600080fd5b94935050505056" + + "5b6000610ac96121fa565b905090565b6004546000906001600160a01b03163314610af6" + + "57610aef6001603f61227d565b9050610883565b60065460408051600160e11b623f1ee9" + + "02815290516001600160a01b0392831692851691627e3dd2916004808301926020929190" + + "829003018186803b158015610b3e57600080fd5b505afa158015610b52573d6000803e3d" + + "6000fd5b505050506040513d6020811015610b6857600080fd5b5051610bbe5760408051" + + "600160e51b62461bcd02815260206004820152601c60248201527f6d61726b6572206d65" + + "74686f642072657475726e65642066616c73650000000060448201529051908190036064" + + "0190fd5b600680546001600160a01b0319166001600160a01b0385811691821790925560" + + "4080519284168352602083019190915280517f7ac369dbd14fa5ea3f473ed67cc9d59896" + + "4a77501540ba6751eb0b3decf5870d9281900390910190a160009392505050565b600c54" + + "81565b6006546001600160a01b031681565b6000805460010180825581610c4b610e8a56" + + "5b90508015610c7157610c69816010811115610c6257fe5b603061227d565b9250506109" + + "02565b610c7a846122e3565b925050600054811461094b5760408051600160e51b62461b" + + "cd02815260206004820152600a6024820152600160b21b691c994b595b9d195c99590260" + + "4482015290519081900360640190fd5b60085481565b600a5481565b6012546001600160" + + "a01b031681565b6001600160a01b03166000908152600f602052604090205490565b6000" + + "805460010180825581610d0f610e8a565b14610d645760408051600160e51b62461bcd02" + + "815260206004820152601660248201527f61636372756520696e74657265737420666169" + + "6c656400000000000000000000604482015290519081900360640190fd5b600c54915060" + + "00548114610db25760408051600160e51b62461bcd02815260206004820152600a602482" + + "0152600160b21b691c994b595b9d195c995902604482015290519081900360640190fd5b" + + "5090565b600061088082612467565b600d5481565b600280546040805160206001841615" + + "6101000260001901909316849004601f8101849004840282018401909252818152929183" + + "01828280156108005780601f106107d55761010080835404028352916020019161080056" + + "5b6000806000610e2d846124a4565b90925090506000826003811115610e4057fe5b1461" + + "0a3557604051600160e51b62461bcd028152600401808060200182810382526037815260" + + "2001806148366037913960400191505060405180910390fd5b600061088082612558565b" + + "6000610e946146ce565b6007546001600160a01b03166315f24053610ead6121fa565b60" + + "0c54600d546040518463ffffffff1660e01b815260040180848152602001838152602001" + + "8281526020019350505050604080518083038186803b158015610ef457600080fd5b505a" + + "fa158015610f08573d6000803e3d6000fd5b505050506040513d6040811015610f1e5760" + + "0080fd5b50805160209182015160408401819052918301526601c6bf526340001015610f" + + "905760408051600160e51b62461bcd02815260206004820152601c60248201527f626f72" + + "726f772072617465206973206162737572646c7920686967680000000060448201529051" + + "9081900360640190fd5b602081015115610fb357610fab60056002836020015161259356" + + "5b9150506109ba565b610fbb6125f9565b60608201819052600a54610fcf91906125fd56" + + "5b6080830181905282826003811115610fe357fe5b6003811115610fee57fe5b90525060" + + "0090508151600381111561100257fe5b1461100957fe5b61102960405180602001604052" + + "8083604001518152508260800151612620565b60a083018190528282600381111561103d" + + "57fe5b600381111561104857fe5b905250600090508151600381111561105c57fe5b1461" + + "107d57610fab600960068360000151600381111561107857fe5b612593565b61108d8160" + + "a00151600c546121a6565b60c08301819052828260038111156110a157fe5b6003811115" + + "6110ac57fe5b90525060009050815160038111156110c057fe5b146110dc57610fab6009" + + "60018360000151600381111561107857fe5b6110ec8160c00151600c54612688565b60e0" + + "83018190528282600381111561110057fe5b600381111561110b57fe5b90525060009050" + + "8151600381111561111f57fe5b1461113b57610fab600960048360000151600381111561" + + "107857fe5b61115c60405180602001604052806009548152508260c00151600d546126ae" + + "565b61010083018190528282600381111561117157fe5b600381111561117c57fe5b9052" + + "50600090508151600381111561119057fe5b146111ac57610fab60096005836000015160" + + "0381111561107857fe5b6111bf8160a00151600b54600b546126ae565b61012083018190" + + "52828260038111156111d457fe5b60038111156111df57fe5b9052506000905081516003" + + "8111156111f357fe5b1461120f57610fab600960038360000151600381111561107857fe" + + "5b606080820151600a55610120820151600b81905560e0830151600c8190556101008401" + + "51600d5560c08401516040805191825260208201939093528083019190915290517f8753" + + "52fb3fadeb8c0be7cbbe8ff761b308fa7033470cd0287f02f3436fd76cb9929181900390" + + "910190a1600091505090565b600080546001018082558161129d33338787611e02565b14" + + "91505b60005481146112ea5760408051600160e51b62461bcd0281526020600482015260" + + "0a6024820152600160b21b691c994b595b9d195c99590260448201529051908190036064" + + "0190fd5b5092915050565b600b5481565b600080611302610957565b6007549091506000" + + "9081906001600160a01b03166315f240536113236121fa565b600c54600d546040518463" + + "ffffffff1660e01b81526004018084815260200183815260200182815260200193505050" + + "50604080518083038186803b15801561136a57600080fd5b505afa15801561137e573d60" + + "00803e3d6000fd5b505050506040513d604081101561139457600080fd5b508051602090" + + "910151909250905081156113e257604051600160e51b62461bcd02815260040180806020" + + "01828103825260318152602001806148d56031913960400191505060405180910390fd5b" + + "60006113ec6146bb565b611406604051806020016040528087815250600e54612620565b" + + "9092509050600082600381111561141957fe5b1461145857604051600160e51b62461bcd" + + "02815260040180806020018281038252603181526020018061486d603191396040019150" + + "5060405180910390fd5b60006114626146bb565b61146e600c548461270a565b90925090" + + "50600082600381111561148157fe5b146114c057604051600160e51b62461bcd02815260" + + "04018080602001828103825260318152602001806147b160319139604001915050604051" + + "80910390fd5b60006114ca6146bb565b6114fa6040518060200160405280670de0b6b3a7" + + "6400008152506040518060200160405280600954815250612769565b9092509050600082" + + "600381111561150d57fe5b1461154c57604051600160e51b62461bcd0281526004018080" + + "6020018281038252603c815260200180614926603c913960400191505060405180910390" + + "fd5b60006115566146bb565b61156f60405180602001604052808b81525084876127a356" + + "5b9092509050600082600381111561158257fe5b146115c157604051600160e51b62461b" + + "cd0281526004018080602001828103825260318152602001806148056031913960400191" + + "505060405180910390fd5b519a505050505050505050505090565b600080546001018082" + + "5560065460408051600160e01b63d02f7351028152306004820152336024820152600160" + + "0160a01b0388811660448301528781166064830152608482018790529151859392909216" + + "9163d02f73519160a48082019260209290919082900301818787803b15801561164a5760" + + "0080fd5b505af115801561165e573d6000803e3d6000fd5b505050506040513d60208110" + + "1561167457600080fd5b5051905080156116935761168b6003601b83612593565b925050" + + "6109d8565b856001600160a01b0316856001600160a01b031614156116b95761168b6006" + + "601c61227d565b6001600160a01b0385166000908152600f602052604081205481908190" + + "6116e090886125fd565b909350915060008360038111156116f357fe5b14611716576117" + + "0b6009601a85600381111561107857fe5b9550505050506109d8565b6001600160a01b03" + + "89166000908152600f60205260409020546117399088612688565b909350905060008360" + + "0381111561174c57fe5b146117645761170b6009601985600381111561107857fe5b6001" + + "600160a01b038089166000818152600f60209081526040808320879055938d1680835291" + + "84902085905583518b815293519193600080516020614906833981519152929081900390" + + "910190a360065460408051600160e01b636d35bf91028152306004820152336024820152" + + "6001600160a01b038c811660448301528b81166064830152608482018b90529151919092" + + "1691636d35bf919160a480830192600092919082900301818387803b15801561181e5760" + + "0080fd5b505af1158015611832573d6000803e3d6000fd5b506000925061183f91505056" + + "5b9550505050506000548114610a215760408051600160e51b62461bcd02815260206004" + + "820152600a6024820152600160b21b691c994b595b9d195c995902604482015290519081" + + "900360640190fd5b6004546000906001600160a01b031633146118af57610aef60016045" + + "61227d565b600580546001600160a01b038481166001600160a01b031983168117909355" + + "6040805191909216808252602082019390935281517fca4f2f25d0898edd99413412fb94" + + "012f9e54ec8142f9b093e7720646a95b16a9929181900390910190a16000610a35565b60" + + "00805460010180825581611928610e8a565b1461197d5760408051600160e51b62461bcd" + + "02815260206004820152601660248201527f61636372756520696e746572657374206661" + + "696c656400000000000000000000604482015290519081900360640190fd5b6119856109" + + "57565b91506000548114610db25760408051600160e51b62461bcd028152602060048201" + + "52600a6024820152600160b21b691c994b595b9d195c9959026044820152905190819003" + + "60640190fd5b6001600160a01b0381166000908152600f60205260408120548190819081" + + "908180806119fb896124a4565b935090506000816003811115611a0d57fe5b14611a2b57" + + "60095b975060009650869550859450611a5e9350505050565b611a33611d54565b925090" + + "506000816003811115611a4557fe5b14611a51576009611a15565b506000965091945092" + + "5090505b9193509193565b6000610880826127ed565b600061088082612828565b600160" + + "0160a01b0391821660009081526010602090815260408083209390941682529190915220" + + "5490565b6005546000906001600160a01b031633141580611ac1575033155b15611ad957" + + "611ad26001600061227d565b90506109ba565b60048054600580546001600160a01b0380" + + "82166001600160a01b031980861682179687905590921690925560408051938316808552" + + "949092166020840152815190927ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f" + + "21c4e8146d8519b417dc92908290030190a1600554604080516001600160a01b03808516" + + "8252909216602083015280517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b0" + + "93e7720646a95b16a99281900390910190a160009250505090565b600080611ba0610e8a" + + "565b90508015611bc657611bbe816010811115611bb757fe5b604061227d565b91505061" + + "0883565b610a358361285e565b6007546001600160a01b031681565b6000610ab7848484" + + "6129d1565b6004546001600160a01b031681565b600754600090819081906001600160a0" + + "1b03166315f24053611c1a6121fa565b600c54600d546040518463ffffffff1660e01b81" + + "526004018084815260200183815260200182815260200193505050506040805180830381" + + "86803b158015611c6157600080fd5b505afa158015611c75573d6000803e3d6000fd5b50" + + "5050506040513d6040811015611c8b57600080fd5b508051602090910151909250905081" + + "156109b657604051600160e51b62461bcd02815260040180806020018281038252603781" + + "526020018061489e6037913960400191505060405180910390fd5b600080546001018082" + + "5581611cec610e8a565b90508015611d0a57610c69816010811115611d0357fe5b604661" + + "227d565b610c7a84612adf565b600181565b6000805460010180825581611d2b610e8a56" + + "5b90508015611d4957610c69816010811115611d4257fe5b603661227d565b610c7a3333" + + "86612b82565b600080600e5460001415611d6f575050600854600090611dfe565b600061" + + "1d796121fa565b90506000611d856146bb565b6000611d9684600c54600d54612fde565b" + + "935090506000816003811115611da857fe5b14611dbc57945060009350611dfe92505050" + + "565b611dc883600e5461301c565b925090506000816003811115611dda57fe5b14611dee" + + "57945060009350611dfe92505050565b5051600094509250611dfe915050565b9091565b" + + "60065460408051600160e31b6317b9b84b0281523060048201526001600160a01b038681" + + "16602483015285811660448301526064820185905291516000938493169163bdcdc25891" + + "608480830192602092919082900301818787803b158015611e6a57600080fd5b505af115" + + "8015611e7e573d6000803e3d6000fd5b505050506040513d6020811015611e9457600080" + + "fd5b505190508015611eb357611eab6003604a83612593565b915050610ab7565b836001" + + "600160a01b0316856001600160a01b03161415611ed957611eab6002604b61227d565b60" + + "006001600160a01b038781169087161415611ef85750600019611f20565b506001600160" + + "a01b038086166000908152601060209081526040808320938a16835292905220545b6000" + + "80600080611f3085896125fd565b90945092506000846003811115611f4357fe5b14611f" + + "6157611f546009604b61227d565b9650505050505050610ab7565b6001600160a01b038a" + + "166000908152600f6020526040902054611f8490896125fd565b90945091506000846003" + + "811115611f9757fe5b14611fa857611f546009604c61227d565b6001600160a01b038916" + + "6000908152600f6020526040902054611fcb9089612688565b9094509050600084600381" + + "1115611fde57fe5b14611fef57611f546009604d61227d565b6001600160a01b03808b16" + + "6000908152600f6020526040808220859055918b16815220819055600019851461204757" + + "6001600160a01b03808b166000908152601060209081526040808320938f168352929052" + + "208390555b886001600160a01b03168a6001600160a01b03166000805160206149068339" + + "815191528a6040518082815260200191505060405180910390a360065460408051600160" + + "e11b63352b4a3f0281523060048201526001600160a01b038d811660248301528c811660" + + "44830152606482018c905291519190921691636a56947e91608480830192600092919082" + + "900301818387803b1580156120e657600080fd5b505af11580156120fa573d6000803e3d" + + "6000fd5b5060009250612107915050565b9b9a5050505050505050505050565b60008054" + + "60010180825581612129610e8a565b9050801561214f5761214781601081111561214057" + + "fe5b603561227d565b9250506112a1565b61215a338686612b82565b9250506000548114" + + "6112ea5760408051600160e51b62461bcd02815260206004820152600a60248201526001" + + "60b21b691c994b595b9d195c995902604482015290519081900360640190fd5b60008060" + + "006121b36146bb565b6121bd8686612620565b909250905060008260038111156121d057" + + "fe5b146121e157509150600090506121f3565b60006121ec826130cc565b935093505050" + + "5b9250929050565b60125460408051600160e01b6370a082310281523060048201529051" + + "6000926001600160a01b03169182916370a0823191602480820192602092909190829003" + + "018186803b15801561224b57600080fd5b505afa15801561225f573d6000803e3d6000fd" + + "5b505050506040513d602081101561227557600080fd5b505191505090565b60007f45b9" + + "6fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0836010811115" + + "6122ac57fe5b83604d8111156122b857fe5b604080519283526020830191909152600082" + + "820152519081900360600190a1826010811115610a3557fe5b6004546000908190819060" + + "01600160a01b03163314612311576123086001603161227d565b92505050610883565b61" + + "23196125f9565b600a541461232d57612308600a603361227d565b836123366121fa565b" + + "101561234857612308600e603261227d565b600d5484111561235e576123086002603461" + + "227d565b50600d54838103908111156123a757604051600160e51b62461bcd0281526004" + + "018080602001828103825260248152602001806149cb6024913960400191505060405180" + + "910390fd5b600d8190556004546123c2906001600160a01b0316856130db565b91506000" + + "8260108111156123d257fe5b1461241157604051600160e51b62461bcd02815260040180" + + "80602001828103825260238152602001806147e260239139604001915050604051809103" + + "90fd5b600454604080516001600160a01b03909216825260208201869052818101839052" + + "517f3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e9181" + + "900360600190a16000949350505050565b600080546001018082558161247a610e8a565b" + + "9050801561249857610c6981601081111561249157fe5b602761227d565b610c7a336000" + + "8661319a565b6001600160a01b0381166000908152601160205260408120805482918291" + + "829182916124db57506000945084935061255392505050565b6124eb8160000154600b54" + + "6136af565b909450925060008460038111156124fe57fe5b146125135750919350600092" + + "50612553915050565b6125218382600101546136ee565b90945091506000846003811115" + + "61253457fe5b14612549575091935060009250612553915050565b506000945092505050" + + "5b915091565b600080546001018082558161256b610e8a565b9050801561258957610c69" + + "81601081111561258257fe5b601e61227d565b610c7a3385613719565b60007f45b96fe4" + + "42630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08460108111156125" + + "c257fe5b84604d8111156125ce57fe5b6040805192835260208301919091528181018590" + + "52519081900360600190a1836010811115610ab757fe5b4390565b600080838311612614" + + "5750600090508183036121f3565b506003905060006121f3565b600061262a6146bb565b" + + "60008061263b8660000151866136af565b9092509050600082600381111561264e57fe5b" + + "1461266d575060408051602081019091526000815290925090506121f3565b6040805160" + + "2081019091529081526000969095509350505050565b6000808383018481106126a05760" + + "00925090506121f3565b5060029150600090506121f3565b60008060006126bb6146bb56" + + "5b6126c58787612620565b909250905060008260038111156126d857fe5b146126e95750" + + "915060009050612702565b6126fb6126f5826130cc565b86612688565b9350935050505b" + + "935093915050565b60006127146146bb565b600080612729670de0b6b3a7640000876136" + + "af565b9092509050600082600381111561273c57fe5b1461275b57506040805160208101" + + "9091526000815290925090506121f3565b6121ec81866000015161301c565b6000612773" + + "6146bb565b600080612788866000015186600001516125fd565b60408051602081019091" + + "529081529097909650945050505050565b60006127ad6146bb565b60006127b76146bb56" + + "5b6127c18787613b67565b909250905060008260038111156127d457fe5b146127e35790" + + "92509050612702565b6126fb8186613b67565b6000805460010180825581612800610e8a" + + "565b9050801561281e57610c6981601081111561281757fe5b600861227d565b610c7a33" + + "85613c50565b600080546001018082558161283b610e8a565b9050801561285257610c69" + + "81601081111561249157fe5b610c7a3385600061319a565b600454600090819060016001" + + "60a01b0316331461288157611bbe6001604261227d565b6128896125f9565b600a541461" + + "289d57611bbe600a604161227d565b600760009054906101000a90046001600160a01b03" + + "169050826001600160a01b0316632191f92a6040518163ffffffff1660e01b8152600401" + + "60206040518083038186803b1580156128ee57600080fd5b505afa158015612902573d60" + + "00803e3d6000fd5b505050506040513d602081101561291857600080fd5b505161296e57" + + "60408051600160e51b62461bcd02815260206004820152601c60248201527f6d61726b65" + + "72206d6574686f642072657475726e65642066616c736500000000604482015290519081" + + "900360640190fd5b600780546001600160a01b0319166001600160a01b03858116918217" + + "909255604080519284168352602083019190915280517fedffc32e068c7c95dfd4bdfd5c" + + "4d939a084d6b11c4199eac8436ed234d72f9269281900390910190a16000610a35565b60" + + "008054600101808255816129e4610e8a565b90508015612a025761168b81601081111561" + + "29fb57fe5b600f61227d565b836001600160a01b031663a6afed956040518163ffffffff" + + "1660e01b8152600401602060405180830381600087803b158015612a3d57600080fd5b50" + + "5af1158015612a51573d6000803e3d6000fd5b505050506040513d6020811015612a6757" + + "600080fd5b505190508015612a875761168b816010811115612a8057fe5b601061227d56" + + "5b612a9333878787613fbf565b9250506000548114610a215760408051600160e51b6246" + + "1bcd02815260206004820152600a6024820152600160b21b691c994b595b9d195c995902" + + "604482015290519081900360640190fd5b6004546000906001600160a01b03163314612b" + + "0057610aef6001604761227d565b612b086125f9565b600a5414612b1c57610aef600a60" + + "4861227d565b670de0b6b3a7640000821115612b3857610aef6002604961227d565b6009" + + "805490839055604080518281526020810185905281517faaa68312e2ea9d50e16af50684" + + "10ab56e1a1fd06037b1a35664812c30f821460929181900390910190a16000610a35565b" + + "60065460408051600160e11b63120045310281523060048201526001600160a01b038681" + + "1660248301528581166044830152606482018590529151600093849316916324008a6291" + + "608480830192602092919082900301818787803b158015612bea57600080fd5b505af115" + + "8015612bfe573d6000803e3d6000fd5b505050506040513d6020811015612c1457600080" + + "fd5b505190508015612c3357612c2b6003603883612593565b915050610a35565b612c3b" + + "6125f9565b600a5414612c4f57612c2b600a603961227d565b612c57614728565b600160" + + "0160a01b0385166000908152601160205260409020600101546060820152612c81856124" + + "a4565b6080830181905260208301826003811115612c9857fe5b6003811115612ca357fe" + + "5b9052506000905081602001516003811115612cba57fe5b14612cdf57612cd660096037" + + "8360200151600381111561107857fe5b92505050610a35565b600019841415612cf85760" + + "808101516040820152612d00565b604081018490525b612d0e8682604001516144b3565b" + + "81906010811115612d1b57fe5b90816010811115612d2857fe5b90525060008151601081" + + "1115612d3a57fe5b14612d4c578051612cd690603c61227d565b612d5e81608001518260" + + "4001516125fd565b60a0830181905260208301826003811115612d7557fe5b6003811115" + + "612d8057fe5b9052506000905081602001516003811115612d9757fe5b14612db357612c" + + "d66009603a8360200151600381111561107857fe5b612dc3600c5482604001516125fd56" + + "5b60c0830181905260208301826003811115612dda57fe5b6003811115612de557fe5b90" + + "52506000905081602001516003811115612dfc57fe5b14612e1857612cd66009603b8360" + + "200151600381111561107857fe5b612e268682604001516145ea565b8190601081111561" + + "2e3357fe5b90816010811115612e4057fe5b905250600081516010811115612e5257fe5b" + + "14612ea75760408051600160e51b62461bcd02815260206004820152601f60248201527f" + + "726570617920626f72726f77207472616e7366657220696e206661696c65640060448201" + + "5290519081900360640190fd5b60a080820180516001600160a01b038089166000818152" + + "60116020908152604091829020948555600b5460019095019490945560c0870151600c81" + + "90558188015195518251948e168552948401929092528281019490945260608201929092" + + "52608081019190915290517f1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0" + + "355478d6f5c362a1929181900390910190a1600654604080830151606084015182516001" + + "60e01b631ededc910281523060048201526001600160a01b038b811660248301528a8116" + + "6044830152606482019390935260848101919091529151921691631ededc919160a48082" + + "019260009290919082900301818387803b158015612fb357600080fd5b505af115801561" + + "2fc7573d6000803e3d6000fd5b5060009250612fd4915050565b9695505050505050565b" + + "600080600080612fee8787612688565b9092509050600082600381111561300157fe5b14" + + "6130125750915060009050612702565b6126fb81866125fd565b60006130266146bb565b" + + "60008061303b86670de0b6b3a76400006136af565b909250905060008260038111156130" + + "4e57fe5b1461306d575060408051602081019091526000815290925090506121f3565b60" + + "008061307a83886136ee565b9092509050600082600381111561308d57fe5b146130af57" + + "5060408051602081019091526000815290945092506121f3915050565b60408051602081" + + "0190915290815260009890975095505050505050565b51670de0b6b3a764000090049056" + + "5b60125460408051600160e01b63a9059cbb0281526001600160a01b0385811660048301" + + "5260248201859052915160009392909216918391839163a9059cbb916044808201928692" + + "90919082900301818387803b15801561313a57600080fd5b505af115801561314e573d60" + + "00803e3d6000fd5b505050503d60008114613168576020811461317257600080fd5b6000" + + "19915061317e565b60206000803e60005191505b508061318f5760109250505061086f56" + + "5b506000949350505050565b60008215806131a7575081155b6131e557604051600160e5" + + "1b62461bcd02815260040180806020018281038252603481526020018061499760349139" + + "60400191505060405180910390fd5b6131ed614728565b6131f5611d54565b6040830181" + + "90526020830182600381111561320c57fe5b600381111561321757fe5b90525060009050" + + "8160200151600381111561322e57fe5b1461324a57612c2b6009602b8360200151600381" + + "111561107857fe5b83156132cb5760608101849052604080516020810182529082015181" + + "5261327190856121a6565b608083018190526020830182600381111561328857fe5b6003" + + "81111561329357fe5b90525060009050816020015160038111156132aa57fe5b146132c6" + + "57612c2b600960298360200151600381111561107857fe5b613344565b6132e783604051" + + "806020016040528084604001518152506146a4565b606083018190526020830182600381" + + "11156132fe57fe5b600381111561330957fe5b9052506000905081602001516003811115" + + "61332057fe5b1461333c57612c2b6009602a8360200151600381111561107857fe5b6080" + + "81018390525b600654606082015160408051600160e01b63eabe7d910281523060048201" + + "526001600160a01b03898116602483015260448201939093529051600093929092169163" + + "eabe7d919160648082019260209290919082900301818787803b1580156133ac57600080" + + "fd5b505af11580156133c0573d6000803e3d6000fd5b505050506040513d602081101561" + + "33d657600080fd5b5051905080156133ed57612cd66003602883612593565b6133f56125" + + "f9565b600a541461340957612cd6600a602c61227d565b613419600e5483606001516125" + + "fd565b60a084018190526020840182600381111561343057fe5b600381111561343b57fe" + + "5b905250600090508260200151600381111561345257fe5b1461346e57612cd66009602e" + + "8460200151600381111561107857fe5b6001600160a01b0386166000908152600f602052" + + "6040902054606083015161349691906125fd565b60c08401819052602084018260038111" + + "156134ad57fe5b60038111156134b857fe5b905250600090508260200151600381111561" + + "34cf57fe5b146134eb57612cd66009602d8460200151600381111561107857fe5b816080" + + "01516134f86121fa565b101561350a57612cd6600e602f61227d565b6135188683608001" + + "516130db565b8290601081111561352557fe5b9081601081111561353257fe5b90525060" + + "008251601081111561354457fe5b146135995760408051600160e51b62461bcd02815260" + + "206004820152601a60248201527f72656465656d207472616e73666572206f7574206661" + + "696c6564000000000000604482015290519081900360640190fd5b60a0820151600e5560" + + "c08201516001600160a01b0387166000818152600f602090815260409182902093909355" + + "6060850151815190815290513093600080516020614906833981519152928290030190a3" + + "6080820151606080840151604080516001600160a01b038b168152602081019490945283" + + "810191909152517fe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4" + + "ec31a9299281900390910190a16006546080830151606084015160408051600160e01b63" + + "51dff9890281523060048201526001600160a01b038b8116602483015260448201949094" + + "5260648101929092525191909216916351dff98991608480830192600092919082900301" + + "818387803b158015612fb357600080fd5b600080836136c2575060009050806121f3565b" + + "838302838582816136cf57fe5b04146136e3575060029150600090506121f3565b600092" + + "5090506121f3565b6000808261370257506001905060006121f3565b600083858161370d" + + "57fe5b04915091509250929050565b60065460408051600160e01b634ef4c3e102815230" + + "60048201526001600160a01b038581166024830152604482018590529151600093849316" + + "91634ef4c3e191606480830192602092919082900301818787803b158015613779576000" + + "80fd5b505af115801561378d573d6000803e3d6000fd5b505050506040513d6020811015" + + "6137a357600080fd5b5051905080156137c2576137ba6003601f83612593565b91505061" + + "086f565b6137ca6125f9565b600a54146137de576137ba600a602261227d565b6137e661" + + "4766565b6137f085856144b3565b819060108111156137fd57fe5b908160108111156138" + + "0a57fe5b90525060008151601081111561381c57fe5b1461383757805161382e90602661" + + "227d565b9250505061086f565b61383f611d54565b604083018190526020830182600381" + + "111561385657fe5b600381111561386157fe5b9052506000905081602001516003811115" + + "61387857fe5b146138945761382e600960218360200151600381111561107857fe5b6138" + + "b084604051806020016040528084604001518152506146a4565b60608301819052602083" + + "018260038111156138c757fe5b60038111156138d257fe5b905250600090508160200151" + + "60038111156138e957fe5b146139055761382e6009602083602001516003811115611078" + + "57fe5b613915600e548260600151612688565b6080830181905260208301826003811115" + + "61392c57fe5b600381111561393757fe5b90525060009050816020015160038111156139" + + "4e57fe5b1461396a5761382e600960248360200151600381111561107857fe5b60016001" + + "60a01b0385166000908152600f602052604090205460608201516139929190612688565b" + + "60a08301819052602083018260038111156139a957fe5b60038111156139b457fe5b9052" + + "5060009050816020015160038111156139cb57fe5b146139e75761382e60096023836020" + + "0151600381111561107857fe5b6139f185856145ea565b819060108111156139fe57fe5b" + + "90816010811115613a0b57fe5b905250600081516010811115613a1d57fe5b14613a2f57" + + "805161382e90602561227d565b6080810151600e5560a08101516001600160a01b038616" + + "6000818152600f6020908152604091829020939093556060808501518251938452938301" + + "88905282820193909352517f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef" + + "26394f4c03821c4f929181900390910190a1606081015160408051918252516001600160" + + "a01b0387169130916000805160206149068339815191529181900360200190a360065460" + + "6082015160408051600160e01b6341c728b90281523060048201526001600160a01b0389" + + "81166024830152604482018990526064820193909352905191909216916341c728b99160" + + "8480830192600092919082900301818387803b158015613b3d57600080fd5b505af11580" + + "15613b51573d6000803e3d6000fd5b5060009250613b5e915050565b9594505050505056" + + "5b6000613b716146bb565b600080613b86866000015186600001516136af565b90925090" + + "506000826003811115613b9957fe5b14613bb85750604080516020810190915260008152" + + "90925090506121f3565b600080613bcd6706f05b59d3b2000084612688565b9092509050" + + "6000826003811115613be057fe5b14613c02575060408051602081019091526000815290" + + "945092506121f3915050565b600080613c1783670de0b6b3a76400006136ee565b909250" + + "90506000826003811115613c2a57fe5b14613c3157fe5b60408051602081019091529081" + + "5260009a909950975050505050505050565b60065460408051600160e21b63368f515302" + + "81523060048201526001600160a01b038581166024830152604482018590529151600093" + + "8493169163da3d454c91606480830192602092919082900301818787803b158015613cb0" + + "57600080fd5b505af1158015613cc4573d6000803e3d6000fd5b505050506040513d6020" + + "811015613cda57600080fd5b505190508015613cf1576137ba6003600e83612593565b61" + + "3cf96125f9565b600a5414613d0c576137ba600a8061227d565b82613d156121fa565b10" + + "15613d27576137ba600e600961227d565b613d2f614780565b613d38856124a4565b6040" + + "830181905260208301826003811115613d4f57fe5b6003811115613d5a57fe5b90525060" + + "00905081602001516003811115613d7157fe5b14613d8d5761382e600960078360200151" + + "600381111561107857fe5b613d9b816040015185612688565b6060830181905260208301" + + "826003811115613db257fe5b6003811115613dbd57fe5b90525060009050816020015160" + + "03811115613dd457fe5b14613df05761382e6009600c8360200151600381111561107857" + + "fe5b613dfc600c5485612688565b6080830181905260208301826003811115613e1357fe" + + "5b6003811115613e1e57fe5b9052506000905081602001516003811115613e3557fe5b14" + + "613e515761382e6009600b8360200151600381111561107857fe5b613e5b85856130db56" + + "5b81906010811115613e6857fe5b90816010811115613e7557fe5b905250600081516010" + + "811115613e8757fe5b14613edc5760408051600160e51b62461bcd028152602060048201" + + "52601a60248201527f626f72726f77207472616e73666572206f7574206661696c656400" + + "0000000000604482015290519081900360640190fd5b606080820180516001600160a01b" + + "038816600081815260116020908152604091829020938455600b54600190940193909355" + + "608080870151600c819055945182519384529383018a9052828201939093529381019290" + + "925291517f13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab" + + "80929181900390910190a160065460408051600160e01b635c7786050281523060048201" + + "526001600160a01b0388811660248301526044820188905291519190921691635c778605" + + "91606480830192600092919082900301818387803b158015613b3d57600080fd5b600654" + + "60408051600160e11b632fe3f38f0281523060048201526001600160a01b038481166024" + + "830152878116604483015286811660648301526084820186905291516000938493169163" + + "5fc7e71e9160a480830192602092919082900301818787803b15801561402f57600080fd" + + "5b505af1158015614043573d6000803e3d6000fd5b505050506040513d60208110156140" + + "5957600080fd5b50519050801561407057611eab6003601283612593565b6140786125f9" + + "565b600a541461408c57611eab600a601661227d565b6140946125f9565b836001600160" + + "a01b0316636c540baf6040518163ffffffff1660e01b8152600401602060405180830381" + + "86803b1580156140cd57600080fd5b505afa1580156140e1573d6000803e3d6000fd5b50" + + "5050506040513d60208110156140f757600080fd5b50511461410a57611eab600a601161" + + "227d565b856001600160a01b0316856001600160a01b0316141561413057611eab600660" + + "1761227d565b8361414157611eab6007601561227d565b60001984141561415757611eab" + + "6007601461227d565b60065460408051600160e01b63c488847b02815230600482015260" + + "01600160a01b038681166024830152604482018890528251600094859492169263c48884" + + "7b926064808301939192829003018186803b1580156141b457600080fd5b505afa158015" + + "6141c8573d6000803e3d6000fd5b505050506040513d60408110156141de57600080fd5b" + + "50805160209091015190925090508115614209576141ff6004601384612593565b935050" + + "5050610ab7565b846001600160a01b03166370a08231886040518263ffffffff1660e01b" + + "815260040180826001600160a01b03166001600160a01b03168152602001915050602060" + + "40518083038186803b15801561425f57600080fd5b505afa158015614273573d6000803e" + + "3d6000fd5b505050506040513d602081101561428957600080fd5b505181111561429e57" + + "6141ff600d601d61227d565b60006142ab898989612b82565b905080156142d4576142c9" + + "8160108111156142c257fe5b601861227d565b945050505050610ab7565b604080516001" + + "60e01b63b2a02ff10281526001600160a01b038b811660048301528a8116602483015260" + + "448201859052915160009289169163b2a02ff19160648083019260209291908290030181" + + "8787803b15801561433257600080fd5b505af1158015614346573d6000803e3d6000fd5b" + + "505050506040513d602081101561435c57600080fd5b5051905080156143b65760408051" + + "600160e51b62461bcd02815260206004820152601460248201527f746f6b656e20736569" + + "7a757265206661696c656400000000000000000000000060448201529051908190036064" + + "0190fd5b604080516001600160a01b03808d168252808c1660208301528183018b905289" + + "1660608201526080810185905290517f298637f684da70674f26509b10f07ec2fbc77a33" + + "5ab1e7d6215a4b2484d8bb529181900360a00190a160065460408051600160e01b6347ef" + + "3b3b0281523060048201526001600160a01b038a811660248301528d811660448301528c" + + "81166064830152608482018c905260a48201879052915191909216916347ef3b3b9160c4" + + "80830192600092919082900301818387803b15801561448457600080fd5b505af1158015" + + "614498573d6000803e3d6000fd5b50600092506144a5915050565b9a9950505050505050" + + "505050565b60125460408051600160e11b636eb1769f0281526001600160a01b03858116" + + "6004830152306024830152915160009392909216918491839163dd62ed3e916044808201" + + "92602092909190829003018186803b15801561451157600080fd5b505afa158015614525" + + "573d6000803e3d6000fd5b505050506040513d602081101561453b57600080fd5b505110" + + "1561454d57600c91505061086f565b82816001600160a01b03166370a082318660405182" + + "63ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152" + + "60200191505060206040518083038186803b1580156145a457600080fd5b505afa158015" + + "6145b8573d6000803e3d6000fd5b505050506040513d60208110156145ce57600080fd5b" + + "505110156145e057600d91505061086f565b5060009392505050565b6012546040805160" + + "0160e01b6323b872dd0281526001600160a01b0385811660048301523060248301526044" + + "820185905291516000939290921691839183916323b872dd916064808201928692909190" + + "82900301818387803b15801561464f57600080fd5b505af1158015614663573d6000803e" + + "3d6000fd5b505050503d6000811461467d576020811461468757600080fd5b6000199150" + + "614693565b60206000803e60005191505b508061318f57600f9250505061086f565b6000" + + "8060006146b16146bb565b6121bd868661270a565b604051806020016040528060008152" + + "5090565b6040805161014081019091528060008152602001600081526020016000815260" + + "200160008152602001600081526020016147066146bb565b815260200160008152602001" + + "6000815260200160008152602001600081525090565b6040805160e08101909152806000" + + "815260200160008152602001600081526020016000815260200160008152602001600081" + + "52602001600081525090565b6040805160c0810190915280600081526020016000614706" + + "565b6040805160a081019091528060008152602001600081526020016000815260200160" + + "00815260200160008152509056fe737570706c7952617465506572426c6f636b3a206361" + + "6c63756c6174696e6720626f72726f7773506572206661696c6564726564756365207265" + + "736572766573207472616e73666572206f7574206661696c6564737570706c7952617465" + + "506572426c6f636b3a2063616c63756c6174696e6720737570706c795261746520666169" + + "6c6564626f72726f7742616c616e636553746f7265643a20626f72726f7742616c616e63" + + "6553746f726564496e7465726e616c206661696c6564737570706c795261746550657242" + + "6c6f636b3a2063616c63756c6174696e6720756e6465726c79696e67206661696c656462" + + "6f72726f7752617465506572426c6f636b3a20696e746572657374526174654d6f64656c" + + "2e626f72726f7752617465206661696c6564737570706c7952617465506572426c6f636b" + + "3a2063616c63756c6174696e6720626f72726f7752617465206661696c6564ddf252ad1b" + + "e2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef737570706c79526174" + + "65506572426c6f636b3a2063616c63756c6174696e67206f6e654d696e75735265736572" + + "7665466163746f72206661696c656465786368616e67655261746553746f7265643a2065" + + "786368616e67655261746553746f726564496e7465726e616c206661696c65646f6e6520" + + "6f662072656465656d546f6b656e73496e206f722072656465656d416d6f756e74496e20" + + "6d757374206265207a65726f72656475636520726573657276657320756e657870656374" + + "656420756e646572666c6f77a165627a7a72305820ae92d0e3e70b657d01891c7457bc6c" + + "8a5ce2401a1a8857f346a2fa9af4627145002953657474696e6720696e74657265737420" + + "72617465206d6f64656c206661696c6564496e697469616c2065786368616e6765207261" + + "7465206d7573742062652067726561746572207468616e207a65726f2e" + + "000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" + // usdc + "0000000000000000000000003d9819210a31b4961b30ef54be2aed79b9c9cd3b" + // troll + "000000000000000000000000c64c4cba055efa614ce01f4bad8a9f519c4f8fab" + // IRM + "0000000000000000000000000000000000000000000000000000b5e620f48000" + + "00000000000000000000000000000000000000000000000000000000000000e0" + + "0000000000000000000000000000000000000000000000000000000000000120" + + "0000000000000000000000000000000000000000000000000000000000000008" + + "0000000000000000000000000000000000000000000000000000000000000011" + + "436f6d706f756e642055534420436f696e000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000005" + + "6355534443000000000000000000000000000000000000000000000000000000"; + + // ************************** helper functions **************************** // + async function send( + title, + instance, + method, + args, + from, + value, + gas, + gasPrice, + shouldSucceed, + assertionCallback + ) { + const receipt = await instance.methods[method](...args) + .send({ + from: from, + value: value, + gas: gas, + gasPrice: gasPrice + }) + .on("confirmation", (confirmationNumber, r) => { + confirmations[r.transactionHash] = confirmationNumber; + }) + .catch(error => { + if (shouldSucceed) { + console.error(error); + } + return { status: false }; + }); + + if (receipt.status !== shouldSucceed) { + return false; + } else if (!shouldSucceed) { + return true; + } + + let assertionsPassed; + try { + assertionCallback(receipt); + assertionsPassed = true; + } catch (error) { + assertionsPassed = false; + console.log(error); + } + + return assertionsPassed; } - ], - "name": "Failure", - "type": "event" - } - ] - - // get available addresses and assign them to various roles - const addresses = await web3.eth.getAccounts() - if (addresses.length < 1) { - console.log('cannot find enough addresses to run tests!') - process.exit(1) - } - - let latestBlock = await web3.eth.getBlock('latest') - - const originalAddress = addresses[0] - - let address = await setupNewDefaultAddress( - '0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed' - ) - - let addressTwo = await setupNewDefaultAddress( - '0xf00df00df00df00df00df00df00df00df00df00df00df00df00df00df00df00d' - ) - - const gasLimit = latestBlock.gasLimit - - // 0x43Af172dFC1017c775D789f5B6cDD375E3D8Fe14 - // primary address, nonce: 0 - const mockPriceOracleDeploymentData = ( - '0x608060405234801561001057600080fd5b5060cd8061001f6000396000f3fe60806040' + - '52348015600f57600080fd5b506004361060325760003560e01c806366331bba14603757' + - '8063fc57d4df146051575b600080fd5b603d6086565b6040805191151582525190819003' + - '60200190f35b607460048036036020811015606557600080fd5b50356001600160a01b03' + - '16608b565b60408051918252519081900360200190f35b600190565b50670de0b6b3a764' + - '00009056fea265627a7a72315820cf3b4d1c8f3041ebb02fbc6b404dd54636a41af89e8a' + - '04ea19bf35f04b48fae764736f6c634300050b0032' - ) - - // 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359 - // nonce: 4 - const mockDaiDeploymentData = ( - '0x608060405234801561001057600080fd5b5060405160208061085d8339810180604052' + - '810190808051906020019092919050505080600160003373ffffffffffffffffffffffff' + - 'ffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001' + - '9081526020016000208190555080600081905550506107cf8061008e6000396000f30060' + - '8060405260043610610078576000357c0100000000000000000000000000000000000000' + - '000000000000000000900463ffffffff168063095ea7b31461007d57806318160ddd1461' + - '00e257806323b872dd1461010d57806370a0823114610192578063a9059cbb146101e957' + - '8063dd62ed3e1461024e575b600080fd5b34801561008957600080fd5b506100c8600480' + - '360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092' + - '9190803590602001909291905050506102c5565b60405180821515151581526020019150' + - '5060405180910390f35b3480156100ee57600080fd5b506100f76103b7565b6040518082' + - '815260200191505060405180910390f35b34801561011957600080fd5b50610178600480' + - '360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092' + - '9190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035' + - '90602001909291905050506103c0565b6040518082151515158152602001915050604051' + - '80910390f35b34801561019e57600080fd5b506101d3600480360381019080803573ffff' + - 'ffffffffffffffffffffffffffffffffffff169060200190929190505050610686565b60' + - '40518082815260200191505060405180910390f35b3480156101f557600080fd5b506102' + - '34600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060' + - '200190929190803590602001909291905050506106cf565b604051808215151515815260' + - '200191505060405180910390f35b34801561025a57600080fd5b506102af600480360381' + - '019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080' + - '3573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506106' + - 'e4565b6040518082815260200191505060405180910390f35b600081600260003373ffff' + - 'ffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffff' + - 'ffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffff' + - 'ffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190' + - '8152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff1633' + - '73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d' + - '1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405180828152602001915050604051' + - '80910390a36001905092915050565b60008054905090565b60003373ffffffffffffffff' + - 'ffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16' + - '1415156104fe5761047d600260008673ffffffffffffffffffffffffffffffffffffffff' + - '1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000' + - '2060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffff' + - 'ffffffffffffffffffffff168152602001908152602001600020548361076b565b600260' + - '008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffff' + - 'ffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffff' + - 'ffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681' + - '52602001908152602001600020819055505b610547600160008673ffffffffffffffffff' + - 'ffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152' + - '602001908152602001600020548361076b565b600160008673ffffffffffffffffffffff' + - 'ffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020' + - '01908152602001600020819055506105d3600160008573ffffffffffffffffffffffffff' + - 'ffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190' + - '81526020016000205483610787565b600160008573ffffffffffffffffffffffffffffff' + - 'ffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152' + - '602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ff' + - 'ffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378d' + - 'aa952ba7f163c4a11628f55a4df523b3ef84604051808281526020019150506040518091' + - '0390a3600190509392505050565b6000600160008373ffffffffffffffffffffffffffff' + - 'ffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081' + - '52602001600020549050919050565b60006106dc3384846103c0565b905092915050565b' + - '6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffff' + - 'ffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffff' + - 'ffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffff' + - 'ffffff16815260200190815260200160002054905092915050565b600082828403915081' + - '1115151561078157600080fd5b92915050565b6000828284019150811015151561079d57' + - '600080fd5b929150505600a165627a7a72305820b4ab3c13e840dd08d9787883bde3458d' + - 'cbab9a56f185c55a59574286095eb6e80029f00000000000000000000000000000000000' + - '0000000000000000000000000000' - ) - - // 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 - // nonce: 20 - const mockUSDCDeploymentData = ( - '0x60806040526000600460146101000a81548160ff021916908315150217905550600060' + - '0e5561003c33610041640100000000026401000000009004565b610084565b8060008061' + - '01000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffff' + - 'ffffffffffffffffffffffffffffffffff16021790555050565b6135c580620000946000' + - '396000f3006080604052600436106101a1576000357c0100000000000000000000000000' + - '000000000000000000000000000000900463ffffffff16806306fdde03146101a6578063' + - '095ea7b31461023657806318160ddd1461029b5780631a895266146102c657806323b872' + - 'dd146103095780633092afd51461038e578063313ce567146103e95780633357162b1461' + - '041a57806335d99f351461059c57806339509351146105f35780633f4ba83a1461065857' + - '806340c10f191461066f57806342966c68146106d45780634e44d9561461070157806355' + - '4bab3c146107665780635c975abb146107a957806370a08231146107d85780638456cb59' + - '1461082f5780638a6db9c3146108465780638da5cb5b1461089d57806395d89b41146108' + - 'f45780639fd0506d14610984578063a457c2d7146109db578063a9059cbb14610a405780' + - '63aa20e1e414610aa5578063aa271e1a14610ae8578063ad38bf2214610b43578063bd10' + - '243014610b86578063dd62ed3e14610bdd578063e5a6b10f14610c54578063f2fde38b14' + - '610ce4578063f9f92be414610d27578063fe575a8714610d6a575b600080fd5b34801561' + - '01b257600080fd5b506101bb610dc5565b60405180806020018281038252838181518152' + - '60200191508051906020019080838360005b838110156101fb5780820151818401526020' + - '810190506101e0565b50505050905090810190601f168015610228578082038051600183' + - '6020036101000a031916815260200191505b509250505060405180910390f35b34801561' + - '024257600080fd5b50610281600480360381019080803573ffffffffffffffffffffffff' + - 'ffffffffffffffff16906020019092919080359060200190929190505050610e63565b60' + - '4051808215151515815260200191505060405180910390f35b3480156102a757600080fd' + - '5b506102b0611033565b6040518082815260200191505060405180910390f35b34801561' + - '02d257600080fd5b50610307600480360381019080803573ffffffffffffffffffffffff' + - 'ffffffffffffffff16906020019092919050505061103d565b005b348015610315576000' + - '80fd5b50610374600480360381019080803573ffffffffffffffffffffffffffffffffff' + - 'ffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16' + - '906020019092919080359060200190929190505050611137565b60405180821515151581' + - '5260200191505060405180910390f35b34801561039a57600080fd5b506103cf60048036' + - '0381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291' + - '90505050611636565b604051808215151515815260200191505060405180910390f35b34' + - '80156103f557600080fd5b506103fe61177d565b604051808260ff1660ff168152602001' + - '91505060405180910390f35b34801561042657600080fd5b5061059a6004803603810190' + - '80803590602001908201803590602001908080601f016020809104026020016040519081' + - '016040528093929190818152602001838380828437820191505050505050919291929080' + - '3590602001908201803590602001908080601f0160208091040260200160405190810160' + - '405280939291908181526020018383808284378201915050505050509192919290803590' + - '602001908201803590602001908080601f01602080910402602001604051908101604052' + - '80939291908181526020018383808284378201915050505050509192919290803560ff16' + - '9060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001' + - '90929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190' + - '803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ff' + - 'ffffffffffffffffffffffffffffffffffffff169060200190929190505050611790565b' + - '005b3480156105a857600080fd5b506105b16119ed565b604051808273ffffffffffffff' + - 'ffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16' + - '815260200191505060405180910390f35b3480156105ff57600080fd5b5061063e600480' + - '360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092' + - '919080359060200190929190505050611a13565b60405180821515151581526020019150' + - '5060405180910390f35b34801561066457600080fd5b5061066d611ab8565b005b348015' + - '61067b57600080fd5b506106ba600480360381019080803573ffffffffffffffffffffff' + - 'ffffffffffffffffff16906020019092919080359060200190929190505050611b5d565b' + - '604051808215151515815260200191505060405180910390f35b3480156106e057600080' + - 'fd5b506106ff60048036038101908080359060200190929190505050611eff565b005b34' + - '801561070d57600080fd5b5061074c600480360381019080803573ffffffffffffffffff' + - 'ffffffffffffffffffffff16906020019092919080359060200190929190505050612166' + - '565b604051808215151515815260200191505060405180910390f35b3480156107725760' + - '0080fd5b506107a7600480360381019080803573ffffffffffffffffffffffffffffffff' + - 'ffffffff1690602001909291905050506122d4565b005b3480156107b557600080fd5b50' + - '6107be6123fa565b604051808215151515815260200191505060405180910390f35b3480' + - '156107e457600080fd5b50610819600480360381019080803573ffffffffffffffffffff' + - 'ffffffffffffffffffff16906020019092919050505061240d565b604051808281526020' + - '0191505060405180910390f35b34801561083b57600080fd5b50610844612456565b005b' + - '34801561085257600080fd5b50610887600480360381019080803573ffffffffffffffff' + - 'ffffffffffffffffffffffff1690602001909291905050506124fb565b60405180828152' + - '60200191505060405180910390f35b3480156108a957600080fd5b506108b2612544565b' + - '604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffff' + - 'ffffffffffffffffffffffff16815260200191505060405180910390f35b348015610900' + - '57600080fd5b5061090961256d565b604051808060200182810382528381815181526020' + - '0191508051906020019080838360005b8381101561094957808201518184015260208101' + - '905061092e565b50505050905090810190601f1680156109765780820380516001836020' + - '036101000a031916815260200191505b509250505060405180910390f35b348015610990' + - '57600080fd5b5061099961260b565b604051808273ffffffffffffffffffffffffffffff' + - 'ffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050' + - '60405180910390f35b3480156109e757600080fd5b50610a266004803603810190808035' + - '73ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001' + - '90929190505050612631565b604051808215151515815260200191505060405180910390' + - 'f35b348015610a4c57600080fd5b50610a8b600480360381019080803573ffffffffffff' + - 'ffffffffffffffffffffffffffff16906020019092919080359060200190929190505050' + - '612734565b604051808215151515815260200191505060405180910390f35b348015610a' + - 'b157600080fd5b50610ae6600480360381019080803573ffffffffffffffffffffffffff' + - 'ffffffffffffff169060200190929190505050612a37565b005b348015610af457600080' + - 'fd5b50610b29600480360381019080803573ffffffffffffffffffffffffffffffffffff' + - 'ffff169060200190929190505050612b5d565b6040518082151515158152602001915050' + - '60405180910390f35b348015610b4f57600080fd5b50610b846004803603810190808035' + - '73ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612bb3' + - '565b005b348015610b9257600080fd5b50610b9b612cd9565b604051808273ffffffffff' + - 'ffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffff' + - 'ff16815260200191505060405180910390f35b348015610be957600080fd5b50610c3e60' + - '0480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001' + - '90929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190' + - '505050612cff565b6040518082815260200191505060405180910390f35b348015610c60' + - '57600080fd5b50610c69612d86565b604051808060200182810382528381815181526020' + - '0191508051906020019080838360005b83811015610ca957808201518184015260208101' + - '9050610c8e565b50505050905090810190601f168015610cd65780820380516001836020' + - '036101000a031916815260200191505b509250505060405180910390f35b348015610cf0' + - '57600080fd5b50610d25600480360381019080803573ffffffffffffffffffffffffffff' + - 'ffffffffffff169060200190929190505050612e24565b005b348015610d3357600080fd' + - '5b50610d68600480360381019080803573ffffffffffffffffffffffffffffffffffffff' + - 'ff169060200190929190505050612f4b565b005b348015610d7657600080fd5b50610dab' + - '600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020' + - '0190929190505050613045565b6040518082151515158152602001915050604051809103' + - '90f35b60078054600181600116156101000203166002900480601f016020809104026020' + - '016040519081016040528092919081815260200182805460018160011615610100020316' + - '600290048015610e5b5780601f10610e3057610100808354040283529160200191610e5b' + - '565b820191906000526020600020905b815481529060010190602001808311610e3e5782' + - '9003601f168201915b505050505081565b6000600460149054906101000a900460ff1615' + - '1515610e8157600080fd5b3360001515600660008373ffffffffffffffffffffffffffff' + - 'ffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081' + - '5260200160002060009054906101000a900460ff161515141515610ee157600080fd5b83' + - '60001515600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffff' + - 'ffffffffffffffffffffffffffffffff1681526020019081526020016000206000905490' + - '6101000a900460ff161515141515610f4157600080fd5b83600d60003373ffffffffffff' + - 'ffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff' + - '16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffff' + - 'ffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020' + - '01600020819055508473ffffffffffffffffffffffffffffffffffffffff163373ffffff' + - 'ffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd' + - '0314c0f7b2291e5b200ac8c7c3b925866040518082815260200191505060405180910390' + - 'a360019250505092915050565b6000600e54905090565b600560009054906101000a9004' + - '73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffff' + - 'ffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156110' + - '9957600080fd5b6000600660008373ffffffffffffffffffffffffffffffffffffffff16' + - '73ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020' + - '60006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffff' + - 'ffffffffffffffffff167f117e3210bb9aa7d9baff172026820255c6f6c30ba8999d1c2f' + - 'd88e2848137c4e60405160405180910390a250565b6000600460149054906101000a9004' + - '60ff1615151561115557600080fd5b8260001515600660008373ffffffffffffffffffff' + - 'ffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260' + - '200190815260200160002060009054906101000a900460ff1615151415156111b5576000' + - '80fd5b3360001515600660008373ffffffffffffffffffffffffffffffffffffffff1673' + - 'ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060' + - '009054906101000a900460ff16151514151561121557600080fd5b856000151560066000' + - '8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffff' + - 'ffffffffffffffff16815260200190815260200160002060009054906101000a900460ff' + - '16151514151561127557600080fd5b600073ffffffffffffffffffffffffffffffffffff' + - 'ffff168673ffffffffffffffffffffffffffffffffffffffff16141515156112b1576000' + - '80fd5b600c60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffff' + - 'ffffffffffffffffffffffffffffff168152602001908152602001600020548511151515' + - '6112ff57600080fd5b600d60008873ffffffffffffffffffffffffffffffffffffffff16' + - '73ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020' + - '60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffff' + - 'ffffffffffffffffffff16815260200190815260200160002054851115151561138a5760' + - '0080fd5b6113dc85600c60008a73ffffffffffffffffffffffffffffffffffffffff1673' + - 'ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054' + - '61309b90919063ffffffff16565b600c60008973ffffffffffffffffffffffffffffffff' + - 'ffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260' + - '20016000208190555061147185600c60008973ffffffffffffffffffffffffffffffffff' + - 'ffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020' + - '01600020546130e590919063ffffffff16565b600c60008873ffffffffffffffffffffff' + - 'ffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020' + - '019081526020016000208190555061154385600d60008a73ffffffffffffffffffffffff' + - 'ffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001' + - '90815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ff' + - 'ffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461' + - '309b90919063ffffffff16565b600d60008973ffffffffffffffffffffffffffffffffff' + - 'ffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020' + - '0160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffff' + - 'ffffffffffffffffffffffffffff168152602001908152602001600020819055508573ff' + - 'ffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffff' + - 'ffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4d' + - 'f523b3ef876040518082815260200191505060405180910390a360019350505050939250' + - '5050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffff' + - 'ffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffff' + - 'ffffffffffffffffffffffffff1614151561169457600080fd5b6000600f60008473ffff' + - 'ffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffff' + - 'ffffffff16815260200190815260200160002060006101000a81548160ff021916908315' + - '1502179055506000601060008473ffffffffffffffffffffffffffffffffffffffff1673' + - 'ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081' + - '9055508173ffffffffffffffffffffffffffffffffffffffff167fe94479a9f7e1952cc7' + - '8f2d6baab678adc1b772d936c6583def489e524cb6669260405160405180910390a26001' + - '9050919050565b600960009054906101000a900460ff1681565b600b6014905490610100' + - '0a900460ff161515156117ac57600080fd5b600073ffffffffffffffffffffffffffffff' + - 'ffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141515156117e8' + - '57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffff' + - 'ffffffffffffffffffffffffffffffff161415151561182457600080fd5b600073ffffff' + - 'ffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffff' + - 'ffffffff161415151561186057600080fd5b600073ffffffffffffffffffffffffffffff' + - 'ffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561189c' + - '57600080fd5b87600790805190602001906118b29291906134f4565b5086600890805190' + - '602001906118c99291906134f4565b5085600a90805190602001906118e09291906134f4' + - '565b5084600960006101000a81548160ff021916908360ff16021790555083600b600061' + - '01000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffff' + - 'ffffffffffffffffffffffffffffffffff16021790555082600460006101000a81548173' + - 'ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffff' + - 'ffffffffffffffffffff16021790555081600560006101000a81548173ffffffffffffff' + - 'ffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffff' + - 'ffffff1602179055506119c88161316f565b6001600b60146101000a81548160ff021916' + - '9083151502179055505050505050505050565b600b60009054906101000a900473ffffff' + - 'ffffffffffffffffffffffffffffffffff1681565b6000611aae3384611aa98560026000' + - '3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffff' + - 'ffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffff' + - 'ffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152' + - '602001908152602001600020546130e590919063ffffffff16565b6131b2565b60019050' + - '92915050565b600460009054906101000a900473ffffffffffffffffffffffffffffffff' + - 'ffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffff' + - 'ffffffffffffffffffffffffff16141515611b1457600080fd5b6000600460146101000a' + - '81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112' + - 'aca9e0847911ed832e158c525b3360405160405180910390a1565b600080600460149054' + - '906101000a900460ff16151515611b7c57600080fd5b60011515600f60003373ffffffff' + - 'ffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffff' + - 'ffff16815260200190815260200160002060009054906101000a900460ff161515141515' + - '611bdb57600080fd5b3360001515600660008373ffffffffffffffffffffffffffffffff' + - 'ffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260' + - '200160002060009054906101000a900460ff161515141515611c3b57600080fd5b846000' + - '1515600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffff' + - 'ffffffffffffffffffffffffffff16815260200190815260200160002060009054906101' + - '000a900460ff161515141515611c9b57600080fd5b600073ffffffffffffffffffffffff' + - 'ffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614151515' + - '611cd757600080fd5b600085111515611ce657600080fd5b601060003373ffffffffffff' + - 'ffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff' + - '168152602001908152602001600020549250828511151515611d3757600080fd5b611d4c' + - '85600e546130e590919063ffffffff16565b600e81905550611da485600c60008973ffff' + - 'ffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffff' + - 'ffffffff168152602001908152602001600020546130e590919063ffffffff16565b600c' + - '60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffff' + - 'ffffffffffffffffffff16815260200190815260200160002081905550611dfa85846130' + - '9b90919063ffffffff16565b601060003373ffffffffffffffffffffffffffffffffffff' + - 'ffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001' + - '600020819055508573ffffffffffffffffffffffffffffffffffffffff163373ffffffff' + - 'ffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb253' + - '6d647574c8e7e5da92c2ede0c9f8876040518082815260200191505060405180910390a3' + - '8573ffffffffffffffffffffffffffffffffffffffff1660007fddf252ad1be2c89b69c2' + - 'b068fc378daa952ba7f163c4a11628f55a4df523b3ef8760405180828152602001915050' + - '60405180910390a36001935050505092915050565b6000600460149054906101000a9004' + - '60ff16151515611f1d57600080fd5b60011515600f60003373ffffffffffffffffffffff' + - 'ffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020' + - '0190815260200160002060009054906101000a900460ff161515141515611f7c57600080' + - 'fd5b3360001515600660008373ffffffffffffffffffffffffffffffffffffffff1673ff' + - 'ffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000' + - '9054906101000a900460ff161515141515611fdc57600080fd5b600c60003373ffffffff' + - 'ffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffff' + - 'ffff16815260200190815260200160002054915060008311151561202d57600080fd5b82' + - '821015151561203c57600080fd5b61205183600e5461309b90919063ffffffff16565b60' + - '0e8190555061206a838361309b90919063ffffffff16565b600c60003373ffffffffffff' + - 'ffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff' + - '168152602001908152602001600020819055503373ffffffffffffffffffffffffffffff' + - 'ffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d' + - '397ca5846040518082815260200191505060405180910390a2600073ffffffffffffffff' + - 'ffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16' + - '7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040' + - '518082815260200191505060405180910390a3505050565b600060046014905490610100' + - '0a900460ff1615151561218457600080fd5b600b60009054906101000a900473ffffffff' + - 'ffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffff' + - 'ffff163373ffffffffffffffffffffffffffffffffffffffff161415156121e057600080' + - 'fd5b6001600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffff' + - 'ffffffffffffffffffffffffffffffff1681526020019081526020016000206000610100' + - '0a81548160ff02191690831515021790555081601060008573ffffffffffffffffffffff' + - 'ffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020' + - '01908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff' + - '167f46980fca912ef9bcdbd36877427b6b90e860769f604e89c0e67720cece530d208360' + - '40518082815260200191505060405180910390a26001905092915050565b6122dc612544' + - '565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffff' + - 'ffffffffffffffffffff1614151561231557600080fd5b600073ffffffffffffffffffff' + - 'ffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415' + - '151561235157600080fd5b80600460006101000a81548173ffffffffffffffffffffffff' + - 'ffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602' + - '17905550600460009054906101000a900473ffffffffffffffffffffffffffffffffffff' + - 'ffff1673ffffffffffffffffffffffffffffffffffffffff167fb80482a293ca2e013eda' + - '8683c9bd7fc8347cfdaeea5ede58cba46df502c2a60460405160405180910390a250565b' + - '600460149054906101000a900460ff1681565b6000600c60008373ffffffffffffffffff' + - 'ffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152' + - '602001908152602001600020549050919050565b600460009054906101000a900473ffff' + - 'ffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffff' + - 'ffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156124b25760' + - '0080fd5b6001600460146101000a81548160ff0219169083151502179055507f6985a022' + - '10a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff6256040516040518091' + - '0390a1565b6000601060008373ffffffffffffffffffffffffffffffffffffffff1673ff' + - 'ffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490' + - '50919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffff' + - 'ffffffffff16905090565b60088054600181600116156101000203166002900480601f01' + - '602080910402602001604051908101604052809291908181526020018280546001816001' + - '16156101000203166002900480156126035780601f106125d85761010080835404028352' + - '9160200191612603565b820191906000526020600020905b815481529060010190602001' + - '8083116125e657829003601f168201915b505050505081565b600460009054906101000a' + - '900473ffffffffffffffffffffffffffffffffffffffff1681565b600061272a33846127' + - '2585606060405190810160405280602581526020017f45524332303a2064656372656173' + - '656420616c6c6f77616e63652062656c6f7781526020017f207a65726f00000000000000' + - '0000000000000000000000000000000000000000815250600260003373ffffffffffffff' + - 'ffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16' + - '815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffff' + - 'ffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001' + - '600020546134339092919063ffffffff16565b6131b2565b6001905092915050565b6000' + - '600460149054906101000a900460ff1615151561275257600080fd5b3360001515600660' + - '008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffff' + - 'ffffffffffffffffff16815260200190815260200160002060009054906101000a900460' + - 'ff1615151415156127b257600080fd5b8360001515600660008373ffffffffffffffffff' + - 'ffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152' + - '60200190815260200160002060009054906101000a900460ff1615151415156128125760' + - '0080fd5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffff' + - 'ffffffffffffffffffffffffffff161415151561284e57600080fd5b600c60003373ffff' + - 'ffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffff' + - 'ffffffff16815260200190815260200160002054841115151561289c57600080fd5b6128' + - 'ee84600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffff' + - 'ffffffffffffffffffffffffffff1681526020019081526020016000205461309b909190' + - '63ffffffff16565b600c60003373ffffffffffffffffffffffffffffffffffffffff1673' + - 'ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081' + - '90555061298384600c60008873ffffffffffffffffffffffffffffffffffffffff1673ff' + - 'ffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461' + - '30e590919063ffffffff16565b600c60008773ffffffffffffffffffffffffffffffffff' + - 'ffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020' + - '01600020819055508473ffffffffffffffffffffffffffffffffffffffff163373ffffff' + - 'ffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa95' + - '2ba7f163c4a11628f55a4df523b3ef866040518082815260200191505060405180910390' + - 'a360019250505092915050565b612a3f612544565b73ffffffffffffffffffffffffffff' + - 'ffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612a78' + - '57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffff' + - 'ffffffffffffffffffffffffffffffff1614151515612ab457600080fd5b80600b600061' + - '01000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffff' + - 'ffffffffffffffffffffffffffffffffff160217905550600b60009054906101000a9004' + - '73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffff' + - 'ffffffffffffff167fdb66dfa9c6b8f5226fe9aac7e51897ae8ee94ac31dc70bb6c9900b' + - '2574b707e660405160405180910390a250565b6000600f60008373ffffffffffffffffff' + - 'ffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152' + - '60200190815260200160002060009054906101000a900460ff169050919050565b612bbb' + - '612544565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffff' + - 'ffffffffffffffffffffffffff16141515612bf457600080fd5b600073ffffffffffffff' + - 'ffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff' + - '1614151515612c3057600080fd5b80600560006101000a81548173ffffffffffffffffff' + - 'ffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffff' + - 'ff160217905550600560009054906101000a900473ffffffffffffffffffffffffffffff' + - 'ffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fc67398012c111c' + - 'e95ecb7429b933096c977380ee6c421175a71a4a4c6c88c06e60405160405180910390a2' + - '50565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffff' + - 'ff1681565b6000600d60008473ffffffffffffffffffffffffffffffffffffffff1673ff' + - 'ffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000' + - '8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffff' + - 'ffffffffffffffff16815260200190815260200160002054905092915050565b600a8054' + - '600181600116156101000203166002900480601f01602080910402602001604051908101' + - '604052809291908181526020018280546001816001161561010002031660029004801561' + - '2e1c5780601f10612df157610100808354040283529160200191612e1c565b8201919060' + - '00526020600020905b815481529060010190602001808311612dff57829003601f168201' + - '915b505050505081565b612e2c612544565b73ffffffffffffffffffffffffffffffffff' + - 'ffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612e65576000' + - '80fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffff' + - 'ffffffffffffffffffffffffff1614151515612ea157600080fd5b7f8be0079c53165914' + - '1344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0612eca612544565b82604051' + - '808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffff' + - 'ffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffff' + - 'ff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050604051' + - '80910390a1612f488161316f565b50565b600560009054906101000a900473ffffffffff' + - 'ffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffff' + - 'ff163373ffffffffffffffffffffffffffffffffffffffff16141515612fa757600080fd' + - '5b6001600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffff' + - 'ffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a' + - '81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffff' + - 'ffffff167fffa4e6181777692565cf28528fc88fd1516ea86b56da075235fa575af6a4b8' + - '5560405160405180910390a250565b6000600660008373ffffffffffffffffffffffffff' + - 'ffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190' + - '815260200160002060009054906101000a900460ff169050919050565b60006130dd8383' + - '6040805190810160405280601e81526020017f536166654d6174683a2073756274726163' + - '74696f6e206f766572666c6f770000815250613433565b905092915050565b6000808284' + - '019050838110151515613165576040517f08c379a0000000000000000000000000000000' + - '00000000000000000000000000815260040180806020018281038252601b815260200180' + - '7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815250' + - '60200191505060405180910390fd5b8091505092915050565b806000806101000a815481' + - '73ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffff' + - 'ffffffffffffffffffffff16021790555050565b600073ffffffffffffffffffffffffff' + - 'ffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151561' + - '327d576040517f08c379a000000000000000000000000000000000000000000000000000' + - '00000081526004018080602001828103825260248152602001807f45524332303a206170' + - '70726f76652066726f6d20746865207a65726f2061646481526020017f72657373000000' + - '000000000000000000000000000000000000000000000000008152506040019150506040' + - '5180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffff' + - 'ffffffffffffffffffffffffffffffffff1614151515613348576040517f08c379a00000' + - '000000000000000000000000000000000000000000000000000081526004018080602001' + - '828103825260228152602001807f45524332303a20617070726f766520746f2074686520' + - '7a65726f20616464726581526020017f7373000000000000000000000000000000000000' + - '00000000000000000000000081525060400191505060405180910390fd5b806002600085' + - '73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffff' + - 'ffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffff' + - 'ffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260' + - '2001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffff' + - 'ff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f' + - '71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405180828152602001915050' + - '60405180910390a3505050565b60008084841115839015156134e3576040517f08c379a0' + - '000000000000000000000000000000000000000000000000000000008152600401808060' + - '2001828103825283818151815260200191508051906020019080838360005b8381101561' + - '34a857808201518184015260208101905061348d565b50505050905090810190601f1680' + - '156134d55780820380516001836020036101000a031916815260200191505b5092505050' + - '60405180910390fd5b508385039050809150509392505050565b82805460018160011615' + - '6101000203166002900490600052602060002090601f016020900481019282601f106135' + - '3557805160ff1916838001178555613563565b8280016001018555821561356357918201' + - '5b82811115613562578251825591602001919060010190613547565b5b50905061357091' + - '90613574565b5090565b61359691905b8082111561359257600081600090555060010161' + - '357a565b5090565b905600a165627a7a72305820e15de5c992fd476a4778192f1e437474' + - 'd0da61a53e449a2db2ec25213f4be8620029' - ) - - // 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B - // nonce: 0 - const mockUnitrollerDeploymentData = ( - '0x608060405234801561001057600080fd5b50600080546001600160a01b031916331790' + - '556105db806100326000396000f3fe60806040526004361061007b5760003560e01c8063' + - 'dcfbc0c71161004e578063dcfbc0c71461019e578063e992a041146101b3578063e9c714' + - 'f2146101e6578063f851a440146101fb5761007b565b806326782247146100fe578063b7' + - '1d1a0c1461012f578063bb82aa5e14610174578063c1e8033414610189575b6002546040' + - '516000916001600160a01b03169082903690808383808284376040519201945060009350' + - '9091505080830381855af49150503d80600081146100de576040519150601f19603f3d01' + - '1682016040523d82523d6000602084013e6100e3565b606091505b505090506040513d60' + - '00823e8180156100fa573d82f35b3d82fd5b34801561010a57600080fd5b506101136102' + - '10565b604080516001600160a01b039092168252519081900360200190f35b3480156101' + - '3b57600080fd5b506101626004803603602081101561015257600080fd5b503560016001' + - '60a01b031661021f565b60408051918252519081900360200190f35b3480156101805760' + - '0080fd5b506101136102b0565b34801561019557600080fd5b506101626102bf565b3480' + - '156101aa57600080fd5b506101136103ba565b3480156101bf57600080fd5b5061016260' + - '0480360360208110156101d657600080fd5b50356001600160a01b03166103c9565b3480' + - '156101f257600080fd5b5061016261044d565b34801561020757600080fd5b5061011361' + - '0533565b6001546001600160a01b031681565b600080546001600160a01b031633146102' + - '455761023e6001600e610542565b90506102ab565b600180546001600160a01b03848116' + - '6001600160a01b0319831681179093556040805191909216808252602082019390935281' + - '517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99291' + - '81900390910190a160005b9150505b919050565b6002546001600160a01b031681565b60' + - '03546000906001600160a01b0316331415806102e557506003546001600160a01b031615' + - '5b156102fc576102f5600180610542565b90506103b7565b600280546003805460016001' + - '60a01b038082166001600160a01b03198086168217968790559092169092556040805193' + - '8316808552949092166020840152815190927fd604de94d45953f9138079ec1b82d533cb' + - '2160c906d1076d1f7ed54befbca97a92908290030190a1600354604080516001600160a0' + - '1b038085168252909216602083015280517fe945ccee5d701fc83f9b8aa8ca94ea4219ec' + - '1fcbd4f4cab4f0ea57c5c3e1d8159281900390910190a160005b925050505b90565b6003' + - '546001600160a01b031681565b600080546001600160a01b031633146103e85761023e60' + - '01600f610542565b600380546001600160a01b038481166001600160a01b031983161792' + - '8390556040805192821680845293909116602083015280517fe945ccee5d701fc83f9b8a' + - 'a8ca94ea4219ec1fcbd4f4cab4f0ea57c5c3e1d8159281900390910190a160006102a756' + - '5b6001546000906001600160a01b031633141580610468575033155b15610479576102f5' + - '60016000610542565b60008054600180546001600160a01b038082166001600160a01b03' + - '198086168217968790559092169092556040805193831680855294909216602084015281' + - '5190927ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc' + - '92908290030190a1600154604080516001600160a01b0380851682529092166020830152' + - '80517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a992' + - '81900390910190a160006103b2565b6000546001600160a01b031681565b60007f45b96f' + - 'e442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601181111561' + - '057157fe5b83601381111561057d57fe5b60408051928352602083019190915260008282' + - '0152519081900360600190a18260118111156105a857fe5b939250505056fea165627a7a' + - '72305820deb1fa7c9392a8cb5591582fb6e4b04575db52ce8ef799b0a7a5140ae6ff75d8' + - '0029' - ) - - // 0x178053c06006e67e09879C09Ff012fF9d263dF29 - // nonce: 68 - const mockCurrentComptrollerDeploymentData = ( - '0x608060405234801561001057600080fd5b50600080546001600160a01b031916331790' + - '55612d15806100326000396000f3fe608060405234801561001057600080fd5b50600436' + - '106102315760003560e01c80638e8f294b11610130578063d02f7351116100b8578063e4' + - '028eee1161007c578063e4028eee1461090e578063e87554461461093a578063eabe7d91' + - '14610942578063ede4edd014610978578063f851a4401461099e57610231565b8063d02f' + - '735114610841578063d9226ced14610887578063da3d454c146108a4578063dce1544914' + - '6108da578063dcfbc0c71461090657610231565b8063abfceffc116100ff578063abfcef' + - 'fc14610695578063bb82aa5e1461070b578063bdcdc25814610713578063c29982381461' + - '074f578063c488847b146107f257610231565b80638e8f294b146105f8578063929fe9a1' + - '1461063957806394b2294b14610667578063a76b3fda1461066f57610231565b80634ef4' + - 'c3e1116101be5780635ec88c79116101825780635ec88c79146104e45780635fc7e71e14' + - '6105285780636a56947e1461056e5780636d35bf91146105aa5780637dc0d1d0146105f0' + - '57610231565b80634ef4c3e1146103f95780634fd42e171461042f57806351dff9891461' + - '044c57806355ee1fe1146104885780635c778605146104ae57610231565b8063317b0b77' + - '11610205578063317b0b771461030857806332000e001461032557806341c728b9146103' + - '6957806347ef3b3b146103a55780634ada90af146103f157610231565b80627e3dd21461' + - '02365780631ededc911461025257806324008a621461029657806326782247146102e457' + - '5b600080fd5b61023e6109a6565b604080519115158252519081900360200190f35b6102' + - '94600480360360a081101561026857600080fd5b506001600160a01b0381358116916020' + - '81013582169160408201351690606081013590608001356109ab565b005b6102d2600480' + - '360360808110156102ac57600080fd5b506001600160a01b038135811691602081013582' + - '169160408201351690606001356109b2565b60408051918252519081900360200190f35b' + - '6102ec6109e8565b604080516001600160a01b039092168252519081900360200190f35b' + - '6102d26004803603602081101561031e57600080fd5b50356109f7565b61029460048036' + - '0360a081101561033b57600080fd5b506001600160a01b03813581169160208101359091' + - '1690604081013590606081013590608001351515610b05565b6102946004803603608081' + - '101561037f57600080fd5b506001600160a01b0381358116916020810135909116906040' + - '8101359060600135610fcd565b610294600480360360c08110156103bb57600080fd5b50' + - '6001600160a01b0381358116916020810135821691604082013581169160608101359091' + - '169060808101359060a00135610fd3565b6102d2610fd8565b6102d26004803603606081' + - '101561040f57600080fd5b506001600160a01b0381358116916020810135909116906040' + - '0135610fde565b6102d26004803603602081101561044557600080fd5b5035611015565b' + - '6102946004803603608081101561046257600080fd5b506001600160a01b038135811691' + - '60208101359091169060408101359060600135611104565b6102d2600480360360208110' + - '1561049e57600080fd5b50356001600160a01b0316611167565b61029460048036036060' + - '8110156104c457600080fd5b506001600160a01b03813581169160208101359091169060' + - '4001356111e9565b61050a600480360360208110156104fa57600080fd5b503560016001' + - '60a01b03166111ee565b6040805193845260208401929092528282015251908190036060' + - '0190f35b6102d2600480360360a081101561053e57600080fd5b506001600160a01b0381' + - '358116916020810135821691604082013581169160608101359091169060800135611223' + - '565b6102946004803603608081101561058457600080fd5b506001600160a01b03813581' + - '169160208101358216916040820135169060600135610fcd565b610294600480360360a0' + - '8110156105c057600080fd5b506001600160a01b03813581169160208101358216916040' + - '820135811691606081013590911690608001356109ab565b6102ec6113aa565b61061e60' + - '04803603602081101561060e57600080fd5b50356001600160a01b03166113b9565b6040' + - '8051921515835260208301919091528051918290030190f35b61023e6004803603604081' + - '101561064f57600080fd5b506001600160a01b03813581169160200135166113d8565b61' + - '02d261140c565b6102d26004803603602081101561068557600080fd5b50356001600160' + - 'a01b0316611412565b6106bb600480360360208110156106ab57600080fd5b5035600160' + - '0160a01b0316611541565b60408051602080825283518183015283519192839290830191' + - '858101910280838360005b838110156106f75781810151838201526020016106df565b50' + - '5050509050019250505060405180910390f35b6102ec6115ca565b6102d2600480360360' + - '8081101561072957600080fd5b506001600160a01b038135811691602081013582169160' + - '408201351690606001356115d9565b6106bb6004803603602081101561076557600080fd' + - '5b81019060208101813564010000000081111561078057600080fd5b8201836020820111' + - '1561079257600080fd5b8035906020019184602083028401116401000000008311171561' + - '07b457600080fd5b91908080602002602001604051908101604052809392919081815260' + - '20018383602002808284376000920191909152509295506115e6945050505050565b6108' + - '286004803603606081101561080857600080fd5b506001600160a01b0381358116916020' + - '810135909116906040013561178a565b6040805192835260208301919091528051918290' + - '030190f35b6102d2600480360360a081101561085757600080fd5b506001600160a01b03' + - '81358116916020810135821691604082013581169160608101359091169060800135611a' + - '05565b6102d26004803603602081101561089d57600080fd5b5035611b4b565b6102d260' + - '0480360360608110156108ba57600080fd5b506001600160a01b03813581169160208101' + - '359091169060400135611baf565b6102ec600480360360408110156108f057600080fd5b' + - '506001600160a01b038135169060200135611ce6565b6102ec611d1b565b6102d2600480' + - '3603604081101561092457600080fd5b506001600160a01b038135169060200135611d2a' + - '565b6102d2611edd565b6102d26004803603606081101561095857600080fd5b50600160' + - '0160a01b03813581169160208101359091169060400135611ee3565b6102d26004803603' + - '602081101561098e57600080fd5b50356001600160a01b0316611ef0565b6102ec612206' + - '565b600181565b5050505050565b6001600160a01b038416600090815260096020526040' + - '81205460ff166109da575060096109e0565b60005b90505b949350505050565b60015460' + - '01600160a01b031681565b6000610a01612215565b610a1857610a116001600461226056' + - '5b9050610b00565b610a20612bde565b506040805160208101909152828152610a37612b' + - 'de565b50604080516020810190915266b1a2bc2ec500008152610a5782826122c6565b15' + - '610a7057610a67600580612260565b92505050610b00565b610a78612bde565b50604080' + - '5160208101909152670c7d713b49da00008152610a9981846122ce565b15610ab357610a' + - 'a9600580612260565b9350505050610b00565b6005805490869055604080518281526020' + - '810188905281517f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f3' + - '46110fd9929181900390910190a160005b9450505050505b919050565b846001600160a0' + - '1b031663f851a4406040518163ffffffff1660e01b815260040160206040518083038186' + - '803b158015610b3e57600080fd5b505afa158015610b52573d6000803e3d6000fd5b5050' + - '50506040513d6020811015610b6857600080fd5b50516001600160a01b03163314610bb3' + - '57604051600160e51b62461bcd0281526004018080602001828103825260278152602001' + - '80612cc36027913960400191505060405180910390fd5b6000856001600160a01b031663' + - 'c1e803346040518163ffffffff1660e01b8152600401602060405180830381600087803b' + - '158015610bf057600080fd5b505af1158015610c04573d6000803e3d6000fd5b50505050' + - '6040513d6020811015610c1a57600080fd5b505190508015610c745760408051600160e5' + - '1b62461bcd02815260206004820152601560248201527f6368616e6765206e6f74206175' + - '74686f72697a65640000000000000000000000604482015290519081900360640190fd5b' + - '81610fc55760008690506000816001600160a01b03166355ee1fe1886040518263ffffff' + - 'ff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191' + - '5050602060405180830381600087803b158015610cd857600080fd5b505af1158015610c' + - 'ec573d6000803e3d6000fd5b505050506040513d6020811015610d0257600080fd5b5051' + - '90508015610d5c5760408051600160e51b62461bcd028152602060048201526016602482' + - '01527f736574207072696365206f7261636c65206572726f720000000000000000000060' + - '4482015290519081900360640190fd5b816001600160a01b031663317b0b778760405182' + - '63ffffffff1660e01b815260040180828152602001915050602060405180830381600087' + - '803b158015610da257600080fd5b505af1158015610db6573d6000803e3d6000fd5b5050' + - '50506040513d6020811015610dcc57600080fd5b505190508015610e2657604080516001' + - '60e51b62461bcd02815260206004820152601660248201527f73657420636c6f73652066' + - '6163746f72206572726f7200000000000000000000604482015290519081900360640190' + - 'fd5b816001600160a01b031663d9226ced866040518263ffffffff1660e01b8152600401' + - '80828152602001915050602060405180830381600087803b158015610e6c57600080fd5b' + - '505af1158015610e80573d6000803e3d6000fd5b505050506040513d6020811015610e96' + - '57600080fd5b505190508015610ef05760408051600160e51b62461bcd02815260206004' + - '820152601560248201527f736574206d61782061737373657473206572726f7200000000' + - '00000000000000604482015290519081900360640190fd5b816001600160a01b0316634f' + - 'd42e17670de0b6b3a76400006040518263ffffffff1660e01b8152600401808281526020' + - '01915050602060405180830381600087803b158015610f3e57600080fd5b505af1158015' + - '610f52573d6000803e3d6000fd5b505050506040513d6020811015610f6857600080fd5b' + - '505190508015610fc25760408051600160e51b62461bcd02815260206004820152601f60' + - '248201527f736574206c69717569646174696f6e20696e63656e74697665206572726f72' + - '00604482015290519081900360640190fd5b50505b505050505050565b50505050565b61' + - '0fc5565b60065481565b6001600160a01b03831660009081526009602052604081205460' + - 'ff166110085760095b905061100e565b60005b90505b9392505050565b600061101f6122' + - '15565b61102f57610a116001600b612260565b611037612bde565b506040805160208101' + - '90915282815261104e612bde565b506040805160208101909152670de0b6b3a764000081' + - '5261106f82826122ce565b1561108057610a676007600c612260565b611088612bde565b' + - '5060408051602081019091526714d1120d7b16000081526110a981846122ce565b156110' + - 'ba57610aa96007600c612260565b60068054908690556040805182815260208101889052' + - '81517faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec131692' + - '9181900390910190a16000610af9565b801580156111125750600082115b15610fcd5760' + - '408051600160e51b62461bcd02815260206004820152601160248201527f72656465656d' + - '546f6b656e73207a65726f00000000000000000000000000000060448201529051908190' + - '0360640190fd5b6000611171612215565b61118157610a1160016010612260565b600480' + - '546001600160a01b038481166001600160a01b0319831681179093556040805191909216' + - '808252602082019390935281517fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d' + - '2d0ea78402d576d22e22929181900390910190a160009392505050565b505050565b6000' + - '806000806000806112058760008060006122d5565b925092509250826011811115611217' + - '57fe5b97919650945092505050565b6001600160a01b0385166000908152600960205260' + - '4081205460ff16158061126457506001600160a01b038516600090815260096020526040' + - '90205460ff16155b156112735760095b90506113a1565b60008061127f856126fd565b91' + - '93509091506000905082601181111561129557fe5b146112af578160118111156112a657' + - 'fe5b925050506113a1565b806112bb5760036112a6565b6000886001600160a01b031663' + - '95dd9193876040518263ffffffff1660e01b815260040180826001600160a01b03166001' + - '600160a01b0316815260200191505060206040518083038186803b158015611313576000' + - '80fd5b505afa158015611327573d6000803e3d6000fd5b505050506040513d6020811015' + - '61133d57600080fd5b505160408051602081019091526005548152909150600090819061' + - '1361908461271d565b9092509050600082600381111561137457fe5b1461138857600b5b' + - '955050505050506113a1565b8087111561139757601161137c565b600095505050505050' + - '5b95945050505050565b6004546001600160a01b031681565b6009602052600090815260' + - '409020805460019091015460ff9091169082565b6001600160a01b038082166000908152' + - '600960209081526040808320938616835260029093019052205460ff165b92915050565b' + - '60075481565b600080546001600160a01b0316331461143157610a116001601261226056' + - '5b6001600160a01b03821660009081526009602052604090205460ff161561145e57610a' + - '11600a6011612260565b816001600160a01b031663fe9c44ae6040518163ffffffff1660' + - 'e01b815260040160206040518083038186803b15801561149757600080fd5b505afa1580' + - '156114ab573d6000803e3d6000fd5b505050506040513d60208110156114c157600080fd' + - '5b50506040805180820182526001808252600060208084018281526001600160a01b0388' + - '1680845260098352928690209451855460ff191690151517855551939092019290925582' + - '5191825291517fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f2' + - '12321f929181900390910190a1600092915050565b60608060086000846001600160a01b' + - '03166001600160a01b031681526020019081526020016000208054806020026020016040' + - '519081016040528092919081815260200182805480156115bd5760200282019190600052' + - '6020600020905b81546001600160a01b0316815260019091019060200180831161159f57' + - '5b5093979650505050505050565b6002546001600160a01b031681565b60006109dd8585' + - '84612771565b606060008251905060608160405190808252806020026020018201604052' + - '801561161a578160200160208202803883390190505b50905060005b8281101561178257' + - '600085828151811061163657fe5b6020908102919091018101516001600160a01b038116' + - '60009081526009909252604090912080549192509060ff1661168a5760095b8484815181' + - '1061167757fe5b602002602001018181525050505061177a565b33600090815260028201' + - '602052604090205460ff161515600114156116b057600061166b565b6007543360009081' + - '5260086020526040902054106116cf57601061166b565b33600081815260028301602090' + - '81526040808320805460ff19166001908117909155600883528184208054918201815584' + - '529282902090920180546001600160a01b0387166001600160a01b031990911681179091' + - '5582519081529081019290925280517f3ab23ab0d51cccc0c3085aec51f99228625aa1a9' + - '22b3a8ca89a26b0f2027a1a59281900390910190a1600084848151811061176b57fe5b60' + - '200260200101818152505050505b600101611620565b509392505050565b600480546040' + - '8051600160e01b63fc57d4df0281526001600160a01b0387811694820194909452905160' + - '00938493849391169163fc57d4df91602480820192602092909190829003018186803b15' + - '80156117e357600080fd5b505afa1580156117f7573d6000803e3d6000fd5b5050505060' + - '40513d602081101561180d57600080fd5b50516004805460408051600160e01b63fc57d4' + - 'df0281526001600160a01b038a8116948201949094529051939450600093929091169163' + - 'fc57d4df91602480820192602092909190829003018186803b15801561186957600080fd' + - '5b505afa15801561187d573d6000803e3d6000fd5b505050506040513d60208110156118' + - '9357600080fd5b505190508115806118a2575080155b156118b757600d93506000925061' + - '19fd915050565b6000866001600160a01b031663182df0f56040518163ffffffff1660e0' + - '1b815260040160206040518083038186803b1580156118f257600080fd5b505afa158015' + - '611906573d6000803e3d6000fd5b505050506040513d602081101561191c57600080fd5b' + - '50519050600061192a612bde565b611932612bde565b61193a612bde565b600061194860' + - '0654896127e0565b94509050600081600381111561195a57fe5b1461197657600b5b9950' + - '600098506119fd975050505050505050565b61198087876127e0565b9350905060008160' + - '0381111561199257fe5b1461199e57600b611962565b6119a8848461281b565b92509050' + - '60008160038111156119ba57fe5b146119c657600b611962565b6119d0828c61271d565b' + - '9550905060008160038111156119e257fe5b146119ee57600b611962565b600099509397' + - '50505050505050505b935093915050565b6001600160a01b038516600090815260096020' + - '52604081205460ff161580611a4657506001600160a01b03851660009081526009602052' + - '604090205460ff16155b15611a5257600961126c565b846001600160a01b0316635fe3b5' + - '676040518163ffffffff1660e01b815260040160206040518083038186803b158015611a' + - '8b57600080fd5b505afa158015611a9f573d6000803e3d6000fd5b505050506040513d60' + - '20811015611ab557600080fd5b505160408051600160e01b635fe3b56702815290516001' + - '600160a01b0392831692891691635fe3b567916004808301926020929190829003018186' + - '803b158015611afe57600080fd5b505afa158015611b12573d6000803e3d6000fd5b5050' + - '50506040513d6020811015611b2857600080fd5b50516001600160a01b031614611b3f57' + - '600261126c565b60009695505050505050565b6000611b55612215565b611b6557610a11' + - '6001600d612260565b6007805490839055604080518281526020810185905281517f7093' + - 'cf1eb653f749c3ff531d6df7f92764536a7fa0d13530cd26e070780c32ea929181900390' + - '910190a1600061100e565b6001600160a01b038316600090815260096020526040812054' + - '60ff16611bd6576009611001565b6001600160a01b038085166000908152600960209081' + - '526040808320938716835260029093019052205460ff16611c0e576008611001565b6004' + - '805460408051600160e01b63fc57d4df0281526001600160a01b03888116948201949094' + - '529051929091169163fc57d4df91602480820192602092909190829003018186803b1580' + - '15611c6257600080fd5b505afa158015611c76573d6000803e3d6000fd5b505050506040' + - '513d6020811015611c8c57600080fd5b5051611c9957600d611001565b600080611ca985' + - '876000876122d5565b91935090915060009050826011811115611cbf57fe5b14611cd957' + - '816011811115611cd057fe5b9250505061100e565b8015611b3f576004611cd0565b6008' + - '6020528160005260406000208181548110611cff57fe5b60009182526020909120015460' + - '01600160a01b03169150829050565b6003546001600160a01b031681565b600080546001' + - '600160a01b03163314611d5057611d4960016006612260565b9050611406565b60016001' + - '60a01b0383166000908152600960205260409020805460ff16611d8557611d7d60096007' + - '612260565b915050611406565b611d8d612bde565b506040805160208101909152838152' + - '611da4612bde565b506040805160208101909152670c7d713b49da00008152611dc58183' + - '6122ce565b15611de057611dd660066008612260565b9350505050611406565b84158015' + - '90611e6c57506004805460408051600160e01b63fc57d4df0281526001600160a01b038a' + - '8116948201949094529051929091169163fc57d4df916024808201926020929091908290' + - '03018186803b158015611e3e57600080fd5b505afa158015611e52573d6000803e3d6000' + - 'fd5b505050506040513d6020811015611e6857600080fd5b5051155b15611e7d57611dd6' + - '600d6009612260565b60018301805490869055604080516001600160a01b038916815260' + - '20810183905280820188905290517f70483e6592cd5182d45ac970e05bc62cdcc90e9d8e' + - 'f2c2dbe686cf383bcd7fc59181900360600190a16000979650505050505050565b600554' + - '81565b600061100b848484612771565b6000808290506000806000836001600160a01b03' + - '1663c37f68e2336040518263ffffffff1660e01b815260040180826001600160a01b0316' + - '6001600160a01b0316815260200191505060806040518083038186803b158015611f5157' + - '600080fd5b505afa158015611f65573d6000803e3d6000fd5b505050506040513d608081' + - '1015611f7b57600080fd5b50805160208201516040909201519094509092509050821561' + - '1fd157604051600160e51b62461bcd028152600401808060200182810382526025815260' + - '200180612c9e6025913960400191505060405180910390fd5b8015611fee57611fe3600c' + - '6002612260565b945050505050610b00565b6000611ffb873385612771565b9050801561' + - '201c57612010600e600383612833565b95505050505050610b00565b6001600160a01b03' + - '85166000908152600960209081526040808320338452600281019092529091205460ff16' + - '61205b5760009650505050505050610b00565b3360009081526002820160209081526040' + - '808320805460ff1916905560088252918290208054835181840281018401909452808452' + - '606093928301828280156120cd57602002820191906000526020600020905b8154600160' + - '0160a01b031681526001909101906020018083116120af575b5050835193945083925060' + - '009150505b8281101561212257896001600160a01b03168482815181106120fb57fe5b60' + - '200260200101516001600160a01b0316141561211a57809150612122565b6001016120dd' + - '565b5081811061212c57fe5b336000908152600860205260409020805481906000198101' + - '90811061214d57fe5b9060005260206000200160009054906101000a90046001600160a0' + - '1b031681838154811061217757fe5b600091825260209091200180546001600160a01b03' + - '19166001600160a01b039290921691909117905580546121b0826000198301612bf1565b' + - '50604080516001600160a01b038c16815233602082015281517fe699a64c18b07ac5b730' + - '1aa273f36a2287239eb9501d81950672794afba29a0d929181900390910190a160009c9b' + - '505050505050505050505050565b6000546001600160a01b031681565b60025460009081' + - '906001600160a01b03163314801561223e57506000546001600160a01b031632145b6000' + - '549091506001600160a01b0316331480806122585750815b925050505b90565b60007f45' + - 'b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08360118111' + - '1561228f57fe5b83601381111561229b57fe5b6040805192835260208301919091526000' + - '82820152519081900360600190a182601181111561100e57fe5b519051111590565b5190' + - '511090565b60008060006122e2612c15565b6001600160a01b0388166000908152600860' + - '209081526040808320805482518185028101850190935280835284936060939291908301' + - '8282801561234f57602002820191906000526020600020905b81546001600160a01b0316' + - '8152600190910190602001808311612331575b50939450600093505050505b8151811015' + - '6126ae57600082828151811061237257fe5b60200260200101519050806001600160a01b' + - '031663c37f68e28e6040518263ffffffff1660e01b815260040180826001600160a01b03' + - '166001600160a01b0316815260200191505060806040518083038186803b1580156123d2' + - '57600080fd5b505afa1580156123e6573d6000803e3d6000fd5b505050506040513d6080' + - '8110156123fc57600080fd5b508051602082015160408084015160609485015160808c01' + - '52938a019390935291880191909152945084156124425750600f97506000965086955061' + - '26f3945050505050565b60408051602080820183526001600160a01b0380851660008181' + - '526009845285902060010154845260c08b01939093528351808301855260808b01518152' + - '60e08b0152600480548551600160e01b63fc57d4df028152918201949094529351921692' + - '63fc57d4df9260248083019392829003018186803b1580156124c557600080fd5b505afa' + - '1580156124d9573d6000803e3d6000fd5b505050506040513d60208110156124ef576000' + - '80fd5b505160a087018190526125135750600d9750600096508695506126f39450505050' + - '50565b604080516020810190915260a08701518152610100870181905260c087015160e0' + - '88015161254092612899565b6101208801529350600084600381111561255657fe5b1461' + - '25725750600b9750600096508695506126f3945050505050565b61258a86610120015187' + - '6040015188600001516128f1565b87529350600084600381111561259c57fe5b146125b8' + - '5750600b9750600096508695506126f3945050505050565b6125d0866101000151876060' + - '015188602001516128f1565b6020880152935060008460038111156125e557fe5b146126' + - '015750600b9750600096508695506126f3945050505050565b8b6001600160a01b031681' + - '6001600160a01b031614156126a55761262f8661012001518c88602001516128f1565b60' + - '208801529350600084600381111561264457fe5b146126605750600b9750600096508695' + - '506126f3945050505050565b6126748661010001518b88602001516128f1565b60208801' + - '529350600084600381111561268957fe5b146126a55750600b9750600096508695506126' + - 'f3945050505050565b5060010161235b565b506020840151845111156126d55750505060' + - '208101519051600094500391508290506126f3565b505081516020909201516000955085' + - '94509190910391506126f39050565b9450945094915050565b6000806000612710846000' + - '8060006122d5565b9250925092509193909250565b600080600061272a612bde565b6127' + - '34868661293e565b9092509050600082600381111561274757fe5b146127585750915060' + - '00905061276a565b6000612763826129a6565b9350935050505b9250929050565b600160' + - '0160a01b03831660009081526009602052604081205460ff16612798576009611001565b' + - '6001600160a01b0380851660009081526009602090815260408083209387168352600290' + - '93019052205460ff166127d0576000611001565b600080611ca985878660006122d5565b' + - '60006127ea612bde565b6128106040518060200160405280868152506040518060200160' + - '405280868152506129b5565b915091509250929050565b6000612825612bde565b835183' + - '516128109190612a9e565b60007f45b96fe442630264581b197e84bbada861235052c5a1' + - 'aadfff9ea4e40a969aa084601181111561286257fe5b84601381111561286e57fe5b6040' + - '80519283526020830191909152818101859052519081900360600190a183601181111561' + - '100b57fe5b60006128a3612bde565b60006128ad612bde565b6128b787876129b5565b90' + - '9250905060008260038111156128ca57fe5b146128d95790925090506119fd565b6128e3' + - '81866129b5565b935093505050935093915050565b60008060006128fe612bde565b6129' + - '08878761293e565b9092509050600082600381111561291b57fe5b1461292c5750915060' + - '0090506119fd565b6128e3612938826129a6565b86612b4e565b6000612948612bde565b' + - '600080612959866000015186612b74565b9092509050600082600381111561296c57fe5b' + - '1461298b5750604080516020810190915260008152909250905061276a565b6040805160' + - '2081019091529081526000969095509350505050565b51670de0b6b3a764000090049056' + - '5b60006129bf612bde565b6000806129d486600001518660000151612b74565b90925090' + - '5060008260038111156129e757fe5b14612a065750604080516020810190915260008152' + - '909250905061276a565b600080612a1b6706f05b59d3b2000084612b4e565b9092509050' + - '6000826003811115612a2e57fe5b14612a50575060408051602081019091526000815290' + - '9450925061276a915050565b600080612a6583670de0b6b3a7640000612bb3565b909250' + - '90506000826003811115612a7857fe5b14612a7f57fe5b60408051602081019091529081' + - '5260009a909950975050505050505050565b6000612aa8612bde565b600080612abd8667' + - '0de0b6b3a7640000612b74565b90925090506000826003811115612ad057fe5b14612aef' + - '5750604080516020810190915260008152909250905061276a565b600080612afc838861' + - '2bb3565b90925090506000826003811115612b0f57fe5b14612b31575060408051602081' + - '0190915260008152909450925061276a915050565b604080516020810190915290815260' + - '009890975095505050505050565b600080838301848110612b665760009250905061276a' + - '565b50600291506000905061276a565b60008083612b875750600090508061276a565b83' + - '830283858281612b9457fe5b0414612ba85750600291506000905061276a565b60009250' + - '905061276a565b60008082612bc7575060019050600061276a565b6000838581612bd257' + - 'fe5b04915091509250929050565b6040518060200160405280600081525090565b815481' + - '8355818111156111e9576000838152602090206111e9918101908301612c7f565b604051' + - '806101400160405280600081526020016000815260200160008152602001600081526020' + - '016000815260200160008152602001612c53612bde565b8152602001612c60612bde565b' + - '8152602001612c6d612bde565b8152602001612c7a612bde565b905290565b61225d9190' + - '5b80821115612c995760008155600101612c85565b509056fe657869744d61726b65743a' + - '206765744163636f756e74536e617073686f74206661696c65646f6e6c7920756e697472' + - '6f6c6c65722061646d696e2063616e206368616e676520627261696e73a165627a7a7230' + - '582075d92d0e96eb01957b794704a02af0b7e3c5efe630de7186f3688639d7128e900029' - ) - - // 0xa1046abfc2598F48C44Fb320d281d3F3c0733c9a - // nonce: 7 - const mockCDaiIRMDeploymentData = ( - '0x608060405234801561001057600080fd5b506040516040806106638339810180604052' + - '604081101561003057600080fd5b50805160209091015160019190915560005561061280' + - '6100516000396000f3fe608060405234801561001057600080fd5b506004361061005757' + - '60003560e01c806315f240531461005c5780631b3ed7221461009e5780631f68f20a1461' + - '00b85780632191f92a146100c0578063a385fb96146100dc575b600080fd5b6100856004' + - '803603606081101561007257600080fd5b50803590602081013590604001356100e4565b' + - '6040805192835260208301919091528051918290030190f35b6100a661017d565b604080' + - '51918252519081900360200190f35b6100a6610183565b6100c8610189565b6040805191' + - '15158252519081900360200190f35b6100a661018e565b60008060006100f16105d3565b' + - '6100f96105d3565b6101038888610195565b919450925090506000836004811115610118' + - '57fe5b146101385782600481111561012957fe5b94506000935061017592505050565b60' + - '006101426105d3565b61014f8362201480610312565b9092509050600082600381111561' + - '016257fe5b1461016957fe5b51600096509450505050505b935093915050565b60005481' + - '565b60015481565b600181565b6220148081565b600061019f6105d3565b6101a76105d3' + - '565b60006101b16105d3565b6101bb878761037c565b9092509050600082600481111561' + - '01ce57fe5b146101fc575060408051602080820183526000808352835191820190935291' + - '8252919450909250905061030b565b60006102066105d3565b6102128360005461043e56' + - '5b9092509050600082600381111561022557fe5b14610257575050604080516020808201' + - '835260008083528351918201909352918252600396509450925061030b915050565b6000' + - '6102616105d3565b61027383670de0b6b3a7640000610312565b90925090506000826003' + - '81111561028657fe5b1461028d57fe5b60006102976105d3565b6102b183604051806020' + - '0160405280600154815250610459565b909250905060008260038111156102c457fe5b14' + - '6102fa57505060408051602080820183526000808352835191820190935291825260049a' + - '509850965061030b95505050505050565b60009a509598509496505050505050505b9250' + - '925092565b600061031c6105d3565b60008061032d866000015186610493565b90925090' + - '50600082600381111561034057fe5b1461035f5750604080516020810190915260008152' + - '9092509050610375565b6040805160208101909152908152600093509150505b92509290' + - '50565b60006103866105d3565b826103a357505060408051602081019091526000808252' + - '90610375565b6000806103b086866104be565b909250905060008260038111156103c357' + - 'fe5b146103e4575050604080516020810190915260008152600192509050610375565b60' + - '006103ee6105d3565b6103f887846104e4565b9092509050600082600381111561040b57' + - 'fe5b1461042f575050604080516020810190915260008152600294509250610375915050' + - '565b60009890975095505050505050565b60006104486105d3565b60008061032d866000' + - '015186610594565b60006104636105d3565b600080610478866000015186600001516104' + - 'be565b60408051602081019091529081529097909650945050505050565b600080826104' + - 'a75750600190506000610375565b60008385816104b257fe5b0491509150925092905056' + - '5b6000808383018481106104d657600092509050610375565b5060029150600090506103' + - '75565b60006104ee6105d3565b60008061050386670de0b6b3a7640000610594565b9092' + - '509050600082600381111561051657fe5b14610535575060408051602081019091526000' + - '81529092509050610375565b6000806105428388610493565b9092509050600082600381' + - '111561055557fe5b14610577575060408051602081019091526000815290945092506103' + - '75915050565b604080516020810190915290815260009890975095505050505050565b60' + - '0080836105a757506000905080610375565b838302838582816105b457fe5b04146105c8' + - '57506002915060009050610375565b600092509050610375565b60405180602001604052' + - '8060008152509056fea165627a7a7230582021d1e96de1a54e5aaf17c19ae397dd393fa0' + - 'cd21afedd016b0e6d1fb0e4c749600290000000000000000000000000000000000000000' + - '0000000000b1a2bc2ec50000000000000000000000000000000000000000000000000000' + - '01aa535d3d0c0000' - ) - - // 0xc64C4cBA055eFA614CE01F4BAD8A9F519C4f8FaB - // nonce: 8 - const mockCUSDCIRMDeploymentData = ( - '0x608060405234801561001057600080fd5b506040516040806106638339810180604052' + - '604081101561003057600080fd5b50805160209091015160019190915560005561061280' + - '6100516000396000f3fe608060405234801561001057600080fd5b506004361061005757' + - '60003560e01c806315f240531461005c5780631b3ed7221461009e5780631f68f20a1461' + - '00b85780632191f92a146100c0578063a385fb96146100dc575b600080fd5b6100856004' + - '803603606081101561007257600080fd5b50803590602081013590604001356100e4565b' + - '6040805192835260208301919091528051918290030190f35b6100a661017d565b604080' + - '51918252519081900360200190f35b6100a6610183565b6100c8610189565b6040805191' + - '15158252519081900360200190f35b6100a661018e565b60008060006100f16105d3565b' + - '6100f96105d3565b6101038888610195565b919450925090506000836004811115610118' + - '57fe5b146101385782600481111561012957fe5b94506000935061017592505050565b60' + - '006101426105d3565b61014f8362201480610312565b9092509050600082600381111561' + - '016257fe5b1461016957fe5b51600096509450505050505b935093915050565b60005481' + - '565b60015481565b600181565b6220148081565b600061019f6105d3565b6101a76105d3' + - '565b60006101b16105d3565b6101bb878761037c565b9092509050600082600481111561' + - '01ce57fe5b146101fc575060408051602080820183526000808352835191820190935291' + - '8252919450909250905061030b565b60006102066105d3565b6102128360005461043e56' + - '5b9092509050600082600381111561022557fe5b14610257575050604080516020808201' + - '835260008083528351918201909352918252600396509450925061030b915050565b6000' + - '6102616105d3565b61027383670de0b6b3a7640000610312565b90925090506000826003' + - '81111561028657fe5b1461028d57fe5b60006102976105d3565b6102b183604051806020' + - '0160405280600154815250610459565b909250905060008260038111156102c457fe5b14' + - '6102fa57505060408051602080820183526000808352835191820190935291825260049a' + - '509850965061030b95505050505050565b60009a509598509496505050505050505b9250' + - '925092565b600061031c6105d3565b60008061032d866000015186610493565b90925090' + - '50600082600381111561034057fe5b1461035f5750604080516020810190915260008152' + - '9092509050610375565b6040805160208101909152908152600093509150505b92509290' + - '50565b60006103866105d3565b826103a357505060408051602081019091526000808252' + - '90610375565b6000806103b086866104be565b909250905060008260038111156103c357' + - 'fe5b146103e4575050604080516020810190915260008152600192509050610375565b60' + - '006103ee6105d3565b6103f887846104e4565b9092509050600082600381111561040b57' + - 'fe5b1461042f575050604080516020810190915260008152600294509250610375915050' + - '565b60009890975095505050505050565b60006104486105d3565b60008061032d866000' + - '015186610594565b60006104636105d3565b600080610478866000015186600001516104' + - 'be565b60408051602081019091529081529097909650945050505050565b600080826104' + - 'a75750600190506000610375565b60008385816104b257fe5b0491509150925092905056' + - '5b6000808383018481106104d657600092509050610375565b5060029150600090506103' + - '75565b60006104ee6105d3565b60008061050386670de0b6b3a7640000610594565b9092' + - '509050600082600381111561051657fe5b14610535575060408051602081019091526000' + - '81529092509050610375565b6000806105428388610493565b9092509050600082600381' + - '111561055557fe5b14610577575060408051602081019091526000815290945092506103' + - '75915050565b604080516020810190915290815260009890975095505050505050565b60' + - '0080836105a757506000905080610375565b838302838582816105b457fe5b04146105c8' + - '57506002915060009050610375565b600092509050610375565b60405180602001604052' + - '8060008152509056fea165627a7a7230582021d1e96de1a54e5aaf17c19ae397dd393fa0' + - 'cd21afedd016b0e6d1fb0e4c749600290000000000000000000000000000000000000000' + - '000000000000000000000000000000000000000000000000000000000000000000000000' + - '02c68af0bb140000' - ) - - // 0xF5DCe57282A584D2746FaF1593d3121Fcac444dC - // nonce: 14 - const mockCDaiDeploymentData = ( - '0x60806040523480156200001157600080fd5b506040516200523c3803806200523c8339' + - '81018060405260e08110156200003757600080fd5b815160208301516040840151606085' + - '0151608086018051949693959294919392830192916401000000008111156200006e5760' + - '0080fd5b820160208101848111156200008257600080fd5b815164010000000081118282' + - '01871017156200009d57600080fd5b505092919060200180516401000000008111156200' + - '00ba57600080fd5b82016020810184811115620000ce57600080fd5b8151640100000000' + - '811182820187101715620000e957600080fd5b5050602090910151600160005560048054' + - '6001600160a01b0319163317905560088690559092509050858585858585836200017057' + - '6040517f08c379a000000000000000000000000000000000000000000000000000000000' + - '81526004018080602001828103825260308152602001806200520c603091396040019150' + - '5060405180910390fd5b600062000183876200036460201b60201c565b90508015620001' + - 'f357604080517f08c379a000000000000000000000000000000000000000000000000000' + - '000000815260206004820152601a60248201527f53657474696e6720636f6d7074726f6c' + - '6c6572206661696c6564000000000000604482015290519081900360640190fd5b620002' + - '03620004f760201b60201c565b600a55670de0b6b3a7640000600b556200022486620004' + - 'fc602090811b901c565b905080156200027f576040517f08c379a0000000000000000000' + - '000000000000000000000000000000000000008152600401808060200182810382526022' + - '815260200180620051ea6022913960400191505060405180910390fd5b83516200029490' + - '60019060208701906200071e565b508251620002aa9060029060208601906200071e565b' + - '50506003555050601280546001600160a01b0319166001600160a01b038c811691909117' + - '91829055604080517f18160ddd0000000000000000000000000000000000000000000000' + - '0000000000815290519290911694506318160ddd93506004808201935060209291829003' + - '018186803b1580156200032857600080fd5b505afa1580156200033d573d6000803e3d60' + - '00fd5b505050506040513d60208110156200035457600080fd5b50620007c09750505050' + - '50505050565b6004546000906001600160a01b0316331462000396576200038e6001603f' + - '620006ae60201b60201c565b9050620004f2565b600654604080517e7e3dd20000000000' + - '0000000000000000000000000000000000000000000000815290516001600160a01b0392' + - '831692851691627e3dd2916004808301926020929190829003018186803b158015620003' + - 'f557600080fd5b505afa1580156200040a573d6000803e3d6000fd5b505050506040513d' + - '60208110156200042157600080fd5b50516200048f57604080517f08c379a00000000000' + - '0000000000000000000000000000000000000000000000815260206004820152601c6024' + - '8201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000' + - '604482015290519081900360640190fd5b600680546001600160a01b0319166001600160' + - 'a01b03858116918217909255604080519284168352602083019190915280517f7ac369db' + - 'd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d9281900390910190' + - 'a160005b9150505b919050565b435b90565b60045460009081906001600160a01b031633' + - '1462000531576200052860016042620006ae60201b60201c565b915050620004f2565b62' + - '000541620004f760201b60201c565b600a54146200055e5762000528600a6041620006ae' + - '60201b60201c565b600760009054906101000a90046001600160a01b0316905082600160' + - '0160a01b0316632191f92a6040518163ffffffff1660e01b815260040160206040518083' + - '038186803b158015620005b057600080fd5b505afa158015620005c5573d6000803e3d60' + - '00fd5b505050506040513d6020811015620005dc57600080fd5b50516200064a57604080' + - '517f08c379a0000000000000000000000000000000000000000000000000000000008152' + - '60206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65' + - '642066616c736500000000604482015290519081900360640190fd5b6007805460016001' + - '60a01b0319166001600160a01b0385811691821790925560408051928416835260208301' + - '9190915280517fedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d' + - '72f9269281900390910190a16000620004ee565b60007f45b96fe442630264581b197e84' + - 'bbada861235052c5a1aadfff9ea4e40a969aa0836010811115620006de57fe5b83604d81' + - '1115620006eb57fe5b604080519283526020830191909152600082820152519081900360' + - '600190a18260108111156200071757fe5b9392505050565b828054600181600116156101' + - '000203166002900490600052602060002090601f016020900481019282601f1062000761' + - '57805160ff191683800117855562000791565b8280016001018555821562000791579182' + - '015b828111156200079157825182559160200191906001019062000774565b506200079f' + - '929150620007a3565b5090565b620004f991905b808211156200079f5760008155600101' + - '620007aa565b614a1a80620007d06000396000f3fe608060405234801561001057600080' + - 'fd5b506004361061028a5760003560e01c80638f840ddd1161015c578063c37f68e21161' + - '00ce578063f3fdb15a11610087578063f3fdb15a14610708578063f5e3c4621461071057' + - '8063f851a44014610746578063f8f9da281461074e578063fca7820b14610756578063fe' + - '9c44ae146107735761028a565b8063c37f68e214610626578063c5ebeaec146106725780' + - '63db006a751461068f578063dd62ed3e146106ac578063e9c714f2146106da578063f2b3' + - 'abbd146106e25761028a565b8063a9059cbb11610120578063a9059cbb14610586578063' + - 'aa5af0fd146105b2578063ae9d70b0146105ba578063b2a02ff1146105c2578063b71d1a' + - '0c146105f8578063bd6d894d1461061e5761028a565b80638f840ddd1461052b57806395' + - 'd89b411461053357806395dd91931461053b578063a0712d6814610561578063a6afed95' + - '1461057e5761028a565b80633af9e66911610200578063675d972c116101b9578063675d' + - '972c146104c85780636c540baf146104d05780636f307dc3146104d857806370a0823114' + - '6104e057806373acee9814610506578063852a12e31461050e5761028a565b80633af9e6' + - '69146104475780633b1d21a21461046d5780634576b5db1461047557806347bd37181461' + - '049b5780635fe3b567146104a3578063601a0bf1146104ab5761028a565b806318160ddd' + - '1161025257806318160ddd146103a9578063182df0f5146103b157806323b872dd146103' + - 'b95780632608f818146103ef578063267822471461041b578063313ce5671461043f5761' + - '028a565b806306fdde031461028f578063095ea7b31461030c5780630e7527021461034c' + - '578063173b99041461037b57806317bfdfbc14610383575b600080fd5b61029761077b56' + - '5b6040805160208082528351818301528351919283929083019185019080838360005b83' + - '8110156102d15781810151838201526020016102b9565b50505050905090810190601f16' + - '80156102fe5780820380516001836020036101000a031916815260200191505b50925050' + - '5060405180910390f35b6103386004803603604081101561032257600080fd5b50600160' + - '0160a01b038135169060200135610808565b604080519115158252519081900360200190' + - 'f35b6103696004803603602081101561036257600080fd5b5035610875565b6040805191' + - '8252519081900360200190f35b610369610888565b610369600480360360208110156103' + - '9957600080fd5b50356001600160a01b031661088e565b610369610951565b6103696109' + - '57565b610338600480360360608110156103cf57600080fd5b506001600160a01b038135' + - '811691602081013590911690604001356109bd565b610369600480360360408110156104' + - '0557600080fd5b506001600160a01b038135169060200135610a29565b610423610a3c56' + - '5b604080516001600160a01b039092168252519081900360200190f35b610369610a4b56' + - '5b6103696004803603602081101561045d57600080fd5b50356001600160a01b0316610a' + - '51565b610369610abf565b6103696004803603602081101561048b57600080fd5b503560' + - '01600160a01b0316610ace565b610369610c23565b610423610c29565b61036960048036' + - '0360208110156104c157600080fd5b5035610c38565b610369610cc6565b610369610ccc' + - '565b610423610cd2565b610369600480360360208110156104f657600080fd5b50356001' + - '600160a01b0316610ce1565b610369610cfc565b61036960048036036020811015610524' + - '57600080fd5b5035610db6565b610369610dc1565b610297610dc7565b61036960048036' + - '03602081101561055157600080fd5b50356001600160a01b0316610e1f565b6103696004' + - '803603602081101561057757600080fd5b5035610e7f565b610369610e8a565b61033860' + - '04803603604081101561059c57600080fd5b506001600160a01b03813516906020013561' + - '1286565b6103696112f1565b6103696112f7565b610369600480360360608110156105d8' + - '57600080fd5b506001600160a01b038135811691602081013590911690604001356115d1' + - '565b6103696004803603602081101561060e57600080fd5b50356001600160a01b031661' + - '188e565b610369611915565b61064c6004803603602081101561063c57600080fd5b5035' + - '6001600160a01b03166119d0565b60408051948552602085019390935283830191909152' + - '6060830152519081900360800190f35b6103696004803603602081101561068857600080' + - 'fd5b5035611a65565b610369600480360360208110156106a557600080fd5b5035611a70' + - '565b610369600480360360408110156106c257600080fd5b506001600160a01b03813581' + - '16916020013516611a7b565b610369611aa6565b610369600480360360208110156106f8' + - '57600080fd5b50356001600160a01b0316611b95565b610423611bcf565b610369600480' + - '3603606081101561072657600080fd5b506001600160a01b038135811691602081013591' + - '60409091013516611bde565b610423611beb565b610369611bfa565b6103696004803603' + - '602081101561076c57600080fd5b5035611cd9565b610338611d13565b60018054604080' + - '516020600284861615610100026000190190941693909304601f81018490048402820184' + - '0190925281815292918301828280156108005780601f106107d557610100808354040283' + - '529160200191610800565b820191906000526020600020905b8154815290600101906020' + - '018083116107e357829003601f168201915b505050505081565b33600081815260106020' + - '90815260408083206001600160a01b038716808552908352818420869055815186815291' + - '51939493909284927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200a' + - 'c8c7c3b925929081900390910190a360019150505b92915050565b600061088082611d18' + - '565b90505b919050565b60095481565b60008054600101808255816108a1610e8a565b14' + - '6108f65760408051600160e51b62461bcd02815260206004820152601660248201527f61' + - '636372756520696e746572657374206661696c6564000000000000000000006044820152' + - '90519081900360640190fd5b6108ff83610e1f565b91505b600054811461094b57604080' + - '51600160e51b62461bcd02815260206004820152600a6024820152600160b21b691c994b' + - '595b9d195c995902604482015290519081900360640190fd5b50919050565b600e548156' + - '5b6000806000610964611d54565b9092509050600082600381111561097757fe5b146109' + - 'b657604051600160e51b62461bcd02815260040180806020018281038252603581526020' + - '01806149626035913960400191505060405180910390fd5b9150505b90565b6000805460' + - '0101808255816109d433878787611e02565b1491505b6000548114610a21576040805160' + - '0160e51b62461bcd02815260206004820152600a6024820152600160b21b691c994b595b' + - '9d195c995902604482015290519081900360640190fd5b509392505050565b6000610a35' + - '8383612116565b9392505050565b6005546001600160a01b031681565b60035481565b60' + - '00610a5b6146bb565b6040518060200160405280610a6e611915565b90526001600160a0' + - '1b0384166000908152600f6020526040812054919250908190610a9a9084906121a6565b' + - '90925090506000826003811115610aad57fe5b14610ab757600080fd5b94935050505056' + - '5b6000610ac96121fa565b905090565b6004546000906001600160a01b03163314610af6' + - '57610aef6001603f61227d565b9050610883565b60065460408051600160e11b623f1ee9' + - '02815290516001600160a01b0392831692851691627e3dd2916004808301926020929190' + - '829003018186803b158015610b3e57600080fd5b505afa158015610b52573d6000803e3d' + - '6000fd5b505050506040513d6020811015610b6857600080fd5b5051610bbe5760408051' + - '600160e51b62461bcd02815260206004820152601c60248201527f6d61726b6572206d65' + - '74686f642072657475726e65642066616c73650000000060448201529051908190036064' + - '0190fd5b600680546001600160a01b0319166001600160a01b0385811691821790925560' + - '4080519284168352602083019190915280517f7ac369dbd14fa5ea3f473ed67cc9d59896' + - '4a77501540ba6751eb0b3decf5870d9281900390910190a160009392505050565b600c54' + - '81565b6006546001600160a01b031681565b6000805460010180825581610c4b610e8a56' + - '5b90508015610c7157610c69816010811115610c6257fe5b603061227d565b9250506109' + - '02565b610c7a846122e3565b925050600054811461094b5760408051600160e51b62461b' + - 'cd02815260206004820152600a6024820152600160b21b691c994b595b9d195c99590260' + - '4482015290519081900360640190fd5b60085481565b600a5481565b6012546001600160' + - 'a01b031681565b6001600160a01b03166000908152600f602052604090205490565b6000' + - '805460010180825581610d0f610e8a565b14610d645760408051600160e51b62461bcd02' + - '815260206004820152601660248201527f61636372756520696e74657265737420666169' + - '6c656400000000000000000000604482015290519081900360640190fd5b600c54915060' + - '00548114610db25760408051600160e51b62461bcd02815260206004820152600a602482' + - '0152600160b21b691c994b595b9d195c995902604482015290519081900360640190fd5b' + - '5090565b600061088082612467565b600d5481565b600280546040805160206001841615' + - '6101000260001901909316849004601f8101849004840282018401909252818152929183' + - '01828280156108005780601f106107d55761010080835404028352916020019161080056' + - '5b6000806000610e2d846124a4565b90925090506000826003811115610e4057fe5b1461' + - '0a3557604051600160e51b62461bcd028152600401808060200182810382526037815260' + - '2001806148366037913960400191505060405180910390fd5b600061088082612558565b' + - '6000610e946146ce565b6007546001600160a01b03166315f24053610ead6121fa565b60' + - '0c54600d546040518463ffffffff1660e01b815260040180848152602001838152602001' + - '8281526020019350505050604080518083038186803b158015610ef457600080fd5b505a' + - 'fa158015610f08573d6000803e3d6000fd5b505050506040513d6040811015610f1e5760' + - '0080fd5b50805160209182015160408401819052918301526601c6bf526340001015610f' + - '905760408051600160e51b62461bcd02815260206004820152601c60248201527f626f72' + - '726f772072617465206973206162737572646c7920686967680000000060448201529051' + - '9081900360640190fd5b602081015115610fb357610fab60056002836020015161259356' + - '5b9150506109ba565b610fbb6125f9565b60608201819052600a54610fcf91906125fd56' + - '5b6080830181905282826003811115610fe357fe5b6003811115610fee57fe5b90525060' + - '0090508151600381111561100257fe5b1461100957fe5b61102960405180602001604052' + - '8083604001518152508260800151612620565b60a083018190528282600381111561103d' + - '57fe5b600381111561104857fe5b905250600090508151600381111561105c57fe5b1461' + - '107d57610fab600960068360000151600381111561107857fe5b612593565b61108d8160' + - 'a00151600c546121a6565b60c08301819052828260038111156110a157fe5b6003811115' + - '6110ac57fe5b90525060009050815160038111156110c057fe5b146110dc57610fab6009' + - '60018360000151600381111561107857fe5b6110ec8160c00151600c54612688565b60e0' + - '83018190528282600381111561110057fe5b600381111561110b57fe5b90525060009050' + - '8151600381111561111f57fe5b1461113b57610fab600960048360000151600381111561' + - '107857fe5b61115c60405180602001604052806009548152508260c00151600d546126ae' + - '565b61010083018190528282600381111561117157fe5b600381111561117c57fe5b9052' + - '50600090508151600381111561119057fe5b146111ac57610fab60096005836000015160' + - '0381111561107857fe5b6111bf8160a00151600b54600b546126ae565b61012083018190' + - '52828260038111156111d457fe5b60038111156111df57fe5b9052506000905081516003' + - '8111156111f357fe5b1461120f57610fab600960038360000151600381111561107857fe' + - '5b606080820151600a55610120820151600b81905560e0830151600c8190556101008401' + - '51600d5560c08401516040805191825260208201939093528083019190915290517f8753' + - '52fb3fadeb8c0be7cbbe8ff761b308fa7033470cd0287f02f3436fd76cb9929181900390' + - '910190a1600091505090565b600080546001018082558161129d33338787611e02565b14' + - '91505b60005481146112ea5760408051600160e51b62461bcd0281526020600482015260' + - '0a6024820152600160b21b691c994b595b9d195c99590260448201529051908190036064' + - '0190fd5b5092915050565b600b5481565b600080611302610957565b6007549091506000' + - '9081906001600160a01b03166315f240536113236121fa565b600c54600d546040518463' + - 'ffffffff1660e01b81526004018084815260200183815260200182815260200193505050' + - '50604080518083038186803b15801561136a57600080fd5b505afa15801561137e573d60' + - '00803e3d6000fd5b505050506040513d604081101561139457600080fd5b508051602090' + - '910151909250905081156113e257604051600160e51b62461bcd02815260040180806020' + - '01828103825260318152602001806148d56031913960400191505060405180910390fd5b' + - '60006113ec6146bb565b611406604051806020016040528087815250600e54612620565b' + - '9092509050600082600381111561141957fe5b1461145857604051600160e51b62461bcd' + - '02815260040180806020018281038252603181526020018061486d603191396040019150' + - '5060405180910390fd5b60006114626146bb565b61146e600c548461270a565b90925090' + - '50600082600381111561148157fe5b146114c057604051600160e51b62461bcd02815260' + - '04018080602001828103825260318152602001806147b160319139604001915050604051' + - '80910390fd5b60006114ca6146bb565b6114fa6040518060200160405280670de0b6b3a7' + - '6400008152506040518060200160405280600954815250612769565b9092509050600082' + - '600381111561150d57fe5b1461154c57604051600160e51b62461bcd0281526004018080' + - '6020018281038252603c815260200180614926603c913960400191505060405180910390' + - 'fd5b60006115566146bb565b61156f60405180602001604052808b81525084876127a356' + - '5b9092509050600082600381111561158257fe5b146115c157604051600160e51b62461b' + - 'cd0281526004018080602001828103825260318152602001806148056031913960400191' + - '505060405180910390fd5b519a505050505050505050505090565b600080546001018082' + - '5560065460408051600160e01b63d02f7351028152306004820152336024820152600160' + - '0160a01b0388811660448301528781166064830152608482018790529151859392909216' + - '9163d02f73519160a48082019260209290919082900301818787803b15801561164a5760' + - '0080fd5b505af115801561165e573d6000803e3d6000fd5b505050506040513d60208110' + - '1561167457600080fd5b5051905080156116935761168b6003601b83612593565b925050' + - '6109d8565b856001600160a01b0316856001600160a01b031614156116b95761168b6006' + - '601c61227d565b6001600160a01b0385166000908152600f602052604081205481908190' + - '6116e090886125fd565b909350915060008360038111156116f357fe5b14611716576117' + - '0b6009601a85600381111561107857fe5b9550505050506109d8565b6001600160a01b03' + - '89166000908152600f60205260409020546117399088612688565b909350905060008360' + - '0381111561174c57fe5b146117645761170b6009601985600381111561107857fe5b6001' + - '600160a01b038089166000818152600f60209081526040808320879055938d1680835291' + - '84902085905583518b815293519193600080516020614906833981519152929081900390' + - '910190a360065460408051600160e01b636d35bf91028152306004820152336024820152' + - '6001600160a01b038c811660448301528b81166064830152608482018b90529151919092' + - '1691636d35bf919160a480830192600092919082900301818387803b15801561181e5760' + - '0080fd5b505af1158015611832573d6000803e3d6000fd5b506000925061183f91505056' + - '5b9550505050506000548114610a215760408051600160e51b62461bcd02815260206004' + - '820152600a6024820152600160b21b691c994b595b9d195c995902604482015290519081' + - '900360640190fd5b6004546000906001600160a01b031633146118af57610aef60016045' + - '61227d565b600580546001600160a01b038481166001600160a01b031983168117909355' + - '6040805191909216808252602082019390935281517fca4f2f25d0898edd99413412fb94' + - '012f9e54ec8142f9b093e7720646a95b16a9929181900390910190a16000610a35565b60' + - '00805460010180825581611928610e8a565b1461197d5760408051600160e51b62461bcd' + - '02815260206004820152601660248201527f61636372756520696e746572657374206661' + - '696c656400000000000000000000604482015290519081900360640190fd5b6119856109' + - '57565b91506000548114610db25760408051600160e51b62461bcd028152602060048201' + - '52600a6024820152600160b21b691c994b595b9d195c9959026044820152905190819003' + - '60640190fd5b6001600160a01b0381166000908152600f60205260408120548190819081' + - '908180806119fb896124a4565b935090506000816003811115611a0d57fe5b14611a2b57' + - '60095b975060009650869550859450611a5e9350505050565b611a33611d54565b925090' + - '506000816003811115611a4557fe5b14611a51576009611a15565b506000965091945092' + - '5090505b9193509193565b6000610880826127ed565b600061088082612828565b600160' + - '0160a01b0391821660009081526010602090815260408083209390941682529190915220' + - '5490565b6005546000906001600160a01b031633141580611ac1575033155b15611ad957' + - '611ad26001600061227d565b90506109ba565b60048054600580546001600160a01b0380' + - '82166001600160a01b031980861682179687905590921690925560408051938316808552' + - '949092166020840152815190927ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f' + - '21c4e8146d8519b417dc92908290030190a1600554604080516001600160a01b03808516' + - '8252909216602083015280517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b0' + - '93e7720646a95b16a99281900390910190a160009250505090565b600080611ba0610e8a' + - '565b90508015611bc657611bbe816010811115611bb757fe5b604061227d565b91505061' + - '0883565b610a358361285e565b6007546001600160a01b031681565b6000610ab7848484' + - '6129d1565b6004546001600160a01b031681565b600754600090819081906001600160a0' + - '1b03166315f24053611c1a6121fa565b600c54600d546040518463ffffffff1660e01b81' + - '526004018084815260200183815260200182815260200193505050506040805180830381' + - '86803b158015611c6157600080fd5b505afa158015611c75573d6000803e3d6000fd5b50' + - '5050506040513d6040811015611c8b57600080fd5b508051602090910151909250905081' + - '156109b657604051600160e51b62461bcd02815260040180806020018281038252603781' + - '526020018061489e6037913960400191505060405180910390fd5b600080546001018082' + - '5581611cec610e8a565b90508015611d0a57610c69816010811115611d0357fe5b604661' + - '227d565b610c7a84612adf565b600181565b6000805460010180825581611d2b610e8a56' + - '5b90508015611d4957610c69816010811115611d4257fe5b603661227d565b610c7a3333' + - '86612b82565b600080600e5460001415611d6f575050600854600090611dfe565b600061' + - '1d796121fa565b90506000611d856146bb565b6000611d9684600c54600d54612fde565b' + - '935090506000816003811115611da857fe5b14611dbc57945060009350611dfe92505050' + - '565b611dc883600e5461301c565b925090506000816003811115611dda57fe5b14611dee' + - '57945060009350611dfe92505050565b5051600094509250611dfe915050565b9091565b' + - '60065460408051600160e31b6317b9b84b0281523060048201526001600160a01b038681' + - '16602483015285811660448301526064820185905291516000938493169163bdcdc25891' + - '608480830192602092919082900301818787803b158015611e6a57600080fd5b505af115' + - '8015611e7e573d6000803e3d6000fd5b505050506040513d6020811015611e9457600080' + - 'fd5b505190508015611eb357611eab6003604a83612593565b915050610ab7565b836001' + - '600160a01b0316856001600160a01b03161415611ed957611eab6002604b61227d565b60' + - '006001600160a01b038781169087161415611ef85750600019611f20565b506001600160' + - 'a01b038086166000908152601060209081526040808320938a16835292905220545b6000' + - '80600080611f3085896125fd565b90945092506000846003811115611f4357fe5b14611f' + - '6157611f546009604b61227d565b9650505050505050610ab7565b6001600160a01b038a' + - '166000908152600f6020526040902054611f8490896125fd565b90945091506000846003' + - '811115611f9757fe5b14611fa857611f546009604c61227d565b6001600160a01b038916' + - '6000908152600f6020526040902054611fcb9089612688565b9094509050600084600381' + - '1115611fde57fe5b14611fef57611f546009604d61227d565b6001600160a01b03808b16' + - '6000908152600f6020526040808220859055918b16815220819055600019851461204757' + - '6001600160a01b03808b166000908152601060209081526040808320938f168352929052' + - '208390555b886001600160a01b03168a6001600160a01b03166000805160206149068339' + - '815191528a6040518082815260200191505060405180910390a360065460408051600160' + - 'e11b63352b4a3f0281523060048201526001600160a01b038d811660248301528c811660' + - '44830152606482018c905291519190921691636a56947e91608480830192600092919082' + - '900301818387803b1580156120e657600080fd5b505af11580156120fa573d6000803e3d' + - '6000fd5b5060009250612107915050565b9b9a5050505050505050505050565b60008054' + - '60010180825581612129610e8a565b9050801561214f5761214781601081111561214057' + - 'fe5b603561227d565b9250506112a1565b61215a338686612b82565b9250506000548114' + - '6112ea5760408051600160e51b62461bcd02815260206004820152600a60248201526001' + - '60b21b691c994b595b9d195c995902604482015290519081900360640190fd5b60008060' + - '006121b36146bb565b6121bd8686612620565b909250905060008260038111156121d057' + - 'fe5b146121e157509150600090506121f3565b60006121ec826130cc565b935093505050' + - '5b9250929050565b60125460408051600160e01b6370a082310281523060048201529051' + - '6000926001600160a01b03169182916370a0823191602480820192602092909190829003' + - '018186803b15801561224b57600080fd5b505afa15801561225f573d6000803e3d6000fd' + - '5b505050506040513d602081101561227557600080fd5b505191505090565b60007f45b9' + - '6fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0836010811115' + - '6122ac57fe5b83604d8111156122b857fe5b604080519283526020830191909152600082' + - '820152519081900360600190a1826010811115610a3557fe5b6004546000908190819060' + - '01600160a01b03163314612311576123086001603161227d565b92505050610883565b61' + - '23196125f9565b600a541461232d57612308600a603361227d565b836123366121fa565b' + - '101561234857612308600e603261227d565b600d5484111561235e576123086002603461' + - '227d565b50600d54838103908111156123a757604051600160e51b62461bcd0281526004' + - '018080602001828103825260248152602001806149cb6024913960400191505060405180' + - '910390fd5b600d8190556004546123c2906001600160a01b0316856130db565b91506000' + - '8260108111156123d257fe5b1461241157604051600160e51b62461bcd02815260040180' + - '80602001828103825260238152602001806147e260239139604001915050604051809103' + - '90fd5b600454604080516001600160a01b03909216825260208201869052818101839052' + - '517f3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e9181' + - '900360600190a16000949350505050565b600080546001018082558161247a610e8a565b' + - '9050801561249857610c6981601081111561249157fe5b602761227d565b610c7a336000' + - '8661319a565b6001600160a01b0381166000908152601160205260408120805482918291' + - '829182916124db57506000945084935061255392505050565b6124eb8160000154600b54' + - '6136af565b909450925060008460038111156124fe57fe5b146125135750919350600092' + - '50612553915050565b6125218382600101546136ee565b90945091506000846003811115' + - '61253457fe5b14612549575091935060009250612553915050565b506000945092505050' + - '5b915091565b600080546001018082558161256b610e8a565b9050801561258957610c69' + - '81601081111561258257fe5b601e61227d565b610c7a3385613719565b60007f45b96fe4' + - '42630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08460108111156125' + - 'c257fe5b84604d8111156125ce57fe5b6040805192835260208301919091528181018590' + - '52519081900360600190a1836010811115610ab757fe5b4390565b600080838311612614' + - '5750600090508183036121f3565b506003905060006121f3565b600061262a6146bb565b' + - '60008061263b8660000151866136af565b9092509050600082600381111561264e57fe5b' + - '1461266d575060408051602081019091526000815290925090506121f3565b6040805160' + - '2081019091529081526000969095509350505050565b6000808383018481106126a05760' + - '00925090506121f3565b5060029150600090506121f3565b60008060006126bb6146bb56' + - '5b6126c58787612620565b909250905060008260038111156126d857fe5b146126e95750' + - '915060009050612702565b6126fb6126f5826130cc565b86612688565b9350935050505b' + - '935093915050565b60006127146146bb565b600080612729670de0b6b3a7640000876136' + - 'af565b9092509050600082600381111561273c57fe5b1461275b57506040805160208101' + - '9091526000815290925090506121f3565b6121ec81866000015161301c565b6000612773' + - '6146bb565b600080612788866000015186600001516125fd565b60408051602081019091' + - '529081529097909650945050505050565b60006127ad6146bb565b60006127b76146bb56' + - '5b6127c18787613b67565b909250905060008260038111156127d457fe5b146127e35790' + - '92509050612702565b6126fb8186613b67565b6000805460010180825581612800610e8a' + - '565b9050801561281e57610c6981601081111561281757fe5b600861227d565b610c7a33' + - '85613c50565b600080546001018082558161283b610e8a565b9050801561285257610c69' + - '81601081111561249157fe5b610c7a3385600061319a565b600454600090819060016001' + - '60a01b0316331461288157611bbe6001604261227d565b6128896125f9565b600a541461' + - '289d57611bbe600a604161227d565b600760009054906101000a90046001600160a01b03' + - '169050826001600160a01b0316632191f92a6040518163ffffffff1660e01b8152600401' + - '60206040518083038186803b1580156128ee57600080fd5b505afa158015612902573d60' + - '00803e3d6000fd5b505050506040513d602081101561291857600080fd5b505161296e57' + - '60408051600160e51b62461bcd02815260206004820152601c60248201527f6d61726b65' + - '72206d6574686f642072657475726e65642066616c736500000000604482015290519081' + - '900360640190fd5b600780546001600160a01b0319166001600160a01b03858116918217' + - '909255604080519284168352602083019190915280517fedffc32e068c7c95dfd4bdfd5c' + - '4d939a084d6b11c4199eac8436ed234d72f9269281900390910190a16000610a35565b60' + - '008054600101808255816129e4610e8a565b90508015612a025761168b81601081111561' + - '29fb57fe5b600f61227d565b836001600160a01b031663a6afed956040518163ffffffff' + - '1660e01b8152600401602060405180830381600087803b158015612a3d57600080fd5b50' + - '5af1158015612a51573d6000803e3d6000fd5b505050506040513d6020811015612a6757' + - '600080fd5b505190508015612a875761168b816010811115612a8057fe5b601061227d56' + - '5b612a9333878787613fbf565b9250506000548114610a215760408051600160e51b6246' + - '1bcd02815260206004820152600a6024820152600160b21b691c994b595b9d195c995902' + - '604482015290519081900360640190fd5b6004546000906001600160a01b03163314612b' + - '0057610aef6001604761227d565b612b086125f9565b600a5414612b1c57610aef600a60' + - '4861227d565b670de0b6b3a7640000821115612b3857610aef6002604961227d565b6009' + - '805490839055604080518281526020810185905281517faaa68312e2ea9d50e16af50684' + - '10ab56e1a1fd06037b1a35664812c30f821460929181900390910190a16000610a35565b' + - '60065460408051600160e11b63120045310281523060048201526001600160a01b038681' + - '1660248301528581166044830152606482018590529151600093849316916324008a6291' + - '608480830192602092919082900301818787803b158015612bea57600080fd5b505af115' + - '8015612bfe573d6000803e3d6000fd5b505050506040513d6020811015612c1457600080' + - 'fd5b505190508015612c3357612c2b6003603883612593565b915050610a35565b612c3b' + - '6125f9565b600a5414612c4f57612c2b600a603961227d565b612c57614728565b600160' + - '0160a01b0385166000908152601160205260409020600101546060820152612c81856124' + - 'a4565b6080830181905260208301826003811115612c9857fe5b6003811115612ca357fe' + - '5b9052506000905081602001516003811115612cba57fe5b14612cdf57612cd660096037' + - '8360200151600381111561107857fe5b92505050610a35565b600019841415612cf85760' + - '808101516040820152612d00565b604081018490525b612d0e8682604001516144b3565b' + - '81906010811115612d1b57fe5b90816010811115612d2857fe5b90525060008151601081' + - '1115612d3a57fe5b14612d4c578051612cd690603c61227d565b612d5e81608001518260' + - '4001516125fd565b60a0830181905260208301826003811115612d7557fe5b6003811115' + - '612d8057fe5b9052506000905081602001516003811115612d9757fe5b14612db357612c' + - 'd66009603a8360200151600381111561107857fe5b612dc3600c5482604001516125fd56' + - '5b60c0830181905260208301826003811115612dda57fe5b6003811115612de557fe5b90' + - '52506000905081602001516003811115612dfc57fe5b14612e1857612cd66009603b8360' + - '200151600381111561107857fe5b612e268682604001516145ea565b8190601081111561' + - '2e3357fe5b90816010811115612e4057fe5b905250600081516010811115612e5257fe5b' + - '14612ea75760408051600160e51b62461bcd02815260206004820152601f60248201527f' + - '726570617920626f72726f77207472616e7366657220696e206661696c65640060448201' + - '5290519081900360640190fd5b60a080820180516001600160a01b038089166000818152' + - '60116020908152604091829020948555600b5460019095019490945560c0870151600c81' + - '90558188015195518251948e168552948401929092528281019490945260608201929092' + - '52608081019190915290517f1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0' + - '355478d6f5c362a1929181900390910190a1600654604080830151606084015182516001' + - '60e01b631ededc910281523060048201526001600160a01b038b811660248301528a8116' + - '6044830152606482019390935260848101919091529151921691631ededc919160a48082' + - '019260009290919082900301818387803b158015612fb357600080fd5b505af115801561' + - '2fc7573d6000803e3d6000fd5b5060009250612fd4915050565b9695505050505050565b' + - '600080600080612fee8787612688565b9092509050600082600381111561300157fe5b14' + - '6130125750915060009050612702565b6126fb81866125fd565b60006130266146bb565b' + - '60008061303b86670de0b6b3a76400006136af565b909250905060008260038111156130' + - '4e57fe5b1461306d575060408051602081019091526000815290925090506121f3565b60' + - '008061307a83886136ee565b9092509050600082600381111561308d57fe5b146130af57' + - '5060408051602081019091526000815290945092506121f3915050565b60408051602081' + - '0190915290815260009890975095505050505050565b51670de0b6b3a764000090049056' + - '5b60125460408051600160e01b63a9059cbb0281526001600160a01b0385811660048301' + - '5260248201859052915160009392909216918391839163a9059cbb916044808201928692' + - '90919082900301818387803b15801561313a57600080fd5b505af115801561314e573d60' + - '00803e3d6000fd5b505050503d60008114613168576020811461317257600080fd5b6000' + - '19915061317e565b60206000803e60005191505b508061318f5760109250505061086f56' + - '5b506000949350505050565b60008215806131a7575081155b6131e557604051600160e5' + - '1b62461bcd02815260040180806020018281038252603481526020018061499760349139' + - '60400191505060405180910390fd5b6131ed614728565b6131f5611d54565b6040830181' + - '90526020830182600381111561320c57fe5b600381111561321757fe5b90525060009050' + - '8160200151600381111561322e57fe5b1461324a57612c2b6009602b8360200151600381' + - '111561107857fe5b83156132cb5760608101849052604080516020810182529082015181' + - '5261327190856121a6565b608083018190526020830182600381111561328857fe5b6003' + - '81111561329357fe5b90525060009050816020015160038111156132aa57fe5b146132c6' + - '57612c2b600960298360200151600381111561107857fe5b613344565b6132e783604051' + - '806020016040528084604001518152506146a4565b606083018190526020830182600381' + - '11156132fe57fe5b600381111561330957fe5b9052506000905081602001516003811115' + - '61332057fe5b1461333c57612c2b6009602a8360200151600381111561107857fe5b6080' + - '81018390525b600654606082015160408051600160e01b63eabe7d910281523060048201' + - '526001600160a01b03898116602483015260448201939093529051600093929092169163' + - 'eabe7d919160648082019260209290919082900301818787803b1580156133ac57600080' + - 'fd5b505af11580156133c0573d6000803e3d6000fd5b505050506040513d602081101561' + - '33d657600080fd5b5051905080156133ed57612cd66003602883612593565b6133f56125' + - 'f9565b600a541461340957612cd6600a602c61227d565b613419600e5483606001516125' + - 'fd565b60a084018190526020840182600381111561343057fe5b600381111561343b57fe' + - '5b905250600090508260200151600381111561345257fe5b1461346e57612cd66009602e' + - '8460200151600381111561107857fe5b6001600160a01b0386166000908152600f602052' + - '6040902054606083015161349691906125fd565b60c08401819052602084018260038111' + - '156134ad57fe5b60038111156134b857fe5b905250600090508260200151600381111561' + - '34cf57fe5b146134eb57612cd66009602d8460200151600381111561107857fe5b816080' + - '01516134f86121fa565b101561350a57612cd6600e602f61227d565b6135188683608001' + - '516130db565b8290601081111561352557fe5b9081601081111561353257fe5b90525060' + - '008251601081111561354457fe5b146135995760408051600160e51b62461bcd02815260' + - '206004820152601a60248201527f72656465656d207472616e73666572206f7574206661' + - '696c6564000000000000604482015290519081900360640190fd5b60a0820151600e5560' + - 'c08201516001600160a01b0387166000818152600f602090815260409182902093909355' + - '6060850151815190815290513093600080516020614906833981519152928290030190a3' + - '6080820151606080840151604080516001600160a01b038b168152602081019490945283' + - '810191909152517fe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4' + - 'ec31a9299281900390910190a16006546080830151606084015160408051600160e01b63' + - '51dff9890281523060048201526001600160a01b038b8116602483015260448201949094' + - '5260648101929092525191909216916351dff98991608480830192600092919082900301' + - '818387803b158015612fb357600080fd5b600080836136c2575060009050806121f3565b' + - '838302838582816136cf57fe5b04146136e3575060029150600090506121f3565b600092' + - '5090506121f3565b6000808261370257506001905060006121f3565b600083858161370d' + - '57fe5b04915091509250929050565b60065460408051600160e01b634ef4c3e102815230' + - '60048201526001600160a01b038581166024830152604482018590529151600093849316' + - '91634ef4c3e191606480830192602092919082900301818787803b158015613779576000' + - '80fd5b505af115801561378d573d6000803e3d6000fd5b505050506040513d6020811015' + - '6137a357600080fd5b5051905080156137c2576137ba6003601f83612593565b91505061' + - '086f565b6137ca6125f9565b600a54146137de576137ba600a602261227d565b6137e661' + - '4766565b6137f085856144b3565b819060108111156137fd57fe5b908160108111156138' + - '0a57fe5b90525060008151601081111561381c57fe5b1461383757805161382e90602661' + - '227d565b9250505061086f565b61383f611d54565b604083018190526020830182600381' + - '111561385657fe5b600381111561386157fe5b9052506000905081602001516003811115' + - '61387857fe5b146138945761382e600960218360200151600381111561107857fe5b6138' + - 'b084604051806020016040528084604001518152506146a4565b60608301819052602083' + - '018260038111156138c757fe5b60038111156138d257fe5b905250600090508160200151' + - '60038111156138e957fe5b146139055761382e6009602083602001516003811115611078' + - '57fe5b613915600e548260600151612688565b6080830181905260208301826003811115' + - '61392c57fe5b600381111561393757fe5b90525060009050816020015160038111156139' + - '4e57fe5b1461396a5761382e600960248360200151600381111561107857fe5b60016001' + - '60a01b0385166000908152600f602052604090205460608201516139929190612688565b' + - '60a08301819052602083018260038111156139a957fe5b60038111156139b457fe5b9052' + - '5060009050816020015160038111156139cb57fe5b146139e75761382e60096023836020' + - '0151600381111561107857fe5b6139f185856145ea565b819060108111156139fe57fe5b' + - '90816010811115613a0b57fe5b905250600081516010811115613a1d57fe5b14613a2f57' + - '805161382e90602561227d565b6080810151600e5560a08101516001600160a01b038616' + - '6000818152600f6020908152604091829020939093556060808501518251938452938301' + - '88905282820193909352517f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef' + - '26394f4c03821c4f929181900390910190a1606081015160408051918252516001600160' + - 'a01b0387169130916000805160206149068339815191529181900360200190a360065460' + - '6082015160408051600160e01b6341c728b90281523060048201526001600160a01b0389' + - '81166024830152604482018990526064820193909352905191909216916341c728b99160' + - '8480830192600092919082900301818387803b158015613b3d57600080fd5b505af11580' + - '15613b51573d6000803e3d6000fd5b5060009250613b5e915050565b9594505050505056' + - '5b6000613b716146bb565b600080613b86866000015186600001516136af565b90925090' + - '506000826003811115613b9957fe5b14613bb85750604080516020810190915260008152' + - '90925090506121f3565b600080613bcd6706f05b59d3b2000084612688565b9092509050' + - '6000826003811115613be057fe5b14613c02575060408051602081019091526000815290' + - '945092506121f3915050565b600080613c1783670de0b6b3a76400006136ee565b909250' + - '90506000826003811115613c2a57fe5b14613c3157fe5b60408051602081019091529081' + - '5260009a909950975050505050505050565b60065460408051600160e21b63368f515302' + - '81523060048201526001600160a01b038581166024830152604482018590529151600093' + - '8493169163da3d454c91606480830192602092919082900301818787803b158015613cb0' + - '57600080fd5b505af1158015613cc4573d6000803e3d6000fd5b505050506040513d6020' + - '811015613cda57600080fd5b505190508015613cf1576137ba6003600e83612593565b61' + - '3cf96125f9565b600a5414613d0c576137ba600a8061227d565b82613d156121fa565b10' + - '15613d27576137ba600e600961227d565b613d2f614780565b613d38856124a4565b6040' + - '830181905260208301826003811115613d4f57fe5b6003811115613d5a57fe5b90525060' + - '00905081602001516003811115613d7157fe5b14613d8d5761382e600960078360200151' + - '600381111561107857fe5b613d9b816040015185612688565b6060830181905260208301' + - '826003811115613db257fe5b6003811115613dbd57fe5b90525060009050816020015160' + - '03811115613dd457fe5b14613df05761382e6009600c8360200151600381111561107857' + - 'fe5b613dfc600c5485612688565b6080830181905260208301826003811115613e1357fe' + - '5b6003811115613e1e57fe5b9052506000905081602001516003811115613e3557fe5b14' + - '613e515761382e6009600b8360200151600381111561107857fe5b613e5b85856130db56' + - '5b81906010811115613e6857fe5b90816010811115613e7557fe5b905250600081516010' + - '811115613e8757fe5b14613edc5760408051600160e51b62461bcd028152602060048201' + - '52601a60248201527f626f72726f77207472616e73666572206f7574206661696c656400' + - '0000000000604482015290519081900360640190fd5b606080820180516001600160a01b' + - '038816600081815260116020908152604091829020938455600b54600190940193909355' + - '608080870151600c819055945182519384529383018a9052828201939093529381019290' + - '925291517f13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab' + - '80929181900390910190a160065460408051600160e01b635c7786050281523060048201' + - '526001600160a01b0388811660248301526044820188905291519190921691635c778605' + - '91606480830192600092919082900301818387803b158015613b3d57600080fd5b600654' + - '60408051600160e11b632fe3f38f0281523060048201526001600160a01b038481166024' + - '830152878116604483015286811660648301526084820186905291516000938493169163' + - '5fc7e71e9160a480830192602092919082900301818787803b15801561402f57600080fd' + - '5b505af1158015614043573d6000803e3d6000fd5b505050506040513d60208110156140' + - '5957600080fd5b50519050801561407057611eab6003601283612593565b6140786125f9' + - '565b600a541461408c57611eab600a601661227d565b6140946125f9565b836001600160' + - 'a01b0316636c540baf6040518163ffffffff1660e01b8152600401602060405180830381' + - '86803b1580156140cd57600080fd5b505afa1580156140e1573d6000803e3d6000fd5b50' + - '5050506040513d60208110156140f757600080fd5b50511461410a57611eab600a601161' + - '227d565b856001600160a01b0316856001600160a01b0316141561413057611eab600660' + - '1761227d565b8361414157611eab6007601561227d565b60001984141561415757611eab' + - '6007601461227d565b60065460408051600160e01b63c488847b02815230600482015260' + - '01600160a01b038681166024830152604482018890528251600094859492169263c48884' + - '7b926064808301939192829003018186803b1580156141b457600080fd5b505afa158015' + - '6141c8573d6000803e3d6000fd5b505050506040513d60408110156141de57600080fd5b' + - '50805160209091015190925090508115614209576141ff6004601384612593565b935050' + - '5050610ab7565b846001600160a01b03166370a08231886040518263ffffffff1660e01b' + - '815260040180826001600160a01b03166001600160a01b03168152602001915050602060' + - '40518083038186803b15801561425f57600080fd5b505afa158015614273573d6000803e' + - '3d6000fd5b505050506040513d602081101561428957600080fd5b505181111561429e57' + - '6141ff600d601d61227d565b60006142ab898989612b82565b905080156142d4576142c9' + - '8160108111156142c257fe5b601861227d565b945050505050610ab7565b604080516001' + - '60e01b63b2a02ff10281526001600160a01b038b811660048301528a8116602483015260' + - '448201859052915160009289169163b2a02ff19160648083019260209291908290030181' + - '8787803b15801561433257600080fd5b505af1158015614346573d6000803e3d6000fd5b' + - '505050506040513d602081101561435c57600080fd5b5051905080156143b65760408051' + - '600160e51b62461bcd02815260206004820152601460248201527f746f6b656e20736569' + - '7a757265206661696c656400000000000000000000000060448201529051908190036064' + - '0190fd5b604080516001600160a01b03808d168252808c1660208301528183018b905289' + - '1660608201526080810185905290517f298637f684da70674f26509b10f07ec2fbc77a33' + - '5ab1e7d6215a4b2484d8bb529181900360a00190a160065460408051600160e01b6347ef' + - '3b3b0281523060048201526001600160a01b038a811660248301528d811660448301528c' + - '81166064830152608482018c905260a48201879052915191909216916347ef3b3b9160c4' + - '80830192600092919082900301818387803b15801561448457600080fd5b505af1158015' + - '614498573d6000803e3d6000fd5b50600092506144a5915050565b9a9950505050505050' + - '505050565b60125460408051600160e11b636eb1769f0281526001600160a01b03858116' + - '6004830152306024830152915160009392909216918491839163dd62ed3e916044808201' + - '92602092909190829003018186803b15801561451157600080fd5b505afa158015614525' + - '573d6000803e3d6000fd5b505050506040513d602081101561453b57600080fd5b505110' + - '1561454d57600c91505061086f565b82816001600160a01b03166370a082318660405182' + - '63ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152' + - '60200191505060206040518083038186803b1580156145a457600080fd5b505afa158015' + - '6145b8573d6000803e3d6000fd5b505050506040513d60208110156145ce57600080fd5b' + - '505110156145e057600d91505061086f565b5060009392505050565b6012546040805160' + - '0160e01b6323b872dd0281526001600160a01b0385811660048301523060248301526044' + - '820185905291516000939290921691839183916323b872dd916064808201928692909190' + - '82900301818387803b15801561464f57600080fd5b505af1158015614663573d6000803e' + - '3d6000fd5b505050503d6000811461467d576020811461468757600080fd5b6000199150' + - '614693565b60206000803e60005191505b508061318f57600f9250505061086f565b6000' + - '8060006146b16146bb565b6121bd868661270a565b604051806020016040528060008152' + - '5090565b6040805161014081019091528060008152602001600081526020016000815260' + - '200160008152602001600081526020016147066146bb565b815260200160008152602001' + - '6000815260200160008152602001600081525090565b6040805160e08101909152806000' + - '815260200160008152602001600081526020016000815260200160008152602001600081' + - '52602001600081525090565b6040805160c0810190915280600081526020016000614706' + - '565b6040805160a081019091528060008152602001600081526020016000815260200160' + - '00815260200160008152509056fe737570706c7952617465506572426c6f636b3a206361' + - '6c63756c6174696e6720626f72726f7773506572206661696c6564726564756365207265' + - '736572766573207472616e73666572206f7574206661696c6564737570706c7952617465' + - '506572426c6f636b3a2063616c63756c6174696e6720737570706c795261746520666169' + - '6c6564626f72726f7742616c616e636553746f7265643a20626f72726f7742616c616e63' + - '6553746f726564496e7465726e616c206661696c6564737570706c795261746550657242' + - '6c6f636b3a2063616c63756c6174696e6720756e6465726c79696e67206661696c656462' + - '6f72726f7752617465506572426c6f636b3a20696e746572657374526174654d6f64656c' + - '2e626f72726f7752617465206661696c6564737570706c7952617465506572426c6f636b' + - '3a2063616c63756c6174696e6720626f72726f7752617465206661696c6564ddf252ad1b' + - 'e2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef737570706c79526174' + - '65506572426c6f636b3a2063616c63756c6174696e67206f6e654d696e75735265736572' + - '7665466163746f72206661696c656465786368616e67655261746553746f7265643a2065' + - '786368616e67655261746553746f726564496e7465726e616c206661696c65646f6e6520' + - '6f662072656465656d546f6b656e73496e206f722072656465656d416d6f756e74496e20' + - '6d757374206265207a65726f72656475636520726573657276657320756e657870656374' + - '656420756e646572666c6f77a165627a7a72305820ae92d0e3e70b657d01891c7457bc6c' + - '8a5ce2401a1a8857f346a2fa9af4627145002953657474696e6720696e74657265737420' + - '72617465206d6f64656c206661696c6564496e697469616c2065786368616e6765207261' + - '7465206d7573742062652067726561746572207468616e207a65726f2e' + - '00000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359' + // dai - '0000000000000000000000003d9819210a31b4961b30ef54be2aed79b9c9cd3b' + // troll - '000000000000000000000000a1046abfc2598f48c44fb320d281d3f3c0733c9a' + // IRM - '000000000000000000000000000000000000000000a56fa5b99019a5c8000000' + - '00000000000000000000000000000000000000000000000000000000000000e0' + - '0000000000000000000000000000000000000000000000000000000000000120' + - '0000000000000000000000000000000000000000000000000000000000000008' + - '000000000000000000000000000000000000000000000000000000000000000c' + - '436f6d706f756e64204461690000000000000000000000000000000000000000' + - '0000000000000000000000000000000000000000000000000000000000000004' + - '6344414900000000000000000000000000000000000000000000000000000000' - ) - - // 0x39AA39c021dfbaE8faC545936693aC917d5E7563 - // nonce: 17 - const mockCUSDCDeploymentData = ( - '0x60806040523480156200001157600080fd5b506040516200523c3803806200523c8339' + - '81018060405260e08110156200003757600080fd5b815160208301516040840151606085' + - '0151608086018051949693959294919392830192916401000000008111156200006e5760' + - '0080fd5b820160208101848111156200008257600080fd5b815164010000000081118282' + - '01871017156200009d57600080fd5b505092919060200180516401000000008111156200' + - '00ba57600080fd5b82016020810184811115620000ce57600080fd5b8151640100000000' + - '811182820187101715620000e957600080fd5b5050602090910151600160005560048054' + - '6001600160a01b0319163317905560088690559092509050858585858585836200017057' + - '6040517f08c379a000000000000000000000000000000000000000000000000000000000' + - '81526004018080602001828103825260308152602001806200520c603091396040019150' + - '5060405180910390fd5b600062000183876200036460201b60201c565b90508015620001' + - 'f357604080517f08c379a000000000000000000000000000000000000000000000000000' + - '000000815260206004820152601a60248201527f53657474696e6720636f6d7074726f6c' + - '6c6572206661696c6564000000000000604482015290519081900360640190fd5b620002' + - '03620004f760201b60201c565b600a55670de0b6b3a7640000600b556200022486620004' + - 'fc602090811b901c565b905080156200027f576040517f08c379a0000000000000000000' + - '000000000000000000000000000000000000008152600401808060200182810382526022' + - '815260200180620051ea6022913960400191505060405180910390fd5b83516200029490' + - '60019060208701906200071e565b508251620002aa9060029060208601906200071e565b' + - '50506003555050601280546001600160a01b0319166001600160a01b038c811691909117' + - '91829055604080517f18160ddd0000000000000000000000000000000000000000000000' + - '0000000000815290519290911694506318160ddd93506004808201935060209291829003' + - '018186803b1580156200032857600080fd5b505afa1580156200033d573d6000803e3d60' + - '00fd5b505050506040513d60208110156200035457600080fd5b50620007c09750505050' + - '50505050565b6004546000906001600160a01b0316331462000396576200038e6001603f' + - '620006ae60201b60201c565b9050620004f2565b600654604080517e7e3dd20000000000' + - '0000000000000000000000000000000000000000000000815290516001600160a01b0392' + - '831692851691627e3dd2916004808301926020929190829003018186803b158015620003' + - 'f557600080fd5b505afa1580156200040a573d6000803e3d6000fd5b505050506040513d' + - '60208110156200042157600080fd5b50516200048f57604080517f08c379a00000000000' + - '0000000000000000000000000000000000000000000000815260206004820152601c6024' + - '8201527f6d61726b6572206d6574686f642072657475726e65642066616c736500000000' + - '604482015290519081900360640190fd5b600680546001600160a01b0319166001600160' + - 'a01b03858116918217909255604080519284168352602083019190915280517f7ac369db' + - 'd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d9281900390910190' + - 'a160005b9150505b919050565b435b90565b60045460009081906001600160a01b031633' + - '1462000531576200052860016042620006ae60201b60201c565b915050620004f2565b62' + - '000541620004f760201b60201c565b600a54146200055e5762000528600a6041620006ae' + - '60201b60201c565b600760009054906101000a90046001600160a01b0316905082600160' + - '0160a01b0316632191f92a6040518163ffffffff1660e01b815260040160206040518083' + - '038186803b158015620005b057600080fd5b505afa158015620005c5573d6000803e3d60' + - '00fd5b505050506040513d6020811015620005dc57600080fd5b50516200064a57604080' + - '517f08c379a0000000000000000000000000000000000000000000000000000000008152' + - '60206004820152601c60248201527f6d61726b6572206d6574686f642072657475726e65' + - '642066616c736500000000604482015290519081900360640190fd5b6007805460016001' + - '60a01b0319166001600160a01b0385811691821790925560408051928416835260208301' + - '9190915280517fedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d' + - '72f9269281900390910190a16000620004ee565b60007f45b96fe442630264581b197e84' + - 'bbada861235052c5a1aadfff9ea4e40a969aa0836010811115620006de57fe5b83604d81' + - '1115620006eb57fe5b604080519283526020830191909152600082820152519081900360' + - '600190a18260108111156200071757fe5b9392505050565b828054600181600116156101' + - '000203166002900490600052602060002090601f016020900481019282601f1062000761' + - '57805160ff191683800117855562000791565b8280016001018555821562000791579182' + - '015b828111156200079157825182559160200191906001019062000774565b506200079f' + - '929150620007a3565b5090565b620004f991905b808211156200079f5760008155600101' + - '620007aa565b614a1a80620007d06000396000f3fe608060405234801561001057600080' + - 'fd5b506004361061028a5760003560e01c80638f840ddd1161015c578063c37f68e21161' + - '00ce578063f3fdb15a11610087578063f3fdb15a14610708578063f5e3c4621461071057' + - '8063f851a44014610746578063f8f9da281461074e578063fca7820b14610756578063fe' + - '9c44ae146107735761028a565b8063c37f68e214610626578063c5ebeaec146106725780' + - '63db006a751461068f578063dd62ed3e146106ac578063e9c714f2146106da578063f2b3' + - 'abbd146106e25761028a565b8063a9059cbb11610120578063a9059cbb14610586578063' + - 'aa5af0fd146105b2578063ae9d70b0146105ba578063b2a02ff1146105c2578063b71d1a' + - '0c146105f8578063bd6d894d1461061e5761028a565b80638f840ddd1461052b57806395' + - 'd89b411461053357806395dd91931461053b578063a0712d6814610561578063a6afed95' + - '1461057e5761028a565b80633af9e66911610200578063675d972c116101b9578063675d' + - '972c146104c85780636c540baf146104d05780636f307dc3146104d857806370a0823114' + - '6104e057806373acee9814610506578063852a12e31461050e5761028a565b80633af9e6' + - '69146104475780633b1d21a21461046d5780634576b5db1461047557806347bd37181461' + - '049b5780635fe3b567146104a3578063601a0bf1146104ab5761028a565b806318160ddd' + - '1161025257806318160ddd146103a9578063182df0f5146103b157806323b872dd146103' + - 'b95780632608f818146103ef578063267822471461041b578063313ce5671461043f5761' + - '028a565b806306fdde031461028f578063095ea7b31461030c5780630e7527021461034c' + - '578063173b99041461037b57806317bfdfbc14610383575b600080fd5b61029761077b56' + - '5b6040805160208082528351818301528351919283929083019185019080838360005b83' + - '8110156102d15781810151838201526020016102b9565b50505050905090810190601f16' + - '80156102fe5780820380516001836020036101000a031916815260200191505b50925050' + - '5060405180910390f35b6103386004803603604081101561032257600080fd5b50600160' + - '0160a01b038135169060200135610808565b604080519115158252519081900360200190' + - 'f35b6103696004803603602081101561036257600080fd5b5035610875565b6040805191' + - '8252519081900360200190f35b610369610888565b610369600480360360208110156103' + - '9957600080fd5b50356001600160a01b031661088e565b610369610951565b6103696109' + - '57565b610338600480360360608110156103cf57600080fd5b506001600160a01b038135' + - '811691602081013590911690604001356109bd565b610369600480360360408110156104' + - '0557600080fd5b506001600160a01b038135169060200135610a29565b610423610a3c56' + - '5b604080516001600160a01b039092168252519081900360200190f35b610369610a4b56' + - '5b6103696004803603602081101561045d57600080fd5b50356001600160a01b0316610a' + - '51565b610369610abf565b6103696004803603602081101561048b57600080fd5b503560' + - '01600160a01b0316610ace565b610369610c23565b610423610c29565b61036960048036' + - '0360208110156104c157600080fd5b5035610c38565b610369610cc6565b610369610ccc' + - '565b610423610cd2565b610369600480360360208110156104f657600080fd5b50356001' + - '600160a01b0316610ce1565b610369610cfc565b61036960048036036020811015610524' + - '57600080fd5b5035610db6565b610369610dc1565b610297610dc7565b61036960048036' + - '03602081101561055157600080fd5b50356001600160a01b0316610e1f565b6103696004' + - '803603602081101561057757600080fd5b5035610e7f565b610369610e8a565b61033860' + - '04803603604081101561059c57600080fd5b506001600160a01b03813516906020013561' + - '1286565b6103696112f1565b6103696112f7565b610369600480360360608110156105d8' + - '57600080fd5b506001600160a01b038135811691602081013590911690604001356115d1' + - '565b6103696004803603602081101561060e57600080fd5b50356001600160a01b031661' + - '188e565b610369611915565b61064c6004803603602081101561063c57600080fd5b5035' + - '6001600160a01b03166119d0565b60408051948552602085019390935283830191909152' + - '6060830152519081900360800190f35b6103696004803603602081101561068857600080' + - 'fd5b5035611a65565b610369600480360360208110156106a557600080fd5b5035611a70' + - '565b610369600480360360408110156106c257600080fd5b506001600160a01b03813581' + - '16916020013516611a7b565b610369611aa6565b610369600480360360208110156106f8' + - '57600080fd5b50356001600160a01b0316611b95565b610423611bcf565b610369600480' + - '3603606081101561072657600080fd5b506001600160a01b038135811691602081013591' + - '60409091013516611bde565b610423611beb565b610369611bfa565b6103696004803603' + - '602081101561076c57600080fd5b5035611cd9565b610338611d13565b60018054604080' + - '516020600284861615610100026000190190941693909304601f81018490048402820184' + - '0190925281815292918301828280156108005780601f106107d557610100808354040283' + - '529160200191610800565b820191906000526020600020905b8154815290600101906020' + - '018083116107e357829003601f168201915b505050505081565b33600081815260106020' + - '90815260408083206001600160a01b038716808552908352818420869055815186815291' + - '51939493909284927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200a' + - 'c8c7c3b925929081900390910190a360019150505b92915050565b600061088082611d18' + - '565b90505b919050565b60095481565b60008054600101808255816108a1610e8a565b14' + - '6108f65760408051600160e51b62461bcd02815260206004820152601660248201527f61' + - '636372756520696e746572657374206661696c6564000000000000000000006044820152' + - '90519081900360640190fd5b6108ff83610e1f565b91505b600054811461094b57604080' + - '51600160e51b62461bcd02815260206004820152600a6024820152600160b21b691c994b' + - '595b9d195c995902604482015290519081900360640190fd5b50919050565b600e548156' + - '5b6000806000610964611d54565b9092509050600082600381111561097757fe5b146109' + - 'b657604051600160e51b62461bcd02815260040180806020018281038252603581526020' + - '01806149626035913960400191505060405180910390fd5b9150505b90565b6000805460' + - '0101808255816109d433878787611e02565b1491505b6000548114610a21576040805160' + - '0160e51b62461bcd02815260206004820152600a6024820152600160b21b691c994b595b' + - '9d195c995902604482015290519081900360640190fd5b509392505050565b6000610a35' + - '8383612116565b9392505050565b6005546001600160a01b031681565b60035481565b60' + - '00610a5b6146bb565b6040518060200160405280610a6e611915565b90526001600160a0' + - '1b0384166000908152600f6020526040812054919250908190610a9a9084906121a6565b' + - '90925090506000826003811115610aad57fe5b14610ab757600080fd5b94935050505056' + - '5b6000610ac96121fa565b905090565b6004546000906001600160a01b03163314610af6' + - '57610aef6001603f61227d565b9050610883565b60065460408051600160e11b623f1ee9' + - '02815290516001600160a01b0392831692851691627e3dd2916004808301926020929190' + - '829003018186803b158015610b3e57600080fd5b505afa158015610b52573d6000803e3d' + - '6000fd5b505050506040513d6020811015610b6857600080fd5b5051610bbe5760408051' + - '600160e51b62461bcd02815260206004820152601c60248201527f6d61726b6572206d65' + - '74686f642072657475726e65642066616c73650000000060448201529051908190036064' + - '0190fd5b600680546001600160a01b0319166001600160a01b0385811691821790925560' + - '4080519284168352602083019190915280517f7ac369dbd14fa5ea3f473ed67cc9d59896' + - '4a77501540ba6751eb0b3decf5870d9281900390910190a160009392505050565b600c54' + - '81565b6006546001600160a01b031681565b6000805460010180825581610c4b610e8a56' + - '5b90508015610c7157610c69816010811115610c6257fe5b603061227d565b9250506109' + - '02565b610c7a846122e3565b925050600054811461094b5760408051600160e51b62461b' + - 'cd02815260206004820152600a6024820152600160b21b691c994b595b9d195c99590260' + - '4482015290519081900360640190fd5b60085481565b600a5481565b6012546001600160' + - 'a01b031681565b6001600160a01b03166000908152600f602052604090205490565b6000' + - '805460010180825581610d0f610e8a565b14610d645760408051600160e51b62461bcd02' + - '815260206004820152601660248201527f61636372756520696e74657265737420666169' + - '6c656400000000000000000000604482015290519081900360640190fd5b600c54915060' + - '00548114610db25760408051600160e51b62461bcd02815260206004820152600a602482' + - '0152600160b21b691c994b595b9d195c995902604482015290519081900360640190fd5b' + - '5090565b600061088082612467565b600d5481565b600280546040805160206001841615' + - '6101000260001901909316849004601f8101849004840282018401909252818152929183' + - '01828280156108005780601f106107d55761010080835404028352916020019161080056' + - '5b6000806000610e2d846124a4565b90925090506000826003811115610e4057fe5b1461' + - '0a3557604051600160e51b62461bcd028152600401808060200182810382526037815260' + - '2001806148366037913960400191505060405180910390fd5b600061088082612558565b' + - '6000610e946146ce565b6007546001600160a01b03166315f24053610ead6121fa565b60' + - '0c54600d546040518463ffffffff1660e01b815260040180848152602001838152602001' + - '8281526020019350505050604080518083038186803b158015610ef457600080fd5b505a' + - 'fa158015610f08573d6000803e3d6000fd5b505050506040513d6040811015610f1e5760' + - '0080fd5b50805160209182015160408401819052918301526601c6bf526340001015610f' + - '905760408051600160e51b62461bcd02815260206004820152601c60248201527f626f72' + - '726f772072617465206973206162737572646c7920686967680000000060448201529051' + - '9081900360640190fd5b602081015115610fb357610fab60056002836020015161259356' + - '5b9150506109ba565b610fbb6125f9565b60608201819052600a54610fcf91906125fd56' + - '5b6080830181905282826003811115610fe357fe5b6003811115610fee57fe5b90525060' + - '0090508151600381111561100257fe5b1461100957fe5b61102960405180602001604052' + - '8083604001518152508260800151612620565b60a083018190528282600381111561103d' + - '57fe5b600381111561104857fe5b905250600090508151600381111561105c57fe5b1461' + - '107d57610fab600960068360000151600381111561107857fe5b612593565b61108d8160' + - 'a00151600c546121a6565b60c08301819052828260038111156110a157fe5b6003811115' + - '6110ac57fe5b90525060009050815160038111156110c057fe5b146110dc57610fab6009' + - '60018360000151600381111561107857fe5b6110ec8160c00151600c54612688565b60e0' + - '83018190528282600381111561110057fe5b600381111561110b57fe5b90525060009050' + - '8151600381111561111f57fe5b1461113b57610fab600960048360000151600381111561' + - '107857fe5b61115c60405180602001604052806009548152508260c00151600d546126ae' + - '565b61010083018190528282600381111561117157fe5b600381111561117c57fe5b9052' + - '50600090508151600381111561119057fe5b146111ac57610fab60096005836000015160' + - '0381111561107857fe5b6111bf8160a00151600b54600b546126ae565b61012083018190' + - '52828260038111156111d457fe5b60038111156111df57fe5b9052506000905081516003' + - '8111156111f357fe5b1461120f57610fab600960038360000151600381111561107857fe' + - '5b606080820151600a55610120820151600b81905560e0830151600c8190556101008401' + - '51600d5560c08401516040805191825260208201939093528083019190915290517f8753' + - '52fb3fadeb8c0be7cbbe8ff761b308fa7033470cd0287f02f3436fd76cb9929181900390' + - '910190a1600091505090565b600080546001018082558161129d33338787611e02565b14' + - '91505b60005481146112ea5760408051600160e51b62461bcd0281526020600482015260' + - '0a6024820152600160b21b691c994b595b9d195c99590260448201529051908190036064' + - '0190fd5b5092915050565b600b5481565b600080611302610957565b6007549091506000' + - '9081906001600160a01b03166315f240536113236121fa565b600c54600d546040518463' + - 'ffffffff1660e01b81526004018084815260200183815260200182815260200193505050' + - '50604080518083038186803b15801561136a57600080fd5b505afa15801561137e573d60' + - '00803e3d6000fd5b505050506040513d604081101561139457600080fd5b508051602090' + - '910151909250905081156113e257604051600160e51b62461bcd02815260040180806020' + - '01828103825260318152602001806148d56031913960400191505060405180910390fd5b' + - '60006113ec6146bb565b611406604051806020016040528087815250600e54612620565b' + - '9092509050600082600381111561141957fe5b1461145857604051600160e51b62461bcd' + - '02815260040180806020018281038252603181526020018061486d603191396040019150' + - '5060405180910390fd5b60006114626146bb565b61146e600c548461270a565b90925090' + - '50600082600381111561148157fe5b146114c057604051600160e51b62461bcd02815260' + - '04018080602001828103825260318152602001806147b160319139604001915050604051' + - '80910390fd5b60006114ca6146bb565b6114fa6040518060200160405280670de0b6b3a7' + - '6400008152506040518060200160405280600954815250612769565b9092509050600082' + - '600381111561150d57fe5b1461154c57604051600160e51b62461bcd0281526004018080' + - '6020018281038252603c815260200180614926603c913960400191505060405180910390' + - 'fd5b60006115566146bb565b61156f60405180602001604052808b81525084876127a356' + - '5b9092509050600082600381111561158257fe5b146115c157604051600160e51b62461b' + - 'cd0281526004018080602001828103825260318152602001806148056031913960400191' + - '505060405180910390fd5b519a505050505050505050505090565b600080546001018082' + - '5560065460408051600160e01b63d02f7351028152306004820152336024820152600160' + - '0160a01b0388811660448301528781166064830152608482018790529151859392909216' + - '9163d02f73519160a48082019260209290919082900301818787803b15801561164a5760' + - '0080fd5b505af115801561165e573d6000803e3d6000fd5b505050506040513d60208110' + - '1561167457600080fd5b5051905080156116935761168b6003601b83612593565b925050' + - '6109d8565b856001600160a01b0316856001600160a01b031614156116b95761168b6006' + - '601c61227d565b6001600160a01b0385166000908152600f602052604081205481908190' + - '6116e090886125fd565b909350915060008360038111156116f357fe5b14611716576117' + - '0b6009601a85600381111561107857fe5b9550505050506109d8565b6001600160a01b03' + - '89166000908152600f60205260409020546117399088612688565b909350905060008360' + - '0381111561174c57fe5b146117645761170b6009601985600381111561107857fe5b6001' + - '600160a01b038089166000818152600f60209081526040808320879055938d1680835291' + - '84902085905583518b815293519193600080516020614906833981519152929081900390' + - '910190a360065460408051600160e01b636d35bf91028152306004820152336024820152' + - '6001600160a01b038c811660448301528b81166064830152608482018b90529151919092' + - '1691636d35bf919160a480830192600092919082900301818387803b15801561181e5760' + - '0080fd5b505af1158015611832573d6000803e3d6000fd5b506000925061183f91505056' + - '5b9550505050506000548114610a215760408051600160e51b62461bcd02815260206004' + - '820152600a6024820152600160b21b691c994b595b9d195c995902604482015290519081' + - '900360640190fd5b6004546000906001600160a01b031633146118af57610aef60016045' + - '61227d565b600580546001600160a01b038481166001600160a01b031983168117909355' + - '6040805191909216808252602082019390935281517fca4f2f25d0898edd99413412fb94' + - '012f9e54ec8142f9b093e7720646a95b16a9929181900390910190a16000610a35565b60' + - '00805460010180825581611928610e8a565b1461197d5760408051600160e51b62461bcd' + - '02815260206004820152601660248201527f61636372756520696e746572657374206661' + - '696c656400000000000000000000604482015290519081900360640190fd5b6119856109' + - '57565b91506000548114610db25760408051600160e51b62461bcd028152602060048201' + - '52600a6024820152600160b21b691c994b595b9d195c9959026044820152905190819003' + - '60640190fd5b6001600160a01b0381166000908152600f60205260408120548190819081' + - '908180806119fb896124a4565b935090506000816003811115611a0d57fe5b14611a2b57' + - '60095b975060009650869550859450611a5e9350505050565b611a33611d54565b925090' + - '506000816003811115611a4557fe5b14611a51576009611a15565b506000965091945092' + - '5090505b9193509193565b6000610880826127ed565b600061088082612828565b600160' + - '0160a01b0391821660009081526010602090815260408083209390941682529190915220' + - '5490565b6005546000906001600160a01b031633141580611ac1575033155b15611ad957' + - '611ad26001600061227d565b90506109ba565b60048054600580546001600160a01b0380' + - '82166001600160a01b031980861682179687905590921690925560408051938316808552' + - '949092166020840152815190927ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f' + - '21c4e8146d8519b417dc92908290030190a1600554604080516001600160a01b03808516' + - '8252909216602083015280517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b0' + - '93e7720646a95b16a99281900390910190a160009250505090565b600080611ba0610e8a' + - '565b90508015611bc657611bbe816010811115611bb757fe5b604061227d565b91505061' + - '0883565b610a358361285e565b6007546001600160a01b031681565b6000610ab7848484' + - '6129d1565b6004546001600160a01b031681565b600754600090819081906001600160a0' + - '1b03166315f24053611c1a6121fa565b600c54600d546040518463ffffffff1660e01b81' + - '526004018084815260200183815260200182815260200193505050506040805180830381' + - '86803b158015611c6157600080fd5b505afa158015611c75573d6000803e3d6000fd5b50' + - '5050506040513d6040811015611c8b57600080fd5b508051602090910151909250905081' + - '156109b657604051600160e51b62461bcd02815260040180806020018281038252603781' + - '526020018061489e6037913960400191505060405180910390fd5b600080546001018082' + - '5581611cec610e8a565b90508015611d0a57610c69816010811115611d0357fe5b604661' + - '227d565b610c7a84612adf565b600181565b6000805460010180825581611d2b610e8a56' + - '5b90508015611d4957610c69816010811115611d4257fe5b603661227d565b610c7a3333' + - '86612b82565b600080600e5460001415611d6f575050600854600090611dfe565b600061' + - '1d796121fa565b90506000611d856146bb565b6000611d9684600c54600d54612fde565b' + - '935090506000816003811115611da857fe5b14611dbc57945060009350611dfe92505050' + - '565b611dc883600e5461301c565b925090506000816003811115611dda57fe5b14611dee' + - '57945060009350611dfe92505050565b5051600094509250611dfe915050565b9091565b' + - '60065460408051600160e31b6317b9b84b0281523060048201526001600160a01b038681' + - '16602483015285811660448301526064820185905291516000938493169163bdcdc25891' + - '608480830192602092919082900301818787803b158015611e6a57600080fd5b505af115' + - '8015611e7e573d6000803e3d6000fd5b505050506040513d6020811015611e9457600080' + - 'fd5b505190508015611eb357611eab6003604a83612593565b915050610ab7565b836001' + - '600160a01b0316856001600160a01b03161415611ed957611eab6002604b61227d565b60' + - '006001600160a01b038781169087161415611ef85750600019611f20565b506001600160' + - 'a01b038086166000908152601060209081526040808320938a16835292905220545b6000' + - '80600080611f3085896125fd565b90945092506000846003811115611f4357fe5b14611f' + - '6157611f546009604b61227d565b9650505050505050610ab7565b6001600160a01b038a' + - '166000908152600f6020526040902054611f8490896125fd565b90945091506000846003' + - '811115611f9757fe5b14611fa857611f546009604c61227d565b6001600160a01b038916' + - '6000908152600f6020526040902054611fcb9089612688565b9094509050600084600381' + - '1115611fde57fe5b14611fef57611f546009604d61227d565b6001600160a01b03808b16' + - '6000908152600f6020526040808220859055918b16815220819055600019851461204757' + - '6001600160a01b03808b166000908152601060209081526040808320938f168352929052' + - '208390555b886001600160a01b03168a6001600160a01b03166000805160206149068339' + - '815191528a6040518082815260200191505060405180910390a360065460408051600160' + - 'e11b63352b4a3f0281523060048201526001600160a01b038d811660248301528c811660' + - '44830152606482018c905291519190921691636a56947e91608480830192600092919082' + - '900301818387803b1580156120e657600080fd5b505af11580156120fa573d6000803e3d' + - '6000fd5b5060009250612107915050565b9b9a5050505050505050505050565b60008054' + - '60010180825581612129610e8a565b9050801561214f5761214781601081111561214057' + - 'fe5b603561227d565b9250506112a1565b61215a338686612b82565b9250506000548114' + - '6112ea5760408051600160e51b62461bcd02815260206004820152600a60248201526001' + - '60b21b691c994b595b9d195c995902604482015290519081900360640190fd5b60008060' + - '006121b36146bb565b6121bd8686612620565b909250905060008260038111156121d057' + - 'fe5b146121e157509150600090506121f3565b60006121ec826130cc565b935093505050' + - '5b9250929050565b60125460408051600160e01b6370a082310281523060048201529051' + - '6000926001600160a01b03169182916370a0823191602480820192602092909190829003' + - '018186803b15801561224b57600080fd5b505afa15801561225f573d6000803e3d6000fd' + - '5b505050506040513d602081101561227557600080fd5b505191505090565b60007f45b9' + - '6fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0836010811115' + - '6122ac57fe5b83604d8111156122b857fe5b604080519283526020830191909152600082' + - '820152519081900360600190a1826010811115610a3557fe5b6004546000908190819060' + - '01600160a01b03163314612311576123086001603161227d565b92505050610883565b61' + - '23196125f9565b600a541461232d57612308600a603361227d565b836123366121fa565b' + - '101561234857612308600e603261227d565b600d5484111561235e576123086002603461' + - '227d565b50600d54838103908111156123a757604051600160e51b62461bcd0281526004' + - '018080602001828103825260248152602001806149cb6024913960400191505060405180' + - '910390fd5b600d8190556004546123c2906001600160a01b0316856130db565b91506000' + - '8260108111156123d257fe5b1461241157604051600160e51b62461bcd02815260040180' + - '80602001828103825260238152602001806147e260239139604001915050604051809103' + - '90fd5b600454604080516001600160a01b03909216825260208201869052818101839052' + - '517f3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e9181' + - '900360600190a16000949350505050565b600080546001018082558161247a610e8a565b' + - '9050801561249857610c6981601081111561249157fe5b602761227d565b610c7a336000' + - '8661319a565b6001600160a01b0381166000908152601160205260408120805482918291' + - '829182916124db57506000945084935061255392505050565b6124eb8160000154600b54' + - '6136af565b909450925060008460038111156124fe57fe5b146125135750919350600092' + - '50612553915050565b6125218382600101546136ee565b90945091506000846003811115' + - '61253457fe5b14612549575091935060009250612553915050565b506000945092505050' + - '5b915091565b600080546001018082558161256b610e8a565b9050801561258957610c69' + - '81601081111561258257fe5b601e61227d565b610c7a3385613719565b60007f45b96fe4' + - '42630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08460108111156125' + - 'c257fe5b84604d8111156125ce57fe5b6040805192835260208301919091528181018590' + - '52519081900360600190a1836010811115610ab757fe5b4390565b600080838311612614' + - '5750600090508183036121f3565b506003905060006121f3565b600061262a6146bb565b' + - '60008061263b8660000151866136af565b9092509050600082600381111561264e57fe5b' + - '1461266d575060408051602081019091526000815290925090506121f3565b6040805160' + - '2081019091529081526000969095509350505050565b6000808383018481106126a05760' + - '00925090506121f3565b5060029150600090506121f3565b60008060006126bb6146bb56' + - '5b6126c58787612620565b909250905060008260038111156126d857fe5b146126e95750' + - '915060009050612702565b6126fb6126f5826130cc565b86612688565b9350935050505b' + - '935093915050565b60006127146146bb565b600080612729670de0b6b3a7640000876136' + - 'af565b9092509050600082600381111561273c57fe5b1461275b57506040805160208101' + - '9091526000815290925090506121f3565b6121ec81866000015161301c565b6000612773' + - '6146bb565b600080612788866000015186600001516125fd565b60408051602081019091' + - '529081529097909650945050505050565b60006127ad6146bb565b60006127b76146bb56' + - '5b6127c18787613b67565b909250905060008260038111156127d457fe5b146127e35790' + - '92509050612702565b6126fb8186613b67565b6000805460010180825581612800610e8a' + - '565b9050801561281e57610c6981601081111561281757fe5b600861227d565b610c7a33' + - '85613c50565b600080546001018082558161283b610e8a565b9050801561285257610c69' + - '81601081111561249157fe5b610c7a3385600061319a565b600454600090819060016001' + - '60a01b0316331461288157611bbe6001604261227d565b6128896125f9565b600a541461' + - '289d57611bbe600a604161227d565b600760009054906101000a90046001600160a01b03' + - '169050826001600160a01b0316632191f92a6040518163ffffffff1660e01b8152600401' + - '60206040518083038186803b1580156128ee57600080fd5b505afa158015612902573d60' + - '00803e3d6000fd5b505050506040513d602081101561291857600080fd5b505161296e57' + - '60408051600160e51b62461bcd02815260206004820152601c60248201527f6d61726b65' + - '72206d6574686f642072657475726e65642066616c736500000000604482015290519081' + - '900360640190fd5b600780546001600160a01b0319166001600160a01b03858116918217' + - '909255604080519284168352602083019190915280517fedffc32e068c7c95dfd4bdfd5c' + - '4d939a084d6b11c4199eac8436ed234d72f9269281900390910190a16000610a35565b60' + - '008054600101808255816129e4610e8a565b90508015612a025761168b81601081111561' + - '29fb57fe5b600f61227d565b836001600160a01b031663a6afed956040518163ffffffff' + - '1660e01b8152600401602060405180830381600087803b158015612a3d57600080fd5b50' + - '5af1158015612a51573d6000803e3d6000fd5b505050506040513d6020811015612a6757' + - '600080fd5b505190508015612a875761168b816010811115612a8057fe5b601061227d56' + - '5b612a9333878787613fbf565b9250506000548114610a215760408051600160e51b6246' + - '1bcd02815260206004820152600a6024820152600160b21b691c994b595b9d195c995902' + - '604482015290519081900360640190fd5b6004546000906001600160a01b03163314612b' + - '0057610aef6001604761227d565b612b086125f9565b600a5414612b1c57610aef600a60' + - '4861227d565b670de0b6b3a7640000821115612b3857610aef6002604961227d565b6009' + - '805490839055604080518281526020810185905281517faaa68312e2ea9d50e16af50684' + - '10ab56e1a1fd06037b1a35664812c30f821460929181900390910190a16000610a35565b' + - '60065460408051600160e11b63120045310281523060048201526001600160a01b038681' + - '1660248301528581166044830152606482018590529151600093849316916324008a6291' + - '608480830192602092919082900301818787803b158015612bea57600080fd5b505af115' + - '8015612bfe573d6000803e3d6000fd5b505050506040513d6020811015612c1457600080' + - 'fd5b505190508015612c3357612c2b6003603883612593565b915050610a35565b612c3b' + - '6125f9565b600a5414612c4f57612c2b600a603961227d565b612c57614728565b600160' + - '0160a01b0385166000908152601160205260409020600101546060820152612c81856124' + - 'a4565b6080830181905260208301826003811115612c9857fe5b6003811115612ca357fe' + - '5b9052506000905081602001516003811115612cba57fe5b14612cdf57612cd660096037' + - '8360200151600381111561107857fe5b92505050610a35565b600019841415612cf85760' + - '808101516040820152612d00565b604081018490525b612d0e8682604001516144b3565b' + - '81906010811115612d1b57fe5b90816010811115612d2857fe5b90525060008151601081' + - '1115612d3a57fe5b14612d4c578051612cd690603c61227d565b612d5e81608001518260' + - '4001516125fd565b60a0830181905260208301826003811115612d7557fe5b6003811115' + - '612d8057fe5b9052506000905081602001516003811115612d9757fe5b14612db357612c' + - 'd66009603a8360200151600381111561107857fe5b612dc3600c5482604001516125fd56' + - '5b60c0830181905260208301826003811115612dda57fe5b6003811115612de557fe5b90' + - '52506000905081602001516003811115612dfc57fe5b14612e1857612cd66009603b8360' + - '200151600381111561107857fe5b612e268682604001516145ea565b8190601081111561' + - '2e3357fe5b90816010811115612e4057fe5b905250600081516010811115612e5257fe5b' + - '14612ea75760408051600160e51b62461bcd02815260206004820152601f60248201527f' + - '726570617920626f72726f77207472616e7366657220696e206661696c65640060448201' + - '5290519081900360640190fd5b60a080820180516001600160a01b038089166000818152' + - '60116020908152604091829020948555600b5460019095019490945560c0870151600c81' + - '90558188015195518251948e168552948401929092528281019490945260608201929092' + - '52608081019190915290517f1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0' + - '355478d6f5c362a1929181900390910190a1600654604080830151606084015182516001' + - '60e01b631ededc910281523060048201526001600160a01b038b811660248301528a8116' + - '6044830152606482019390935260848101919091529151921691631ededc919160a48082' + - '019260009290919082900301818387803b158015612fb357600080fd5b505af115801561' + - '2fc7573d6000803e3d6000fd5b5060009250612fd4915050565b9695505050505050565b' + - '600080600080612fee8787612688565b9092509050600082600381111561300157fe5b14' + - '6130125750915060009050612702565b6126fb81866125fd565b60006130266146bb565b' + - '60008061303b86670de0b6b3a76400006136af565b909250905060008260038111156130' + - '4e57fe5b1461306d575060408051602081019091526000815290925090506121f3565b60' + - '008061307a83886136ee565b9092509050600082600381111561308d57fe5b146130af57' + - '5060408051602081019091526000815290945092506121f3915050565b60408051602081' + - '0190915290815260009890975095505050505050565b51670de0b6b3a764000090049056' + - '5b60125460408051600160e01b63a9059cbb0281526001600160a01b0385811660048301' + - '5260248201859052915160009392909216918391839163a9059cbb916044808201928692' + - '90919082900301818387803b15801561313a57600080fd5b505af115801561314e573d60' + - '00803e3d6000fd5b505050503d60008114613168576020811461317257600080fd5b6000' + - '19915061317e565b60206000803e60005191505b508061318f5760109250505061086f56' + - '5b506000949350505050565b60008215806131a7575081155b6131e557604051600160e5' + - '1b62461bcd02815260040180806020018281038252603481526020018061499760349139' + - '60400191505060405180910390fd5b6131ed614728565b6131f5611d54565b6040830181' + - '90526020830182600381111561320c57fe5b600381111561321757fe5b90525060009050' + - '8160200151600381111561322e57fe5b1461324a57612c2b6009602b8360200151600381' + - '111561107857fe5b83156132cb5760608101849052604080516020810182529082015181' + - '5261327190856121a6565b608083018190526020830182600381111561328857fe5b6003' + - '81111561329357fe5b90525060009050816020015160038111156132aa57fe5b146132c6' + - '57612c2b600960298360200151600381111561107857fe5b613344565b6132e783604051' + - '806020016040528084604001518152506146a4565b606083018190526020830182600381' + - '11156132fe57fe5b600381111561330957fe5b9052506000905081602001516003811115' + - '61332057fe5b1461333c57612c2b6009602a8360200151600381111561107857fe5b6080' + - '81018390525b600654606082015160408051600160e01b63eabe7d910281523060048201' + - '526001600160a01b03898116602483015260448201939093529051600093929092169163' + - 'eabe7d919160648082019260209290919082900301818787803b1580156133ac57600080' + - 'fd5b505af11580156133c0573d6000803e3d6000fd5b505050506040513d602081101561' + - '33d657600080fd5b5051905080156133ed57612cd66003602883612593565b6133f56125' + - 'f9565b600a541461340957612cd6600a602c61227d565b613419600e5483606001516125' + - 'fd565b60a084018190526020840182600381111561343057fe5b600381111561343b57fe' + - '5b905250600090508260200151600381111561345257fe5b1461346e57612cd66009602e' + - '8460200151600381111561107857fe5b6001600160a01b0386166000908152600f602052' + - '6040902054606083015161349691906125fd565b60c08401819052602084018260038111' + - '156134ad57fe5b60038111156134b857fe5b905250600090508260200151600381111561' + - '34cf57fe5b146134eb57612cd66009602d8460200151600381111561107857fe5b816080' + - '01516134f86121fa565b101561350a57612cd6600e602f61227d565b6135188683608001' + - '516130db565b8290601081111561352557fe5b9081601081111561353257fe5b90525060' + - '008251601081111561354457fe5b146135995760408051600160e51b62461bcd02815260' + - '206004820152601a60248201527f72656465656d207472616e73666572206f7574206661' + - '696c6564000000000000604482015290519081900360640190fd5b60a0820151600e5560' + - 'c08201516001600160a01b0387166000818152600f602090815260409182902093909355' + - '6060850151815190815290513093600080516020614906833981519152928290030190a3' + - '6080820151606080840151604080516001600160a01b038b168152602081019490945283' + - '810191909152517fe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4' + - 'ec31a9299281900390910190a16006546080830151606084015160408051600160e01b63' + - '51dff9890281523060048201526001600160a01b038b8116602483015260448201949094' + - '5260648101929092525191909216916351dff98991608480830192600092919082900301' + - '818387803b158015612fb357600080fd5b600080836136c2575060009050806121f3565b' + - '838302838582816136cf57fe5b04146136e3575060029150600090506121f3565b600092' + - '5090506121f3565b6000808261370257506001905060006121f3565b600083858161370d' + - '57fe5b04915091509250929050565b60065460408051600160e01b634ef4c3e102815230' + - '60048201526001600160a01b038581166024830152604482018590529151600093849316' + - '91634ef4c3e191606480830192602092919082900301818787803b158015613779576000' + - '80fd5b505af115801561378d573d6000803e3d6000fd5b505050506040513d6020811015' + - '6137a357600080fd5b5051905080156137c2576137ba6003601f83612593565b91505061' + - '086f565b6137ca6125f9565b600a54146137de576137ba600a602261227d565b6137e661' + - '4766565b6137f085856144b3565b819060108111156137fd57fe5b908160108111156138' + - '0a57fe5b90525060008151601081111561381c57fe5b1461383757805161382e90602661' + - '227d565b9250505061086f565b61383f611d54565b604083018190526020830182600381' + - '111561385657fe5b600381111561386157fe5b9052506000905081602001516003811115' + - '61387857fe5b146138945761382e600960218360200151600381111561107857fe5b6138' + - 'b084604051806020016040528084604001518152506146a4565b60608301819052602083' + - '018260038111156138c757fe5b60038111156138d257fe5b905250600090508160200151' + - '60038111156138e957fe5b146139055761382e6009602083602001516003811115611078' + - '57fe5b613915600e548260600151612688565b6080830181905260208301826003811115' + - '61392c57fe5b600381111561393757fe5b90525060009050816020015160038111156139' + - '4e57fe5b1461396a5761382e600960248360200151600381111561107857fe5b60016001' + - '60a01b0385166000908152600f602052604090205460608201516139929190612688565b' + - '60a08301819052602083018260038111156139a957fe5b60038111156139b457fe5b9052' + - '5060009050816020015160038111156139cb57fe5b146139e75761382e60096023836020' + - '0151600381111561107857fe5b6139f185856145ea565b819060108111156139fe57fe5b' + - '90816010811115613a0b57fe5b905250600081516010811115613a1d57fe5b14613a2f57' + - '805161382e90602561227d565b6080810151600e5560a08101516001600160a01b038616' + - '6000818152600f6020908152604091829020939093556060808501518251938452938301' + - '88905282820193909352517f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef' + - '26394f4c03821c4f929181900390910190a1606081015160408051918252516001600160' + - 'a01b0387169130916000805160206149068339815191529181900360200190a360065460' + - '6082015160408051600160e01b6341c728b90281523060048201526001600160a01b0389' + - '81166024830152604482018990526064820193909352905191909216916341c728b99160' + - '8480830192600092919082900301818387803b158015613b3d57600080fd5b505af11580' + - '15613b51573d6000803e3d6000fd5b5060009250613b5e915050565b9594505050505056' + - '5b6000613b716146bb565b600080613b86866000015186600001516136af565b90925090' + - '506000826003811115613b9957fe5b14613bb85750604080516020810190915260008152' + - '90925090506121f3565b600080613bcd6706f05b59d3b2000084612688565b9092509050' + - '6000826003811115613be057fe5b14613c02575060408051602081019091526000815290' + - '945092506121f3915050565b600080613c1783670de0b6b3a76400006136ee565b909250' + - '90506000826003811115613c2a57fe5b14613c3157fe5b60408051602081019091529081' + - '5260009a909950975050505050505050565b60065460408051600160e21b63368f515302' + - '81523060048201526001600160a01b038581166024830152604482018590529151600093' + - '8493169163da3d454c91606480830192602092919082900301818787803b158015613cb0' + - '57600080fd5b505af1158015613cc4573d6000803e3d6000fd5b505050506040513d6020' + - '811015613cda57600080fd5b505190508015613cf1576137ba6003600e83612593565b61' + - '3cf96125f9565b600a5414613d0c576137ba600a8061227d565b82613d156121fa565b10' + - '15613d27576137ba600e600961227d565b613d2f614780565b613d38856124a4565b6040' + - '830181905260208301826003811115613d4f57fe5b6003811115613d5a57fe5b90525060' + - '00905081602001516003811115613d7157fe5b14613d8d5761382e600960078360200151' + - '600381111561107857fe5b613d9b816040015185612688565b6060830181905260208301' + - '826003811115613db257fe5b6003811115613dbd57fe5b90525060009050816020015160' + - '03811115613dd457fe5b14613df05761382e6009600c8360200151600381111561107857' + - 'fe5b613dfc600c5485612688565b6080830181905260208301826003811115613e1357fe' + - '5b6003811115613e1e57fe5b9052506000905081602001516003811115613e3557fe5b14' + - '613e515761382e6009600b8360200151600381111561107857fe5b613e5b85856130db56' + - '5b81906010811115613e6857fe5b90816010811115613e7557fe5b905250600081516010' + - '811115613e8757fe5b14613edc5760408051600160e51b62461bcd028152602060048201' + - '52601a60248201527f626f72726f77207472616e73666572206f7574206661696c656400' + - '0000000000604482015290519081900360640190fd5b606080820180516001600160a01b' + - '038816600081815260116020908152604091829020938455600b54600190940193909355' + - '608080870151600c819055945182519384529383018a9052828201939093529381019290' + - '925291517f13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab' + - '80929181900390910190a160065460408051600160e01b635c7786050281523060048201' + - '526001600160a01b0388811660248301526044820188905291519190921691635c778605' + - '91606480830192600092919082900301818387803b158015613b3d57600080fd5b600654' + - '60408051600160e11b632fe3f38f0281523060048201526001600160a01b038481166024' + - '830152878116604483015286811660648301526084820186905291516000938493169163' + - '5fc7e71e9160a480830192602092919082900301818787803b15801561402f57600080fd' + - '5b505af1158015614043573d6000803e3d6000fd5b505050506040513d60208110156140' + - '5957600080fd5b50519050801561407057611eab6003601283612593565b6140786125f9' + - '565b600a541461408c57611eab600a601661227d565b6140946125f9565b836001600160' + - 'a01b0316636c540baf6040518163ffffffff1660e01b8152600401602060405180830381' + - '86803b1580156140cd57600080fd5b505afa1580156140e1573d6000803e3d6000fd5b50' + - '5050506040513d60208110156140f757600080fd5b50511461410a57611eab600a601161' + - '227d565b856001600160a01b0316856001600160a01b0316141561413057611eab600660' + - '1761227d565b8361414157611eab6007601561227d565b60001984141561415757611eab' + - '6007601461227d565b60065460408051600160e01b63c488847b02815230600482015260' + - '01600160a01b038681166024830152604482018890528251600094859492169263c48884' + - '7b926064808301939192829003018186803b1580156141b457600080fd5b505afa158015' + - '6141c8573d6000803e3d6000fd5b505050506040513d60408110156141de57600080fd5b' + - '50805160209091015190925090508115614209576141ff6004601384612593565b935050' + - '5050610ab7565b846001600160a01b03166370a08231886040518263ffffffff1660e01b' + - '815260040180826001600160a01b03166001600160a01b03168152602001915050602060' + - '40518083038186803b15801561425f57600080fd5b505afa158015614273573d6000803e' + - '3d6000fd5b505050506040513d602081101561428957600080fd5b505181111561429e57' + - '6141ff600d601d61227d565b60006142ab898989612b82565b905080156142d4576142c9' + - '8160108111156142c257fe5b601861227d565b945050505050610ab7565b604080516001' + - '60e01b63b2a02ff10281526001600160a01b038b811660048301528a8116602483015260' + - '448201859052915160009289169163b2a02ff19160648083019260209291908290030181' + - '8787803b15801561433257600080fd5b505af1158015614346573d6000803e3d6000fd5b' + - '505050506040513d602081101561435c57600080fd5b5051905080156143b65760408051' + - '600160e51b62461bcd02815260206004820152601460248201527f746f6b656e20736569' + - '7a757265206661696c656400000000000000000000000060448201529051908190036064' + - '0190fd5b604080516001600160a01b03808d168252808c1660208301528183018b905289' + - '1660608201526080810185905290517f298637f684da70674f26509b10f07ec2fbc77a33' + - '5ab1e7d6215a4b2484d8bb529181900360a00190a160065460408051600160e01b6347ef' + - '3b3b0281523060048201526001600160a01b038a811660248301528d811660448301528c' + - '81166064830152608482018c905260a48201879052915191909216916347ef3b3b9160c4' + - '80830192600092919082900301818387803b15801561448457600080fd5b505af1158015' + - '614498573d6000803e3d6000fd5b50600092506144a5915050565b9a9950505050505050' + - '505050565b60125460408051600160e11b636eb1769f0281526001600160a01b03858116' + - '6004830152306024830152915160009392909216918491839163dd62ed3e916044808201' + - '92602092909190829003018186803b15801561451157600080fd5b505afa158015614525' + - '573d6000803e3d6000fd5b505050506040513d602081101561453b57600080fd5b505110' + - '1561454d57600c91505061086f565b82816001600160a01b03166370a082318660405182' + - '63ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152' + - '60200191505060206040518083038186803b1580156145a457600080fd5b505afa158015' + - '6145b8573d6000803e3d6000fd5b505050506040513d60208110156145ce57600080fd5b' + - '505110156145e057600d91505061086f565b5060009392505050565b6012546040805160' + - '0160e01b6323b872dd0281526001600160a01b0385811660048301523060248301526044' + - '820185905291516000939290921691839183916323b872dd916064808201928692909190' + - '82900301818387803b15801561464f57600080fd5b505af1158015614663573d6000803e' + - '3d6000fd5b505050503d6000811461467d576020811461468757600080fd5b6000199150' + - '614693565b60206000803e60005191505b508061318f57600f9250505061086f565b6000' + - '8060006146b16146bb565b6121bd868661270a565b604051806020016040528060008152' + - '5090565b6040805161014081019091528060008152602001600081526020016000815260' + - '200160008152602001600081526020016147066146bb565b815260200160008152602001' + - '6000815260200160008152602001600081525090565b6040805160e08101909152806000' + - '815260200160008152602001600081526020016000815260200160008152602001600081' + - '52602001600081525090565b6040805160c0810190915280600081526020016000614706' + - '565b6040805160a081019091528060008152602001600081526020016000815260200160' + - '00815260200160008152509056fe737570706c7952617465506572426c6f636b3a206361' + - '6c63756c6174696e6720626f72726f7773506572206661696c6564726564756365207265' + - '736572766573207472616e73666572206f7574206661696c6564737570706c7952617465' + - '506572426c6f636b3a2063616c63756c6174696e6720737570706c795261746520666169' + - '6c6564626f72726f7742616c616e636553746f7265643a20626f72726f7742616c616e63' + - '6553746f726564496e7465726e616c206661696c6564737570706c795261746550657242' + - '6c6f636b3a2063616c63756c6174696e6720756e6465726c79696e67206661696c656462' + - '6f72726f7752617465506572426c6f636b3a20696e746572657374526174654d6f64656c' + - '2e626f72726f7752617465206661696c6564737570706c7952617465506572426c6f636b' + - '3a2063616c63756c6174696e6720626f72726f7752617465206661696c6564ddf252ad1b' + - 'e2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef737570706c79526174' + - '65506572426c6f636b3a2063616c63756c6174696e67206f6e654d696e75735265736572' + - '7665466163746f72206661696c656465786368616e67655261746553746f7265643a2065' + - '786368616e67655261746553746f726564496e7465726e616c206661696c65646f6e6520' + - '6f662072656465656d546f6b656e73496e206f722072656465656d416d6f756e74496e20' + - '6d757374206265207a65726f72656475636520726573657276657320756e657870656374' + - '656420756e646572666c6f77a165627a7a72305820ae92d0e3e70b657d01891c7457bc6c' + - '8a5ce2401a1a8857f346a2fa9af4627145002953657474696e6720696e74657265737420' + - '72617465206d6f64656c206661696c6564496e697469616c2065786368616e6765207261' + - '7465206d7573742062652067726561746572207468616e207a65726f2e' + - '000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' + // usdc - '0000000000000000000000003d9819210a31b4961b30ef54be2aed79b9c9cd3b' + // troll - '000000000000000000000000c64c4cba055efa614ce01f4bad8a9f519c4f8fab' + // IRM - '0000000000000000000000000000000000000000000000000000b5e620f48000' + - '00000000000000000000000000000000000000000000000000000000000000e0' + - '0000000000000000000000000000000000000000000000000000000000000120' + - '0000000000000000000000000000000000000000000000000000000000000008' + - '0000000000000000000000000000000000000000000000000000000000000011' + - '436f6d706f756e642055534420436f696e000000000000000000000000000000' + - '0000000000000000000000000000000000000000000000000000000000000005' + - '6355534443000000000000000000000000000000000000000000000000000000' - ) - - // ************************** helper functions **************************** // - async function send( - title, - instance, - method, - args, - from, - value, - gas, - gasPrice, - shouldSucceed, - assertionCallback - ) { - const receipt = await instance.methods[method](...args).send({ - from: from, - value: value, - gas: gas, - gasPrice: gasPrice - }).on('confirmation', (confirmationNumber, r) => { - confirmations[r.transactionHash] = confirmationNumber - }).catch(error => { - if (shouldSucceed) { - console.error(error) - } - return {status: false} - }) - - if (receipt.status !== shouldSucceed) { - return false - } else if (!shouldSucceed) { - return true - } - let assertionsPassed - try { - assertionCallback(receipt) - assertionsPassed = true - } catch(error) { - assertionsPassed = false - console.log(error); - } + async function call( + title, + instance, + method, + args, + from, + value, + gas, + gasPrice, + shouldSucceed, + assertionCallback + ) { + let succeeded = true; + returnValues = await instance.methods[method](...args) + .call({ + from: from, + value: value, + gas: gas, + gasPrice: gasPrice + }) + .catch(error => { + if (shouldSucceed) { + console.error(error); + } + succeeded = false; + }); + + if (succeeded !== shouldSucceed) { + return false; + } else if (!shouldSucceed) { + return true; + } + + let assertionsPassed; + try { + assertionCallback(returnValues); + assertionsPassed = true; + } catch (error) { + assertionsPassed = false; + console.log(error); + } + + return assertionsPassed; + } - return assertionsPassed - } - - async function call( - title, - instance, - method, - args, - from, - value, - gas, - gasPrice, - shouldSucceed, - assertionCallback - ) { - let succeeded = true - returnValues = await instance.methods[method](...args).call({ - from: from, - value: value, - gas: gas, - gasPrice: gasPrice - }).catch(error => { - if (shouldSucceed) { - console.error(error) - } - succeeded = false - }) - - if (succeeded !== shouldSucceed) { - return false - } else if (!shouldSucceed) { - return true - } + async function deploy( + title, + instance, + args, + from, + value, + gas, + gasPrice, + shouldSucceed, + assertionCallback + ) { + let deployData = instance.deploy({ arguments: args }).encodeABI(); + let deployGas = await web3.eth + .estimateGas({ + from: from, + data: deployData + }) + .catch(error => { + if (shouldSucceed) { + console.error(error); + } + return gasLimit; + }); + + if (deployGas > gasLimit) { + console.error( + ` ✘ ${title}: deployment costs exceed block gas limit!` + ); + process.exit(1); + } + + if (typeof gas === "undefined") { + gas = deployGas; + } + + if (deployGas > gas) { + console.error( + ` ✘ ${title}: deployment costs exceed supplied gas.` + ); + process.exit(1); + } + + let signed; + let deployHash; + let receipt; + const contract = await instance + .deploy({ arguments: args }) + .send({ + from: from, + gas: gas, + gasPrice: gasPrice + }) + .on("transactionHash", hash => { + deployHash = hash; + }) + .on("receipt", r => { + receipt = r; + }) + .on("confirmation", (confirmationNumber, r) => { + confirmations[r.transactionHash] = confirmationNumber; + }) + .catch(error => { + if (shouldSucceed) { + console.error(error); + } + + receipt = { status: false }; + }); + + if (receipt.status !== shouldSucceed) { + if (contract) { + return [false, contract, gas]; + } + return [false, instance, gas]; + } else if (!shouldSucceed) { + if (contract) { + return [true, contract, gas]; + } + return [true, instance, gas]; + } + + assert.ok(receipt.status); + + let assertionsPassed; + try { + assertionCallback(receipt); + assertionsPassed = true; + } catch (error) { + assertionsPassed = false; + } + + if (contract) { + return [assertionsPassed, contract, gas]; + } + return [assertionsPassed, instance, gas]; + } - let assertionsPassed - try { - assertionCallback(returnValues) - assertionsPassed = true - } catch(error) { - assertionsPassed = false - console.log(error); - } + async function runTest( + title, + instance, + method, + callOrSend, + args, + shouldSucceed, + assertionCallback, + from, + value, + gas + ) { + if (typeof callOrSend === "undefined") { + callOrSend = "send"; + } + if (typeof args === "undefined") { + args = []; + } + if (typeof shouldSucceed === "undefined") { + shouldSucceed = true; + } + if (typeof assertionCallback === "undefined") { + assertionCallback = value => {}; + } + if (typeof from === "undefined") { + from = address; + } + if (typeof value === "undefined") { + value = 0; + } + if (typeof gas === "undefined" && callOrSend !== "deploy") { + gas = 6009006; + if (testingContext === "coverage") { + gas = gasLimit - 1; + } + } + let ok = false; + let contract; + let deployGas; + if (callOrSend === "send") { + ok = await send( + title, + instance, + method, + args, + from, + value, + gas, + 1, + shouldSucceed, + assertionCallback + ); + } else if (callOrSend === "call") { + ok = await call( + title, + instance, + method, + args, + from, + value, + gas, + 1, + shouldSucceed, + assertionCallback + ); + } else if (callOrSend === "deploy") { + const fields = await deploy( + title, + instance, + args, + from, + value, + gas, + 1, + shouldSucceed, + assertionCallback + ); + ok = fields[0]; + contract = fields[1]; + deployGas = fields[2]; + } else { + console.error("must use call, send, or deploy!"); + process.exit(1); + } + + if (ok) { + console.log( + ` ✓ ${ + callOrSend === "deploy" ? "successful " : "" + }${title}${ + callOrSend === "deploy" ? ` (${deployGas} gas)` : "" + }` + ); + passed++; + } else { + console.log( + ` ✘ ${callOrSend === "deploy" ? "failed " : ""}${title}${ + callOrSend === "deploy" ? ` (${deployGas} gas)` : "" + }` + ); + failed++; + } + + if (contract) { + return contract; + } + } - return assertionsPassed - } - - async function deploy( - title, - instance, - args, - from, - value, - gas, - gasPrice, - shouldSucceed, - assertionCallback - ) { - let deployData = instance.deploy({arguments: args}).encodeABI() - let deployGas = await web3.eth.estimateGas({ - from: from, - data: deployData - }).catch(error => { - if (shouldSucceed) { - console.error(error) - } - return gasLimit - }) - - if (deployGas > gasLimit) { - console.error(` ✘ ${title}: deployment costs exceed block gas limit!`) - process.exit(1) - } + async function setupNewDefaultAddress(newPrivateKey) { + const pubKey = await web3.eth.accounts.privateKeyToAccount( + newPrivateKey + ); + await web3.eth.accounts.wallet.add(pubKey); + + const txCount = await web3.eth.getTransactionCount(pubKey.address); + + if (txCount > 0) { + console.warn( + `warning: ${ + pubKey.address + } has already been used, which may cause ` + + "some tests to fail or to be skipped." + ); + } + + await web3.eth.sendTransaction({ + from: originalAddress, + to: pubKey.address, + value: 10 ** 18, + gas: "0x5208", + gasPrice: "0x4A817C800" + }); + + return pubKey.address; + } - if (typeof(gas) === 'undefined') { - gas = deployGas - } + // *************************** deploy contracts *************************** // + const currentSaiCode = await web3.eth.getCode( + constants.SAI_MAINNET_ADDRESS + ); + if (currentSaiCode !== "0x") { + console.log("contracts already set up, skipping..."); + return 0; + } - if (deployGas > gas) { - console.error(` ✘ ${title}: deployment costs exceed supplied gas.`) - process.exit(1) - } + console.log("funding mcd deployer address..."); + await web3.eth.sendTransaction({ + from: originalAddress, + to: "0xb5b06a16621616875A6C2637948bF98eA57c58fa", + value: web3.utils.toWei("0.1", "ether"), + gas: testingContext !== "coverage" ? "0x5208" : gasLimit - 1, + gasPrice: 1 + }); + + console.log("funding Dai migrator deployer address..."); + await web3.eth.sendTransaction({ + from: originalAddress, + to: "0xddb108893104de4e1c6d0e47c42237db4e617acc", + value: web3.utils.toWei("0.8", "ether"), + gas: testingContext !== "coverage" ? "0x5208" : gasLimit - 1, + gasPrice: 1 + }); + + console.log("funding dai deployer address..."); + await web3.eth.sendTransaction({ + from: originalAddress, + to: "0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9", + value: web3.utils.toWei("10", "ether"), + gas: testingContext !== "coverage" ? "0x5208" : gasLimit - 1, + gasPrice: 1 + }); + + console.log("funding usdc deployer address..."); + await web3.eth.sendTransaction({ + from: originalAddress, + to: "0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911", + value: web3.utils.toWei("10", "ether"), + gas: testingContext !== "coverage" ? "0x5208" : gasLimit - 1, + gasPrice: 1 + }); + + console.log("funding Compound deployer address..."); + await web3.eth.sendTransaction({ + from: originalAddress, + to: "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6", + value: web3.utils.toWei("10", "ether"), + gas: testingContext !== "coverage" ? "0x5208" : gasLimit - 1, + gasPrice: 1 + }); + + console.log("deploying mock price oracle contract..."); + const priceOracleDeployReceipt = await web3.eth.sendTransaction({ + from: address, + gas: testingContext !== "coverage" ? "1000000" : gasLimit - 1, + gasPrice: 1, + data: mockPriceOracleDeploymentData + }); + + assert.strictEqual( + priceOracleDeployReceipt.contractAddress, + "0x43Af172dFC1017c775D789f5B6cDD375E3D8Fe14" + ); + + console.log("incrementing dai deployment nonce..."); + let daiDeployReceipt; + for (i = 0; i < 1; i++) { + daiDeployReceipt = await web3.eth.sendTransaction({ + from: "0xb5b06a16621616875A6C2637948bF98eA57c58fa", + gas: testingContext !== "coverage" ? "1000000" : gasLimit - 1, + gasPrice: 1, + data: "0x3838533838f3" + }); + } - let signed - let deployHash - let receipt - const contract = await instance.deploy({arguments: args}).send({ - from: from, - gas: gas, - gasPrice: gasPrice - }).on('transactionHash', hash => { - deployHash = hash - }).on('receipt', r => { - receipt = r - }).on('confirmation', (confirmationNumber, r) => { - confirmations[r.transactionHash] = confirmationNumber - }).catch(error => { - if (shouldSucceed) { - console.error(error) - } - - receipt = {status: false} - }) - - if (receipt.status !== shouldSucceed) { - if (contract) { - return [false, contract, gas] - } - return [false, instance, gas] - } else if (!shouldSucceed) { - if (contract) { - return [true, contract, gas] - } - return [true, instance, gas] - } + console.log("deploying mock Dai..."); + daiDeployReceipt = await web3.eth.sendTransaction({ + from: "0xb5b06a16621616875A6C2637948bF98eA57c58fa", + gas: testingContext !== "coverage" ? "1000000" : gasLimit - 1, + gasPrice: 1, + data: mockDaiDeploymentData + }); + + assert.strictEqual( + daiDeployReceipt.contractAddress, + constants.DAI_MAINNET_ADDRESS + ); + + console.log("incrementing Sai deployment nonce..."); + let saiDeployReceipt; + for (i = 0; i < 4; i++) { + saiDeployReceipt = await web3.eth.sendTransaction({ + from: "0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9", + gas: testingContext !== "coverage" ? "1000000" : gasLimit - 1, + gasPrice: 1, + data: "0x3838533838f3" + }); + } - assert.ok(receipt.status) + console.log("deploying mock Sai..."); + saiDeployReceipt = await web3.eth.sendTransaction({ + from: "0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9", + gas: testingContext !== "coverage" ? "1000000" : gasLimit - 1, + gasPrice: 1, + data: mockDaiDeploymentData + }); + + assert.strictEqual( + saiDeployReceipt.contractAddress, + constants.SAI_MAINNET_ADDRESS + ); + + console.log( + "incrementing Dai migrator deployment nonce (this takes ~30 seconds)..." + ); + let daiMigratorDeployReceipt; + for (i = 0; i < 1250; i++) { + daiMigratorDeployReceipt = await web3.eth + .sendTransaction({ + from: "0xddb108893104de4e1c6d0e47c42237db4e617acc", + to: "0xddb108893104de4e1c6d0e47c42237db4e617acc", + gas: + testingContext !== "coverage" + ? "1000000" + : gasLimit - 1, + gasPrice: 1, + data: "0x" + }) + .catch(console.error); + } - let assertionsPassed - try { - assertionCallback(receipt) - assertionsPassed = true - } catch(error) { - assertionsPassed = false - } + console.log("deploying mock Dai migrator..."); + daiMigratorDeployReceipt = await web3.eth.sendTransaction({ + from: "0xddb108893104de4e1c6d0e47c42237db4e617acc", + gas: testingContext !== "coverage" ? "1000000" : gasLimit - 1, + gasPrice: 1, + data: MockSaiToDaiMigratorArtifact.bytecode + }); + + assert.strictEqual( + daiMigratorDeployReceipt.contractAddress, + constants.DAI_MIGRATOR_MAINNET_ADDRESS + ); + + await runTest( + "Transfer Dai to whale address", + DAI, + "transfer", + "send", + [ + constants.DAI_WHALE_ADDRESS, + "8555083659983933209597798445644913612440610624038028786991485007418559037440" + ], + true, + receipt => {}, + "0xb5b06a16621616875A6C2637948bF98eA57c58fa" + ); + + await runTest( + "Transfer Dai to migrator address", + DAI, + "transfer", + "send", + [ + constants.DAI_MIGRATOR_MAINNET_ADDRESS, + "1000000000000000000000000000000000000000000000000000000000000000000000000000" + ], + true, + receipt => {}, + "0xb5b06a16621616875A6C2637948bF98eA57c58fa" + ); + + await runTest( + "Transfer Sai to whale address", + SAI, + "transfer", + "send", + [ + constants.SAI_WHALE_ADDRESS, + "8555083659983933209597798445644913612440610624038028786991485007418559037440" + ], + true, + receipt => {}, + "0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9" + ); + + await runTest( + "Transfer Dai to primary address", + SAI, + "transfer", + "send", + [ + address, + "1000000000000000000000000000000000000000000000000000000000000000000000000000" + ], + true, + receipt => {}, + "0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9" + ); + + await runTest( + "Dai totalSupply is reachable", + SAI, + "totalSupply", + "call", + [], + true, + value => { + assert.strictEqual( + value, + "108555083659983933209597798445644913612440610624038028786991485007418559037440" + ); + } + ); + + console.log("incrementing usdc deployment nonce..."); + let usdcDeployReceipt; + for (i = 0; i < 20; i++) { + usdcDeployReceipt = await web3.eth.sendTransaction({ + from: "0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911", + gas: testingContext !== "coverage" ? "1000000" : gasLimit - 1, + gasPrice: 1, + data: "0x3838533838f3" + }); + } - if (contract) { - return [assertionsPassed, contract, gas] - } - return [assertionsPassed, instance, gas] - } - - async function runTest( - title, - instance, - method, - callOrSend, - args, - shouldSucceed, - assertionCallback, - from, - value, - gas - ) { - if (typeof(callOrSend) === 'undefined') { - callOrSend = 'send' - } - if (typeof(args) === 'undefined') { - args = [] - } - if (typeof(shouldSucceed) === 'undefined') { - shouldSucceed = true - } - if (typeof(assertionCallback) === 'undefined') { - assertionCallback = (value) => {} - } - if (typeof(from) === 'undefined') { - from = address - } - if (typeof(value) === 'undefined') { - value = 0 - } - if (typeof(gas) === 'undefined' && callOrSend !== 'deploy') { - gas = 6009006 - if (testingContext === 'coverage') { - gas = gasLimit - 1 - } - } - let ok = false - let contract - let deployGas - if (callOrSend === 'send') { - ok = await send( - title, - instance, - method, - args, - from, - value, - gas, - 1, - shouldSucceed, - assertionCallback - ) - } else if (callOrSend === 'call') { - ok = await call( - title, - instance, - method, - args, - from, - value, - gas, - 1, - shouldSucceed, - assertionCallback - ) - } else if (callOrSend === 'deploy') { - const fields = await deploy( - title, - instance, - args, - from, - value, - gas, - 1, - shouldSucceed, - assertionCallback - ) - ok = fields[0] - contract = fields[1] - deployGas = fields[2] - } else { - console.error('must use call, send, or deploy!') - process.exit(1) - } + console.log("deploying mock USDC..."); + usdcDeployReceipt = await web3.eth.sendTransaction({ + from: "0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911", + gas: testingContext !== "coverage" ? "4000000" : gasLimit - 1, + gasPrice: 1, + data: mockUSDCDeploymentData + }); + + assert.strictEqual( + usdcDeployReceipt.contractAddress, + constants.USDC_MAINNET_ADDRESS + ); + + await runTest("initialize USDC", FIAT_TOKEN, "initialize", "send", [ + "USD//C", + "USDC", + "USD", + 6, + address, + address, + address, + address + ]); + + await runTest( + "add USDC minter", + FIAT_TOKEN, + "configureMinter", + "send", + [ + address, + "0xf000000000000000000000000000000000000000000000000000000000000000" + ] + ); + + await runTest( + "Mint USDC to whale address", + FIAT_TOKEN, + "mint", + "send", + [ + constants.USDC_WHALE_ADDRESS, + "8555083659983933209597798445644913612440610624038028786991485007418559037440" + ] + ); + + await runTest( + "Mint USDC to primary address", + FIAT_TOKEN, + "mint", + "send", + [ + address, + "100000000000000000000000000000000000000000000000000000000000000000000000000000" + ] + ); + + await runTest( + "USDC totalSupply is reachable", + USDC, + "totalSupply", + "call", + [], + true, + value => { + assert.strictEqual( + value, + "108555083659983933209597798445644913612440610624038028786991485007418559037440" + ); + } + ); + + await runTest( + "blacklist a USDC address", + FIAT_TOKEN, + "blacklist", + "send", + [constants.MOCK_USDC_BLACKLISTED_ADDRESS] + ); + + console.log("deploying Compound unitroller..."); + const unitrollerDeploymentReceipt = await web3.eth.sendTransaction({ + from: "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6", + gas: testingContext !== "coverage" ? "1000000" : gasLimit - 1, + gasPrice: 1, + data: mockUnitrollerDeploymentData + }); + + assert.strictEqual( + unitrollerDeploymentReceipt.contractAddress, + constants.COMPTROLLER_MAINNET_ADDRESS + ); + + console.log("deploying v0 Compound comptroller..."); + let comptrollerDeploymentReceipt = await web3.eth.sendTransaction({ + from: "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6", + gas: testingContext !== "coverage" ? "5000000" : gasLimit - 1, + gasPrice: 1, + data: mockCurrentComptrollerDeploymentData + }); + + let COMPTROLLER = new web3.eth.Contract( + COMPTROLLER_ABI, + comptrollerDeploymentReceipt.contractAddress + ); + + const UNITROLLER_COMPTROLLER = new web3.eth.Contract( + COMPTROLLER_ABI, + UNITROLLER.options.address + ); + + await runTest( + "Set pending Comptroller on Unitroller", + UNITROLLER, + "_setPendingImplementation", + "send", + [COMPTROLLER.options.address], + true, + receipt => {}, + "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6" + ); + + await runTest( + "Set Comptroller on Unitroller", + COMPTROLLER, + "_become", + "send", + [ + UNITROLLER.options.address, + priceOracleDeployReceipt.contractAddress, + "500000000000000000", + 20, + false + ], + true, + receipt => {}, + "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6" + ); + + await runTest( + "comptroller implementation is set correctly", + UNITROLLER, + "comptrollerImplementation", + "call", + [], + true, + value => { + assert.strictEqual(value, COMPTROLLER.options.address); + } + ); + + console.log("incrementing Compound deployment nonce..."); + let compoundDeployReceipt; + for (i = 4; i < 7; i++) { + compoundDeployReceipt = await web3.eth.sendTransaction({ + from: "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6", + gas: testingContext !== "coverage" ? "1000000" : gasLimit - 1, + gasPrice: 1, + data: "0x3838533838f3" + }); + } - if (ok) { - console.log( - ` ✓ ${ - callOrSend === 'deploy' ? 'successful ' : '' - }${title}${ - callOrSend === 'deploy' ? ` (${deployGas} gas)` : '' - }` - ) - passed++ - } else { - console.log( - ` ✘ ${ - callOrSend === 'deploy' ? 'failed ' : '' - }${title}${ - callOrSend === 'deploy' ? ` (${deployGas} gas)` : '' - }` - ) - failed++ - } + console.log("deploying Compound cSAI IRM..."); + const cSAIIRMDeploymentReceipt = await web3.eth.sendTransaction({ + from: "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6", + gas: testingContext !== "coverage" ? "1000000" : gasLimit - 1, + gasPrice: 1, + data: mockCDaiIRMDeploymentData + }); + + assert.strictEqual( + cSAIIRMDeploymentReceipt.contractAddress, + "0xa1046abfc2598F48C44Fb320d281d3F3c0733c9a" + ); + + console.log("deploying Compound cUSDC IRM..."); + const cUSDCIRMDeploymentReceipt = await web3.eth.sendTransaction({ + from: "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6", + gas: testingContext !== "coverage" ? "1000000" : gasLimit - 1, + gasPrice: 1, + data: mockCUSDCIRMDeploymentData + }); + + assert.strictEqual( + cUSDCIRMDeploymentReceipt.contractAddress, + "0xc64C4cBA055eFA614CE01F4BAD8A9F519C4f8FaB" + ); + + console.log("incrementing Compound deployment nonce..."); + for (i = 9; i < 14; i++) { + compoundDeployReceipt = await web3.eth.sendTransaction({ + from: "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6", + gas: testingContext !== "coverage" ? "1000000" : gasLimit - 1, + gasPrice: 1, + data: "0x3838533838f3" + }); + } - if (contract) { - return contract - } - } + console.log("deploying Compound cSai..."); + const cSaiDeploymentReceipt = await web3.eth.sendTransaction({ + from: "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6", + gas: testingContext !== "coverage" ? "7000000" : gasLimit - 1, + gasPrice: 1, + data: mockCDaiDeploymentData + }); + + assert.strictEqual( + cSaiDeploymentReceipt.contractAddress, + constants.CSAI_MAINNET_ADDRESS + ); + + for (i = 15; i < 17; i++) { + compoundDeployReceipt = await web3.eth.sendTransaction({ + from: "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6", + gas: testingContext !== "coverage" ? "1000000" : gasLimit - 1, + gasPrice: 1, + data: "0x3838533838f3" + }); + } - async function setupNewDefaultAddress(newPrivateKey) { - const pubKey = await web3.eth.accounts.privateKeyToAccount(newPrivateKey) - await web3.eth.accounts.wallet.add(pubKey) + console.log("deploying Compound cUSDC..."); + const cUSDCDeploymentReceipt = await web3.eth.sendTransaction({ + from: "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6", + gas: testingContext !== "coverage" ? "7000000" : gasLimit - 1, + gasPrice: 1, + data: mockCUSDCDeploymentData + }); + + assert.strictEqual( + cUSDCDeploymentReceipt.contractAddress, + constants.CUSDC_MAINNET_ADDRESS + ); + + for (i = 18; i < 68; i++) { + compoundDeployReceipt = await web3.eth.sendTransaction({ + from: "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6", + gas: testingContext !== "coverage" ? "1000000" : gasLimit - 1, + gasPrice: 1, + data: "0x3838533838f3" + }); + } - const txCount = await web3.eth.getTransactionCount(pubKey.address) + console.log("deploying current Compound comptroller..."); + comptrollerDeploymentReceipt = await web3.eth.sendTransaction({ + from: "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6", + gas: testingContext !== "coverage" ? "5000000" : gasLimit - 1, + gasPrice: 1, + data: mockCurrentComptrollerDeploymentData + }); + + assert.strictEqual( + comptrollerDeploymentReceipt.contractAddress, + "0x178053c06006e67e09879C09Ff012fF9d263dF29" + ); + + COMPTROLLER = new web3.eth.Contract( + COMPTROLLER_ABI, + comptrollerDeploymentReceipt.contractAddress + ); + + await runTest( + "Set pending Comptroller on Unitroller", + UNITROLLER, + "_setPendingImplementation", + "send", + [comptrollerDeploymentReceipt.contractAddress], + true, + receipt => {}, + "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6" + ); + + await runTest( + "Set Comptroller on Unitroller", + COMPTROLLER, + "_become", + "send", + [ + UNITROLLER.options.address, + priceOracleDeployReceipt.contractAddress, + "500000000000000000", + 20, + true + ], + true, + receipt => {}, + "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6" + ); + + await runTest( + "comptroller implementation is set correctly", + UNITROLLER, + "comptrollerImplementation", + "call", + [], + true, + value => { + assert.strictEqual(value, COMPTROLLER.options.address); + } + ); + + await runTest( + "Set pending admin on Unitroller", + UNITROLLER, + "_setPendingAdmin", + "send", + [address], + true, + receipt => {}, + "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6" + ); + + await runTest( + "Set new admin on Unitroller", + UNITROLLER, + "_acceptAdmin" + ); + + await runTest( + "comptroller admin is set correctly", + UNITROLLER, + "admin", + "call", + [], + true, + value => { + assert.strictEqual(value, address); + } + ); + + console.log("incrementing Compound deployment nonce..."); + for (i = 72; i < 90; i++) { + compoundDeployReceipt = await web3.eth.sendTransaction({ + from: "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6", + gas: testingContext !== "coverage" ? "1000000" : gasLimit - 1, + gasPrice: 1, + data: "0x3838533838f3" + }); + } - if (txCount > 0) { - console.warn( - `warning: ${pubKey.address} has already been used, which may cause ` + - 'some tests to fail or to be skipped.' - ) - } + console.log("deploying Compound cDai..."); + const daiDeploymentReceipt = await web3.eth.sendTransaction({ + from: "0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6", + gas: testingContext !== "coverage" ? "7000000" : gasLimit - 1, + gasPrice: 1, + data: mockCDaiDeploymentData.replace( + "89d24a6b4ccb1b6faa2625fe562bdd9a23260359", + constants.DAI_MAINNET_ADDRESS.slice(2) + ) + }); + + assert.strictEqual( + daiDeploymentReceipt.contractAddress, + constants.CDAI_MAINNET_ADDRESS + ); + + await runTest( + "List cSai on Comptroller", + UNITROLLER_COMPTROLLER, + "_supportMarket", + "send", + [CSAI.options.address] + ); + + await runTest( + "List cUSDC on Comptroller", + UNITROLLER_COMPTROLLER, + "_supportMarket", + "send", + [CUSDC.options.address] + ); + + await runTest( + "List cDai on Comptroller", + UNITROLLER_COMPTROLLER, + "_supportMarket", + "send", + [CDAI.options.address] + ); + + await runTest( + "Call MockSaiToDaiMigrator", + MockSaiToDaiMigrator, + "swapSaiToDai", + "send", + [0] + ); + + // TODO: list increase cDAI and cUSDC collateral factor on comptroller + + // TODO: set prices using price oracle + + // TODO: verify comptroller state + + // TODO: supply and borrow some assets in each market + + console.log( + `completed ${passed + failed} test${ + passed + failed === 1 ? "" : "s" + } ` + `with ${failed} failure${failed === 1 ? "" : "s"}.` + ); + + if (failed > 0) { + process.exit(1); + } - await web3.eth.sendTransaction({ - from: originalAddress, - to: pubKey.address, - value: 10 ** 18, - gas: '0x5208', - gasPrice: '0x4A817C800' - }) - - return pubKey.address - } - - // *************************** deploy contracts *************************** // - const currentSaiCode = await web3.eth.getCode(constants.SAI_MAINNET_ADDRESS) - if (currentSaiCode !== '0x') { - console.log('contracts already set up, skipping...') - return 0 - } - - console.log('funding mcd deployer address...') - await web3.eth.sendTransaction({ - from: originalAddress, - to: '0xb5b06a16621616875A6C2637948bF98eA57c58fa', - value: web3.utils.toWei('0.1', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : gasLimit - 1, - gasPrice: 1 - }) - - console.log('funding Dai migrator deployer address...') - await web3.eth.sendTransaction({ - from: originalAddress, - to: '0xddb108893104de4e1c6d0e47c42237db4e617acc', - value: web3.utils.toWei('0.8', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : gasLimit - 1, - gasPrice: 1 - }) - - console.log('funding dai deployer address...') - await web3.eth.sendTransaction({ - from: originalAddress, - to: '0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9', - value: web3.utils.toWei('10', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : gasLimit - 1, - gasPrice: 1 - }) - - console.log('funding usdc deployer address...') - await web3.eth.sendTransaction({ - from: originalAddress, - to: '0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911', - value: web3.utils.toWei('10', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : gasLimit - 1, - gasPrice: 1 - }) - - console.log('funding Compound deployer address...') - await web3.eth.sendTransaction({ - from: originalAddress, - to: '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6', - value: web3.utils.toWei('10', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : gasLimit - 1, - gasPrice: 1 - }) - - console.log('deploying mock price oracle contract...') - const priceOracleDeployReceipt = await web3.eth.sendTransaction({ - from: address, - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: mockPriceOracleDeploymentData - }) - - assert.strictEqual( - priceOracleDeployReceipt.contractAddress, - '0x43Af172dFC1017c775D789f5B6cDD375E3D8Fe14' - ) - - console.log('incrementing dai deployment nonce...') - let daiDeployReceipt - for (i = 0; i < 1; i++) { - daiDeployReceipt = await web3.eth.sendTransaction({ - from: '0xb5b06a16621616875A6C2637948bF98eA57c58fa', - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: '0x3838533838f3' - }) - } - - console.log('deploying mock Dai...') - daiDeployReceipt = await web3.eth.sendTransaction({ - from: '0xb5b06a16621616875A6C2637948bF98eA57c58fa', - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: mockDaiDeploymentData - }) - - assert.strictEqual( - daiDeployReceipt.contractAddress, constants.DAI_MAINNET_ADDRESS - ) - - console.log('incrementing Sai deployment nonce...') - let saiDeployReceipt - for (i = 0; i < 4; i++) { - saiDeployReceipt = await web3.eth.sendTransaction({ - from: '0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9', - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: '0x3838533838f3' - }) - } - - console.log('deploying mock Sai...') - saiDeployReceipt = await web3.eth.sendTransaction({ - from: '0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9', - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: mockDaiDeploymentData - }) - - assert.strictEqual( - saiDeployReceipt.contractAddress, constants.SAI_MAINNET_ADDRESS - ) - - console.log( - 'incrementing Dai migrator deployment nonce (this takes ~30 seconds)...' - ) - let daiMigratorDeployReceipt - for (i = 0; i < 1250; i++) { - daiMigratorDeployReceipt = await web3.eth.sendTransaction({ - from: '0xddb108893104de4e1c6d0e47c42237db4e617acc', - to: '0xddb108893104de4e1c6d0e47c42237db4e617acc', - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: '0x' - }).catch(console.error) - } - - console.log('deploying mock Dai migrator...') - daiMigratorDeployReceipt = await web3.eth.sendTransaction({ - from: '0xddb108893104de4e1c6d0e47c42237db4e617acc', - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: MockSaiToDaiMigratorArtifact.bytecode - }) - - assert.strictEqual( - daiMigratorDeployReceipt.contractAddress, - constants.DAI_MIGRATOR_MAINNET_ADDRESS - ) - - await runTest( - 'Transfer Dai to whale address', - DAI, - 'transfer', - 'send', - [ - constants.DAI_WHALE_ADDRESS, - '8555083659983933209597798445644913612440610624038028786991485007418559037440' - ], - true, - receipt => {}, - '0xb5b06a16621616875A6C2637948bF98eA57c58fa' - ) - - await runTest( - 'Transfer Dai to migrator address', - DAI, - 'transfer', - 'send', - [ - constants.DAI_MIGRATOR_MAINNET_ADDRESS, - '1000000000000000000000000000000000000000000000000000000000000000000000000000' - ], - true, - receipt => {}, - '0xb5b06a16621616875A6C2637948bF98eA57c58fa' - ) - - await runTest( - 'Transfer Sai to whale address', - SAI, - 'transfer', - 'send', - [ - constants.SAI_WHALE_ADDRESS, - '8555083659983933209597798445644913612440610624038028786991485007418559037440' - ], - true, - receipt => {}, - '0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9' - ) - - await runTest( - 'Transfer Dai to primary address', - SAI, - 'transfer', - 'send', - [ - address, - '1000000000000000000000000000000000000000000000000000000000000000000000000000' - ], - true, - receipt => {}, - '0x552F355CCb9b91C8FB47D9c011AbAD5B72EC30e9' - ) - - await runTest( - 'Dai totalSupply is reachable', - SAI, - 'totalSupply', - 'call', - [], - true, - value => { - assert.strictEqual( - value, - '108555083659983933209597798445644913612440610624038028786991485007418559037440' - ) - } - ) - - console.log('incrementing usdc deployment nonce...') - let usdcDeployReceipt - for (i = 0; i < 20; i++) { - usdcDeployReceipt = await web3.eth.sendTransaction({ - from: '0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911', - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: '0x3838533838f3' - }) - } - - console.log('deploying mock USDC...') - usdcDeployReceipt = await web3.eth.sendTransaction({ - from: '0x95Ba4cF87D6723ad9C0Db21737D862bE80e93911', - gas: (testingContext !== 'coverage') ? '4000000' : gasLimit - 1, - gasPrice: 1, - data: mockUSDCDeploymentData - }) - - assert.strictEqual( - usdcDeployReceipt.contractAddress, constants.USDC_MAINNET_ADDRESS - ) - - await runTest( - 'initialize USDC', - FIAT_TOKEN, - 'initialize', - 'send', - [ - 'USD//C', - 'USDC', - 'USD', - 6, - address, - address, - address, - address - ] - ) - - await runTest( - 'add USDC minter', - FIAT_TOKEN, - 'configureMinter', - 'send', - [ - address, - '0xf000000000000000000000000000000000000000000000000000000000000000' - ] - ) - - await runTest( - 'Mint USDC to whale address', - FIAT_TOKEN, - 'mint', - 'send', - [ - constants.USDC_WHALE_ADDRESS, - '8555083659983933209597798445644913612440610624038028786991485007418559037440' - ] - ) - - await runTest( - 'Mint USDC to primary address', - FIAT_TOKEN, - 'mint', - 'send', - [ - address, - '100000000000000000000000000000000000000000000000000000000000000000000000000000' - ] - ) - - await runTest( - 'USDC totalSupply is reachable', - USDC, - 'totalSupply', - 'call', - [], - true, - value => { - assert.strictEqual( - value, - '108555083659983933209597798445644913612440610624038028786991485007418559037440' - ) - } - ) - - await runTest( - 'blacklist a USDC address', - FIAT_TOKEN, - 'blacklist', - 'send', - [constants.MOCK_USDC_BLACKLISTED_ADDRESS] - ) - - console.log('deploying Compound unitroller...') - const unitrollerDeploymentReceipt = await web3.eth.sendTransaction({ - from: '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6', - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: mockUnitrollerDeploymentData - }) - - assert.strictEqual( - unitrollerDeploymentReceipt.contractAddress, - constants.COMPTROLLER_MAINNET_ADDRESS - ) - - console.log('deploying v0 Compound comptroller...') - let comptrollerDeploymentReceipt = await web3.eth.sendTransaction({ - from: '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6', - gas: (testingContext !== 'coverage') ? '5000000' : gasLimit - 1, - gasPrice: 1, - data: mockCurrentComptrollerDeploymentData - }) - - let COMPTROLLER = new web3.eth.Contract( - COMPTROLLER_ABI, - comptrollerDeploymentReceipt.contractAddress - ) - - const UNITROLLER_COMPTROLLER = new web3.eth.Contract( - COMPTROLLER_ABI, - UNITROLLER.options.address - ) - - await runTest( - 'Set pending Comptroller on Unitroller', - UNITROLLER, - '_setPendingImplementation', - 'send', - [ - COMPTROLLER.options.address - ], - true, - receipt => {}, - '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6' - ) - - await runTest( - 'Set Comptroller on Unitroller', - COMPTROLLER, - '_become', - 'send', - [ - UNITROLLER.options.address, - priceOracleDeployReceipt.contractAddress, - '500000000000000000', - 20, - false - ], - true, - receipt => {}, - '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6' - ) - - await runTest( - 'comptroller implementation is set correctly', - UNITROLLER, - 'comptrollerImplementation', - 'call', - [], - true, - value => { - assert.strictEqual(value, COMPTROLLER.options.address) - } - ) - - console.log('incrementing Compound deployment nonce...') - let compoundDeployReceipt - for (i = 4; i < 7; i++) { - compoundDeployReceipt = await web3.eth.sendTransaction({ - from: '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6', - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: '0x3838533838f3' - }) - } - - console.log('deploying Compound cSAI IRM...') - const cSAIIRMDeploymentReceipt = await web3.eth.sendTransaction({ - from: '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6', - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: mockCDaiIRMDeploymentData - }) - - assert.strictEqual( - cSAIIRMDeploymentReceipt.contractAddress, - '0xa1046abfc2598F48C44Fb320d281d3F3c0733c9a' - ) - - console.log('deploying Compound cUSDC IRM...') - const cUSDCIRMDeploymentReceipt = await web3.eth.sendTransaction({ - from: '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6', - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: mockCUSDCIRMDeploymentData - }) - - assert.strictEqual( - cUSDCIRMDeploymentReceipt.contractAddress, - '0xc64C4cBA055eFA614CE01F4BAD8A9F519C4f8FaB' - ) - - console.log('incrementing Compound deployment nonce...') - for (i = 9; i < 14; i++) { - compoundDeployReceipt = await web3.eth.sendTransaction({ - from: '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6', - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: '0x3838533838f3' - }) - } - - console.log('deploying Compound cSai...') - const cSaiDeploymentReceipt = await web3.eth.sendTransaction({ - from: '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6', - gas: (testingContext !== 'coverage') ? '7000000' : gasLimit - 1, - gasPrice: 1, - data: mockCDaiDeploymentData - }) - - assert.strictEqual( - cSaiDeploymentReceipt.contractAddress, constants.CSAI_MAINNET_ADDRESS - ) - - for (i = 15; i < 17; i++) { - compoundDeployReceipt = await web3.eth.sendTransaction({ - from: '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6', - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: '0x3838533838f3' - }) - } - - console.log('deploying Compound cUSDC...') - const cUSDCDeploymentReceipt = await web3.eth.sendTransaction({ - from: '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6', - gas: (testingContext !== 'coverage') ? '7000000' : gasLimit - 1, - gasPrice: 1, - data: mockCUSDCDeploymentData - }) - - assert.strictEqual( - cUSDCDeploymentReceipt.contractAddress, constants.CUSDC_MAINNET_ADDRESS - ) - - for (i = 18; i < 68; i++) { - compoundDeployReceipt = await web3.eth.sendTransaction({ - from: '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6', - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: '0x3838533838f3' - }) - } - - console.log('deploying current Compound comptroller...') - comptrollerDeploymentReceipt = await web3.eth.sendTransaction({ - from: '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6', - gas: (testingContext !== 'coverage') ? '5000000' : gasLimit - 1, - gasPrice: 1, - data: mockCurrentComptrollerDeploymentData - }) - - assert.strictEqual( - comptrollerDeploymentReceipt.contractAddress, - '0x178053c06006e67e09879C09Ff012fF9d263dF29' - ) - - COMPTROLLER = new web3.eth.Contract( - COMPTROLLER_ABI, - comptrollerDeploymentReceipt.contractAddress - ) - - await runTest( - 'Set pending Comptroller on Unitroller', - UNITROLLER, - '_setPendingImplementation', - 'send', - [ - comptrollerDeploymentReceipt.contractAddress - ], - true, - receipt => {}, - '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6' - ) - - await runTest( - 'Set Comptroller on Unitroller', - COMPTROLLER, - '_become', - 'send', - [ - UNITROLLER.options.address, - priceOracleDeployReceipt.contractAddress, - '500000000000000000', - 20, - true - ], - true, - receipt => {}, - '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6' - ) - - await runTest( - 'comptroller implementation is set correctly', - UNITROLLER, - 'comptrollerImplementation', - 'call', - [], - true, - value => { - assert.strictEqual(value, COMPTROLLER.options.address) - } - ) - - await runTest( - 'Set pending admin on Unitroller', - UNITROLLER, - '_setPendingAdmin', - 'send', - [ - address - ], - true, - receipt => {}, - '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6' - ) - - await runTest( - 'Set new admin on Unitroller', - UNITROLLER, - '_acceptAdmin' - ) - - await runTest( - 'comptroller admin is set correctly', - UNITROLLER, - 'admin', - 'call', - [], - true, - value => { - assert.strictEqual(value, address) + // exit. + return 0; } - ) - - console.log('incrementing Compound deployment nonce...') - for (i = 72; i < 90; i++) { - compoundDeployReceipt = await web3.eth.sendTransaction({ - from: '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6', - gas: (testingContext !== 'coverage') ? '1000000' : gasLimit - 1, - gasPrice: 1, - data: '0x3838533838f3' - }) - } - - console.log('deploying Compound cDai...') - const daiDeploymentReceipt = await web3.eth.sendTransaction({ - from: '0xA7ff0d561cd15eD525e31bbe0aF3fE34ac2059F6', - gas: (testingContext !== 'coverage') ? '7000000' : gasLimit - 1, - gasPrice: 1, - data: mockCDaiDeploymentData.replace( - '89d24a6b4ccb1b6faa2625fe562bdd9a23260359', - constants.DAI_MAINNET_ADDRESS.slice(2) - ) - }) - - assert.strictEqual( - daiDeploymentReceipt.contractAddress, constants.CDAI_MAINNET_ADDRESS - ) - - await runTest( - 'List cSai on Comptroller', - UNITROLLER_COMPTROLLER, - '_supportMarket', - 'send', - [ - CSAI.options.address - ] - ) - - await runTest( - 'List cUSDC on Comptroller', - UNITROLLER_COMPTROLLER, - '_supportMarket', - 'send', - [ - CUSDC.options.address - ] - ) - - await runTest( - 'List cDai on Comptroller', - UNITROLLER_COMPTROLLER, - '_supportMarket', - 'send', - [ - CDAI.options.address - ] - ) - - await runTest( - 'Call MockSaiToDaiMigrator', - MockSaiToDaiMigrator, - 'swapSaiToDai', - 'send', - [0] - ) - - // TODO: list increase cDAI and cUSDC collateral factor on comptroller - - // TODO: set prices using price oracle - - // TODO: verify comptroller state - - // TODO: supply and borrow some assets in each market - - console.log( - `completed ${passed + failed} test${passed + failed === 1 ? '' : 's'} ` + - `with ${failed} failure${failed === 1 ? '' : 's'}.` - ) - - if (failed > 0) { - process.exit(1) - } - - // exit. - return 0 -}} +}; diff --git a/scripts/test/test.js b/scripts/test/test.js index 160e97d..579ec57 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -1,8731 +1,8923 @@ -var assert = require('assert') -var fs = require('fs') -var util = require('ethereumjs-util') -const constants = require('./constants.js') +var assert = require("assert"); +var fs = require("fs"); +var util = require("ethereumjs-util"); +const constants = require("./constants.js"); const { web3 } = require("./web3"); const { Tester, longer } = require("./testHelpers"); -const { testAccountRecoveryManager } = require("./contracts/account-recovery/testAccountRecoveryManager"); -const { testUpgradeBeaconController } = require("./contracts/upgradeability/testUpgradeBeaconController"); -const { testUpgradeBeaconControllerManagerPartOne, testUpgradeBeaconControllerManagerPartTwo } = require("./contracts/upgradeability/testUpgradeBeaconControllerManager"); -const { testKeyRegistryV2 } = require("./contracts/registries/testKeyRegistryV2"); -const { testPerformingUpgrade } = require("./contracts/upgradeability/testPerformingUpgrade"); - -const AdharmaSmartWalletImplementationArtifact = require('../../build/contracts/AdharmaSmartWalletImplementation.json') -const AdharmaKeyRingImplementationArtifact = require('../../build/contracts/AdharmaKeyRingImplementation.json') - -const DharmaSmartWalletImplementationV6Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV6.json') -const DharmaSmartWalletImplementationV7Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV7.json') - -const DharmaKeyRingImplementationV1Artifact = require('../../build/contracts/DharmaKeyRingImplementationV1.json') - -const contractNames = Object.assign({}, constants.CONTRACT_NAMES) - +const { + testAccountRecoveryManager +} = require("./contracts/account-recovery/testAccountRecoveryManager"); +const { + testUpgradeBeaconController +} = require("./contracts/upgradeability/testUpgradeBeaconController"); +const { + testUpgradeBeaconControllerManagerPartOne, + testUpgradeBeaconControllerManagerPartTwo +} = require("./contracts/upgradeability/testUpgradeBeaconControllerManager"); +const { + testKeyRegistryV2 +} = require("./contracts/registries/testKeyRegistryV2"); +const { + testPerformingUpgrade +} = require("./contracts/upgradeability/testPerformingUpgrade"); + +const AdharmaSmartWalletImplementationArtifact = require("../../build/contracts/AdharmaSmartWalletImplementation.json"); +const AdharmaKeyRingImplementationArtifact = require("../../build/contracts/AdharmaKeyRingImplementation.json"); + +const DharmaSmartWalletImplementationV6Artifact = require("../../build/contracts/DharmaSmartWalletImplementationV6.json"); +const DharmaSmartWalletImplementationV7Artifact = require("../../build/contracts/DharmaSmartWalletImplementationV7.json"); + +const DharmaKeyRingImplementationV1Artifact = require("../../build/contracts/DharmaKeyRingImplementationV1.json"); + +const contractNames = Object.assign({}, constants.CONTRACT_NAMES); async function test(testingContext) { - const tester = new Tester(testingContext); - await tester.init(); - - console.log('running tests...') - - await tester.runTest( - `DharmaUpgradeBeaconController can transfer owner`, - tester.DharmaUpgradeBeaconController, - 'transferOwnership', - 'send', - [tester.address] - ) - - await tester.runTest( - 'Dharma Key Registry V2 gets the initial global key correctly', - tester.DharmaKeyRegistryV2, - 'getGlobalKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - const messageV2 = ( - tester.DharmaKeyRegistryV2.options.address + - tester.address.slice(2) + - web3.utils.asciiToHex( - "This signature demonstrates that the supplied signing key is valid." - ).slice(2) - ) - - const v2KeySignature = tester.signHashedPrefixedHashedHexString(messageV2, tester.address) - - await tester.runTest( - 'Dharma Key Registry V2 cannot set a previously used global key', - tester.DharmaKeyRegistryV2, - 'setGlobalKey', - 'send', - [ - tester.address, - v2KeySignature - ], - false - ) - - const BadBeacon = await tester.runTest( - `Mock Bad Beacon contract deployment`, - tester.BadBeaconDeployer, - '', - 'deploy' - ) - - const BadBeaconTwo = await tester.runTest( - `Mock Bad Beacon Two contract deployment`, - tester.BadBeaconTwoDeployer, - '', - 'deploy' - ) - - const DharmaSmartWalletImplementationV6 = await tester.runTest( - `DharmaSmartWalletImplementationV6 contract deployment`, - tester.DharmaSmartWalletImplementationV6Deployer, - '', - 'deploy' - ) - - const DharmaSmartWalletImplementationV7 = await tester.runTest( - `DharmaSmartWalletImplementationV7 contract deployment`, - tester.DharmaSmartWalletImplementationV7Deployer, - '', - 'deploy' - ) - - const DharmaKeyRingImplementationV1 = await tester.runTest( - `DharmaKeyRingImplementationV1 contract deployment`, - tester.DharmaKeyRingImplementationV1Deployer, - '', - 'deploy' - ) - - await tester.runTest( - 'Dharma Upgrade Beacon Controller cannot set null address as implementation', - tester.DharmaUpgradeBeaconController, - 'upgrade', - 'send', - [ - tester.DharmaUpgradeBeacon.options.address, - constants.NULL_ADDRESS - ], - false - ) - - await tester.runTest( - 'Dharma Upgrade Beacon Controller cannot set non-contract as implementation', - tester.DharmaUpgradeBeaconController, - 'upgrade', - 'send', - [ - tester.DharmaUpgradeBeacon.options.address, - tester.address - ], - false - ) - - await tester.runTest( - 'Dharma Upgrade Beacon Controller cannot support a "bad" beacon that throws', - tester.DharmaUpgradeBeaconController, - 'upgrade', - 'send', - [ - BadBeacon.options.address, - DharmaSmartWalletImplementationV6.options.address - ], - false - ) - - await tester.runTest( - 'Dharma Upgrade Beacon Controller cannot upgrade a non-upgradeable beacon', - tester.DharmaUpgradeBeaconController, - 'upgrade', - 'send', - [ - BadBeaconTwo.options.address, - DharmaSmartWalletImplementationV6.options.address - ], - false - ) - - await tester.runTest( - 'Dharma Upgrade Beacon Controller is inaccessible from a non-owner', - tester.DharmaUpgradeBeaconController, - 'upgrade', - 'send', - [ - tester.DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV6.options.address - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'Dharma Upgrade Beacon Controller can set initial upgrade beacon implementation', - tester.DharmaUpgradeBeaconController, - 'upgrade', - 'send', - [ - tester.DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV6.options.address - ], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Upgraded.returnValues.upgradeBeacon, - tester.DharmaUpgradeBeacon.options.address - ) - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementation, - constants.NULL_ADDRESS - ) - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementationCodeHash, - constants.EMPTY_HASH - ) - assert.strictEqual( - receipt.events.Upgraded.returnValues.newImplementation, - DharmaSmartWalletImplementationV6.options.address - ) - /* TODO + const tester = new Tester(testingContext); + await tester.init(); + + console.log("running tests..."); + + await tester.runTest( + `DharmaUpgradeBeaconController can transfer owner`, + tester.DharmaUpgradeBeaconController, + "transferOwnership", + "send", + [tester.address] + ); + + await tester.runTest( + "Dharma Key Registry V2 gets the initial global key correctly", + tester.DharmaKeyRegistryV2, + "getGlobalKey", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.address); + } + ); + + const messageV2 = + tester.DharmaKeyRegistryV2.options.address + + tester.address.slice(2) + + web3.utils + .asciiToHex( + "This signature demonstrates that the supplied signing key is valid." + ) + .slice(2); + + const v2KeySignature = tester.signHashedPrefixedHashedHexString( + messageV2, + tester.address + ); + + await tester.runTest( + "Dharma Key Registry V2 cannot set a previously used global key", + tester.DharmaKeyRegistryV2, + "setGlobalKey", + "send", + [tester.address, v2KeySignature], + false + ); + + const BadBeacon = await tester.runTest( + `Mock Bad Beacon contract deployment`, + tester.BadBeaconDeployer, + "", + "deploy" + ); + + const BadBeaconTwo = await tester.runTest( + `Mock Bad Beacon Two contract deployment`, + tester.BadBeaconTwoDeployer, + "", + "deploy" + ); + + const DharmaSmartWalletImplementationV6 = await tester.runTest( + `DharmaSmartWalletImplementationV6 contract deployment`, + tester.DharmaSmartWalletImplementationV6Deployer, + "", + "deploy" + ); + + const DharmaSmartWalletImplementationV7 = await tester.runTest( + `DharmaSmartWalletImplementationV7 contract deployment`, + tester.DharmaSmartWalletImplementationV7Deployer, + "", + "deploy" + ); + + const DharmaKeyRingImplementationV1 = await tester.runTest( + `DharmaKeyRingImplementationV1 contract deployment`, + tester.DharmaKeyRingImplementationV1Deployer, + "", + "deploy" + ); + + await tester.runTest( + "Dharma Upgrade Beacon Controller cannot set null address as implementation", + tester.DharmaUpgradeBeaconController, + "upgrade", + "send", + [tester.DharmaUpgradeBeacon.options.address, constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + "Dharma Upgrade Beacon Controller cannot set non-contract as implementation", + tester.DharmaUpgradeBeaconController, + "upgrade", + "send", + [tester.DharmaUpgradeBeacon.options.address, tester.address], + false + ); + + await tester.runTest( + 'Dharma Upgrade Beacon Controller cannot support a "bad" beacon that throws', + tester.DharmaUpgradeBeaconController, + "upgrade", + "send", + [ + BadBeacon.options.address, + DharmaSmartWalletImplementationV6.options.address + ], + false + ); + + await tester.runTest( + "Dharma Upgrade Beacon Controller cannot upgrade a non-upgradeable beacon", + tester.DharmaUpgradeBeaconController, + "upgrade", + "send", + [ + BadBeaconTwo.options.address, + DharmaSmartWalletImplementationV6.options.address + ], + false + ); + + await tester.runTest( + "Dharma Upgrade Beacon Controller is inaccessible from a non-owner", + tester.DharmaUpgradeBeaconController, + "upgrade", + "send", + [ + tester.DharmaUpgradeBeacon.options.address, + DharmaSmartWalletImplementationV6.options.address + ], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "Dharma Upgrade Beacon Controller can set initial upgrade beacon implementation", + tester.DharmaUpgradeBeaconController, + "upgrade", + "send", + [ + tester.DharmaUpgradeBeacon.options.address, + DharmaSmartWalletImplementationV6.options.address + ], + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Upgraded.returnValues.upgradeBeacon, + tester.DharmaUpgradeBeacon.options.address + ); + assert.strictEqual( + receipt.events.Upgraded.returnValues.oldImplementation, + constants.NULL_ADDRESS + ); + assert.strictEqual( + receipt.events.Upgraded.returnValues + .oldImplementationCodeHash, + constants.EMPTY_HASH + ); + assert.strictEqual( + receipt.events.Upgraded.returnValues.newImplementation, + DharmaSmartWalletImplementationV6.options.address + ); + /* TODO assert.strictEqual( receipt.events.Upgraded.returnValues.newImplementationCodeHash, ... ) */ - } - } - ) - - await tester.runTest( - 'Dharma Upgrade Beacon Controller cannot clear upgrade beacon implementation', - tester.DharmaUpgradeBeaconController, - 'upgrade', - 'send', - [ - tester.DharmaUpgradeBeacon.options.address, - constants.NULL_ADDRESS - ], - false - ) - - await tester.runTest( - 'Dharma Upgrade Beacon Controller can reset upgrade beacon implementation', - tester.DharmaUpgradeBeaconController, - 'upgrade', - 'send', - [ - tester.DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV6.options.address - ], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Upgraded.returnValues.upgradeBeacon, - tester.DharmaUpgradeBeacon.options.address - ) - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementation, - DharmaSmartWalletImplementationV6.options.address - ) - /* TODO + } + } + ); + + await tester.runTest( + "Dharma Upgrade Beacon Controller cannot clear upgrade beacon implementation", + tester.DharmaUpgradeBeaconController, + "upgrade", + "send", + [tester.DharmaUpgradeBeacon.options.address, constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + "Dharma Upgrade Beacon Controller can reset upgrade beacon implementation", + tester.DharmaUpgradeBeaconController, + "upgrade", + "send", + [ + tester.DharmaUpgradeBeacon.options.address, + DharmaSmartWalletImplementationV6.options.address + ], + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Upgraded.returnValues.upgradeBeacon, + tester.DharmaUpgradeBeacon.options.address + ); + assert.strictEqual( + receipt.events.Upgraded.returnValues.oldImplementation, + DharmaSmartWalletImplementationV6.options.address + ); + /* TODO assert.strictEqual( receipt.events.Upgraded.returnValues.oldImplementationCodeHash, constants.EMPTY_HASH ) */ - assert.strictEqual( - receipt.events.Upgraded.returnValues.newImplementation, - DharmaSmartWalletImplementationV6.options.address - ) - /* TODO + assert.strictEqual( + receipt.events.Upgraded.returnValues.newImplementation, + DharmaSmartWalletImplementationV6.options.address + ); + /* TODO assert.strictEqual( receipt.events.Upgraded.returnValues.newImplementationCodeHash, ... ) */ - } - } - ) - - const UpgradeBeaconImplementationCheck = await tester.runTest( - `UpgradeBeaconImplementationCheck deployment`, - tester.UpgradeBeaconImplementationCheckDeployer, - '', - 'deploy', - [ - tester.DharmaUpgradeBeacon.options.address, - DharmaSmartWalletImplementationV6.options.address - ] - ) - - await tester.runTest( - 'DharmaUpgradeBeacon has the implementation set', - tester.DharmaUpgradeBeaconController, - 'getImplementation', - 'call', - [tester.DharmaUpgradeBeacon.options.address], - true, - value => { - assert.strictEqual(value, DharmaSmartWalletImplementationV6.options.address) - } - ) - - await tester.runTest( - 'Dharma Key Ring Upgrade Beacon Controller can set initial key ring upgrade beacon implementation', - tester.DharmaKeyRingUpgradeBeaconController, - 'upgrade', - 'send', - [ - tester.DharmaKeyRingUpgradeBeacon.options.address, - DharmaKeyRingImplementationV1.options.address - ], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Upgraded.returnValues.upgradeBeacon, - tester.DharmaKeyRingUpgradeBeacon.options.address - ) - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementation, - constants.NULL_ADDRESS - ) - assert.strictEqual( - receipt.events.Upgraded.returnValues.oldImplementationCodeHash, - constants.EMPTY_HASH - ) - assert.strictEqual( - receipt.events.Upgraded.returnValues.newImplementation, - DharmaKeyRingImplementationV1.options.address - ) - /* TODO + } + } + ); + + const UpgradeBeaconImplementationCheck = await tester.runTest( + `UpgradeBeaconImplementationCheck deployment`, + tester.UpgradeBeaconImplementationCheckDeployer, + "", + "deploy", + [ + tester.DharmaUpgradeBeacon.options.address, + DharmaSmartWalletImplementationV6.options.address + ] + ); + + await tester.runTest( + "DharmaUpgradeBeacon has the implementation set", + tester.DharmaUpgradeBeaconController, + "getImplementation", + "call", + [tester.DharmaUpgradeBeacon.options.address], + true, + value => { + assert.strictEqual( + value, + DharmaSmartWalletImplementationV6.options.address + ); + } + ); + + await tester.runTest( + "Dharma Key Ring Upgrade Beacon Controller can set initial key ring upgrade beacon implementation", + tester.DharmaKeyRingUpgradeBeaconController, + "upgrade", + "send", + [ + tester.DharmaKeyRingUpgradeBeacon.options.address, + DharmaKeyRingImplementationV1.options.address + ], + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Upgraded.returnValues.upgradeBeacon, + tester.DharmaKeyRingUpgradeBeacon.options.address + ); + assert.strictEqual( + receipt.events.Upgraded.returnValues.oldImplementation, + constants.NULL_ADDRESS + ); + assert.strictEqual( + receipt.events.Upgraded.returnValues + .oldImplementationCodeHash, + constants.EMPTY_HASH + ); + assert.strictEqual( + receipt.events.Upgraded.returnValues.newImplementation, + DharmaKeyRingImplementationV1.options.address + ); + /* TODO assert.strictEqual( receipt.events.Upgraded.returnValues.newImplementationCodeHash, ... ) */ - } - } - ) - - const KeyRingUpgradeBeaconImplementationCheck = await tester.runTest( - `KeyRingUpgradeBeaconImplementationCheck deployment`, - tester.UpgradeBeaconImplementationCheckDeployer, - '', - 'deploy', - [ - tester.DharmaKeyRingUpgradeBeacon.options.address, - DharmaKeyRingImplementationV1.options.address - ] - ) - - await tester.runTest( - 'DharmaKeyRingUpgradeBeacon has the implementation set', - tester.DharmaKeyRingUpgradeBeaconController, - 'getImplementation', - 'call', - [tester.DharmaKeyRingUpgradeBeacon.options.address], - true, - value => { - assert.strictEqual(value, DharmaKeyRingImplementationV1.options.address) - } - ) - - const DharmaSmartWalletNoFactoryNoConstructorDeployer = new web3.eth.Contract([]) - DharmaSmartWalletNoFactoryNoConstructorDeployer.options.data = ( - '0x600b5981380380925939f359595959365960205959596e' + - tester.DharmaUpgradeBeacon.options.address.slice(12).toLowerCase() + - '5afa1551368280375af43d3d93803e602e57fd5bf3' - ) - - const DharmaSmartWalletNoFactoryNoConstructor = await tester.runTest( - `DharmaSmartWallet minimal upgradeable proxy deployment - no factory or constructor`, - DharmaSmartWalletNoFactoryNoConstructorDeployer, - '', - 'deploy' - ) - - const DharmaSmartWalletImplementationTest = new web3.eth.Contract( - DharmaSmartWalletImplementationV6Artifact.abi, - DharmaSmartWalletNoFactoryNoConstructor.options.address - ) - - await tester.runTest( - 'test passes', - DharmaSmartWalletImplementationTest, - 'getVersion', - 'call', - [], - true, - value => { - assert.ok(value.length > 0) - } - ) - - let currentSaiCode; - await tester.runTest( - 'Checking for required external contracts...', - tester.MockCodeCheck, - 'code', - 'call', - [constants.SAI_MAINNET_ADDRESS], - true, - value => { - currentSaiCode = value; + } + } + ); + + const KeyRingUpgradeBeaconImplementationCheck = await tester.runTest( + `KeyRingUpgradeBeaconImplementationCheck deployment`, + tester.UpgradeBeaconImplementationCheckDeployer, + "", + "deploy", + [ + tester.DharmaKeyRingUpgradeBeacon.options.address, + DharmaKeyRingImplementationV1.options.address + ] + ); + + await tester.runTest( + "DharmaKeyRingUpgradeBeacon has the implementation set", + tester.DharmaKeyRingUpgradeBeaconController, + "getImplementation", + "call", + [tester.DharmaKeyRingUpgradeBeacon.options.address], + true, + value => { + assert.strictEqual( + value, + DharmaKeyRingImplementationV1.options.address + ); + } + ); + + const DharmaSmartWalletNoFactoryNoConstructorDeployer = new web3.eth.Contract( + [] + ); + DharmaSmartWalletNoFactoryNoConstructorDeployer.options.data = + "0x600b5981380380925939f359595959365960205959596e" + + tester.DharmaUpgradeBeacon.options.address.slice(12).toLowerCase() + + "5afa1551368280375af43d3d93803e602e57fd5bf3"; + + const DharmaSmartWalletNoFactoryNoConstructor = await tester.runTest( + `DharmaSmartWallet minimal upgradeable proxy deployment - no factory or constructor`, + DharmaSmartWalletNoFactoryNoConstructorDeployer, + "", + "deploy" + ); + + const DharmaSmartWalletImplementationTest = new web3.eth.Contract( + DharmaSmartWalletImplementationV6Artifact.abi, + DharmaSmartWalletNoFactoryNoConstructor.options.address + ); + + await tester.runTest( + "test passes", + DharmaSmartWalletImplementationTest, + "getVersion", + "call", + [], + true, + value => { + assert.ok(value.length > 0); + } + ); + + let currentSaiCode; + await tester.runTest( + "Checking for required external contracts...", + tester.MockCodeCheck, + "code", + "call", + [constants.SAI_MAINNET_ADDRESS], + true, + value => { + currentSaiCode = value; + } + ); + + if (!currentSaiCode) { + console.log( + `completed ${tester.passed + tester.failed} test${ + tester.passed + tester.failed === 1 ? "" : "s" + } ` + + `with ${tester.failed} failure${ + tester.failed === 1 ? "" : "s" + }.` + ); + + console.log( + "Note that the full test suite cannot be executed locally - instead, " + + "run against a fork of mainnet using `yarn forkStart` and `yarn test`." + ); + + if (tester.failed > 0) { + process.exit(1); + } + + // exit. + return 0; + } + + const DharmaSmartWalletNoFactoryDeployer = new web3.eth.Contract([]); + DharmaSmartWalletNoFactoryDeployer.options.data = + "0x595959596076380359602059595973" + + tester.DharmaUpgradeBeacon.options.address.slice(2).toLowerCase() + + "5afa155182607683395af46038573d903d81803efd5b60356041819339f3595959593659602059595973" + + tester.DharmaUpgradeBeacon.options.address.slice(2).toLowerCase() + + "5afa1551368280375af43d3d93803e603357fd5bf3" + + "c4d66de80000000000000000000000009999999999999999999999999999999999999999"; + + const DharmaSmartWalletNoFactory = await tester.runTest( + `DharmaSmartWallet minimal upgradeable proxy deployment - no factory but with constructor`, + DharmaSmartWalletNoFactoryDeployer, + "", + "deploy" + ); + + const DharmaSmartWalletImplementationTestWithConstructor = new web3.eth.Contract( + DharmaSmartWalletImplementationV6Artifact.abi, + DharmaSmartWalletNoFactory.options.address + ); + + await tester.runTest( + "test passes", + DharmaSmartWalletImplementationTestWithConstructor, + "getVersion", + "call", + [], + true, + value => { + assert.ok(value.length > 0); + } + ); + + await tester.runTest( + "new user smart wallet can be called and has the correct dharma key set", + DharmaSmartWalletImplementationTestWithConstructor, + "getUserSigningKey", + "call", + [], + true, + value => { + assert.strictEqual( + value, + "0x9999999999999999999999999999999999999999" + ); + } + ); + + const DharmaSmartWalletFactoryV1 = await tester.runTest( + `DharmaSmartWalletFactoryV1 contract deployment`, + tester.DharmaSmartWalletFactoryV1Deployer, + "", + "deploy", + [] + ); + + let targetWalletAddress; + await tester.runTest( + "DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time", + DharmaSmartWalletFactoryV1, + "getNextSmartWallet", + "call", + [tester.address], + true, + value => { + // TODO: verify against expected value + targetWalletAddress = value; + } + ); + + const UserSmartWalletV6 = new web3.eth.Contract( + DharmaSmartWalletImplementationV6Artifact.abi, + targetWalletAddress + ); + + const UserSmartWalletV7 = new web3.eth.Contract( + DharmaSmartWalletImplementationV7Artifact.abi, + targetWalletAddress + ); + + await testPerformingUpgrade( + tester, + DharmaSmartWalletImplementationV6, // new implementation + UserSmartWalletV6, + tester.DharmaUpgradeBeaconController, + tester.DharmaUpgradeBeacon.options.address, + 6, + true + ); + + contractNames[DharmaSmartWalletFactoryV1.options.address] = + "Smart Wallet Factory"; + contractNames[targetWalletAddress] = "Smart Wallet"; + + const ethWhaleBalance = await web3.eth.getBalance( + constants.ETH_WHALE_ADDRESS + ); + const saiWhaleBalance = await web3.eth.getBalance( + constants.SAI_WHALE_ADDRESS + ); + const daiWhaleBalance = await web3.eth.getBalance( + constants.DAI_WHALE_ADDRESS + ); + const usdcWhaleBalance = await web3.eth.getBalance( + constants.USDC_WHALE_ADDRESS + ); + + if (ethWhaleBalance === "0") { + await web3.eth.sendTransaction({ + from: tester.address, + to: constants.ETH_WHALE_ADDRESS, + value: web3.utils.toWei(".2", "ether"), + gas: testingContext !== "coverage" ? "0x5208" : tester.gasLimit - 1, + gasPrice: 1 + }); + console.log(" ✓ Eth Whale can receive eth if needed"); + } + + if (saiWhaleBalance === "0") { + await web3.eth.sendTransaction({ + from: tester.address, + to: constants.SAI_WHALE_ADDRESS, + value: web3.utils.toWei(".1", "ether"), + gas: testingContext !== "coverage" ? "0x5208" : tester.gasLimit - 1, + gasPrice: 1 + }); + console.log(" ✓ Sai Whale can receive eth if needed"); + } + + if (daiWhaleBalance === "0") { + await web3.eth.sendTransaction({ + from: tester.address, + to: constants.DAI_WHALE_ADDRESS, + value: web3.utils.toWei(".1", "ether"), + gas: testingContext !== "coverage" ? "0x5208" : tester.gasLimit - 1, + gasPrice: 1 + }); + console.log(" ✓ Dai Whale can receive eth if needed"); + } + + if (usdcWhaleBalance === "0") { + await web3.eth.sendTransaction({ + from: tester.address, + to: constants.USDC_WHALE_ADDRESS, + value: web3.utils.toWei(".1", "ether"), + gas: testingContext !== "coverage" ? "0x5208" : tester.gasLimit - 1, + gasPrice: 1 + }); + console.log(" ✓ USDC Whale can receive eth if needed"); } - ) - - if (!currentSaiCode) { - console.log( - `completed ${tester.passed + tester.failed} test${tester.passed + tester.failed === 1 ? '' : 's'} ` + - `with ${tester.failed} failure${tester.failed === 1 ? '' : 's'}.` - ) + await web3.eth.sendTransaction({ + from: constants.ETH_WHALE_ADDRESS, + to: targetWalletAddress, + value: web3.utils.toWei(".1", "ether"), + gas: testingContext !== "coverage" ? "0x5208" : tester.gasLimit - 1, + gasPrice: 1 + }); console.log( - 'Note that the full test suite cannot be executed locally - instead, ' + - 'run against a fork of mainnet using `yarn forkStart` and `yarn test`.' - ) - - if (tester.failed > 0) { - process.exit(1) - } - - // exit. - return 0 - } - - const DharmaSmartWalletNoFactoryDeployer = new web3.eth.Contract([]) - DharmaSmartWalletNoFactoryDeployer.options.data = ( - '0x595959596076380359602059595973' + - tester.DharmaUpgradeBeacon.options.address.slice(2).toLowerCase() + - '5afa155182607683395af46038573d903d81803efd5b60356041819339f3595959593659602059595973' + - tester.DharmaUpgradeBeacon.options.address.slice(2).toLowerCase() + - '5afa1551368280375af43d3d93803e603357fd5bf3' + - 'c4d66de80000000000000000000000009999999999999999999999999999999999999999' + " ✓ Eth Whale can deposit eth into the yet-to-be-deployed smart wallet" + ); + + await tester.runTest( + "Dai Whale can deposit dai into the yet-to-be-deployed smart wallet", + tester.DAI, + "transfer", + "send", + [targetWalletAddress, web3.utils.toWei("100", "ether")], + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.DAI_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("100", "ether") + ); + } + }, + constants.DAI_WHALE_ADDRESS + ); + + await tester.runTest( + "USDC Whale can deposit usdc into the yet-to-be-deployed smart wallet", + tester.USDC, + "transfer", + "send", + [targetWalletAddress, web3.utils.toWei("100", "lovelace")], // six decimals + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.USDC_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("100", "lovelace") + ); + } + }, + constants.USDC_WHALE_ADDRESS + ); + + await tester.runTest( + "DharmaSmartWalletFactoryV1 cannot deploy a new smart wallet with no key", + DharmaSmartWalletFactoryV1, + "newSmartWallet", + "send", + [constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + "DharmaSmartWalletFactoryV1 can deploy a new smart wallet using a Dharma Key", + DharmaSmartWalletFactoryV1, + "newSmartWallet", + "send", + [tester.address], + true, + receipt => { + //console.log(receipt.status, receipt.gasUsed) + if (testingContext !== "coverage") { + let events = []; + Object.values(receipt.events).forEach(value => { + const log = constants.EVENT_DETAILS[value.raw.topics[0]]; + if (typeof log === "undefined") { + console.log(value); + } + const decoded = web3.eth.abi.decodeLog( + log.abi, + value.raw.data, + value.raw.topics + ); + events.push({ + address: contractNames[value.address], + eventName: log.name, + returnValues: decoded + }); + }); + + assert.strictEqual(events[0].address, "Smart Wallet"); + assert.strictEqual(events[0].eventName, "NewUserSigningKey"); + assert.strictEqual( + events[0].returnValues.userSigningKey, + tester.address + ); + + assert.strictEqual(events[1].address, "DAI"); + assert.strictEqual(events[1].eventName, "Approval"); + assert.strictEqual( + events[1].returnValues.value, + constants.FULL_APPROVAL + ); + + assert.strictEqual(events[2].address, "CDAI"); + assert.strictEqual(events[2].eventName, "AccrueInterest"); + + assert.strictEqual(events[3].address, "DAI"); + assert.strictEqual(events[3].eventName, "Transfer"); + assert.strictEqual( + events[3].returnValues.value, + web3.utils.toWei("100", "ether") + ); + + assert.strictEqual(events[4].address, "CDAI"); + assert.strictEqual(events[4].eventName, "Mint"); + assert.strictEqual( + events[4].returnValues.mintTokens, + web3.utils.toWei("100", "ether") + ); + + assert.strictEqual(events[5].address, "CDAI"); + assert.strictEqual(events[5].eventName, "Transfer"); + + assert.strictEqual(events[6].address, "USDC"); + assert.strictEqual(events[6].eventName, "Approval"); + assert.strictEqual( + events[6].returnValues.value, + constants.FULL_APPROVAL + ); + + assert.strictEqual(events[7].address, "CUSDC"); + assert.strictEqual(events[7].eventName, "AccrueInterest"); + + assert.strictEqual(events[8].address, "USDC"); + assert.strictEqual(events[8].eventName, "Transfer"); + assert.strictEqual( + events[8].returnValues.value, + web3.utils.toWei("100", "lovelace") + ); + + assert.strictEqual(events[9].address, "CUSDC"); + assert.strictEqual(events[9].eventName, "Mint"); + assert.strictEqual( + events[9].returnValues.mintTokens, + web3.utils.toWei("100", "lovelace") + ); + + assert.strictEqual(events[10].address, "CUSDC"); + assert.strictEqual(events[10].eventName, "Transfer"); + } + } + ); + + await tester.runTest( + "DharmaSmartWalletFactoryV1 gets a new smart wallet address with same key", + DharmaSmartWalletFactoryV1, + "getNextSmartWallet", + "call", + [tester.address], + true, + value => { + // TODO: verify against expected value + assert.ok(targetWalletAddress !== value); + } + ); + + let originalNonce = 0; + await tester.runTest( + "UserSmartWalletV6 nonce can be retrieved and starts at zero", + UserSmartWalletV6, + "getNonce", + "call", + [], + true, + value => { + assert.strictEqual(value, originalNonce.toString()); + } + ); + + await tester.runTest( + "V6 UserSmartWallet can get balances", + UserSmartWalletV6, + "getBalances", + "call", + [], + true, + value => { + //console.log(value) + } + ); + + await tester.runTest( + "V6 UserSmartWallet secondary can call to cancel", + UserSmartWalletV6, + "cancel", + "send", + [0, "0x"] + ); + + await tester.runTest( + "V6 UserSmartWallet nonce is now set to original + 1", + UserSmartWalletV6, + "getNonce", + "call", + [], + true, + value => { + assert.strictEqual(value, (parseInt(originalNonce) + 1).toString()); + } + ); + + await tester.runTest( + "V6 UserSmartWallet can get next custom action ID to set a user signing key", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 1, // SetUserSigningKey, + constants.FULL_APPROVAL, // This value shouldn't matter + tester.addressTwo, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + await tester.runTest( + "V6 UserSmartWallet can set a new user signing key with signatures", + UserSmartWalletV6, + "setUserSigningKey", + "send", + [tester.addressTwo, 0, "0x", setUserSigningKeyDharmaSignature] + ); + + await tester.runTest( + "V6 UserSmartWallet has the new user signing key set", + UserSmartWalletV6, + "getUserSigningKey", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.addressTwo); + } + ); + + await tester.runTest( + "cSai can be sent to V6 UserSmartWallet", + tester.CSAI, + "transfer", + "send", + [UserSmartWalletV6.options.address, web3.utils.toWei("0.5", "mwei")] + ); + + await tester.runTest( + "V6 UserSmartWallet relay can trigger cSai to cDai migration before cDai approval", + UserSmartWalletV6, + "migrateCSaiToCDai", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get next custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 0, // DAIWithdrawal + constants.FULL_APPROVAL, + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + await tester.runTest( + "V6 UserSmartWallet can get custom action ID and it matches next action ID", + UserSmartWalletV6, + "getCustomActionID", + "call", + [ + 0, // DAIWithdrawal + constants.FULL_APPROVAL, + tester.address, + parseInt(originalNonce) + 2, + 0 + ], + true, + value => { + assert.strictEqual(value, customActionId); + } + ); + + await tester.runTest( + "V6 UserSmartWallet can get next generic action ID", + UserSmartWalletV6, + "getNextGenericActionID", + "call", + [tester.address, "0x", 0], + true, + value => { + genericActionID = value; + } + ); + + await tester.runTest( + "V6 UserSmartWallet can get generic action ID and it matches next action ID", + UserSmartWalletV6, + "getGenericActionID", + "call", + [tester.address, "0x", parseInt(originalNonce) + 2, 0], + true, + value => { + assert.strictEqual(value, genericActionID); + } + ); + + await tester.runTest( + "UserSmartWallet calls to atomic methods revert", + UserSmartWalletV6, + "_withdrawDaiAtomic", + "send", + ["1", tester.address], + false + ); + + // Give the Dai Whale some ETH so it can make transactions + await web3.eth.sendTransaction({ + from: tester.address, + to: constants.DAI_WHALE_ADDRESS, + value: web3.utils.toWei("1", "ether"), + gas: testingContext !== "coverage" ? "0xffff" : tester.gasLimit - 1, + gasPrice: 1 + }); + + await tester.runTest( + "Dai Whale can deposit Dai into the V6 smart wallet", + tester.DAI, + "transfer", + "send", + [targetWalletAddress, web3.utils.toWei("100", "ether")], + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.DAI_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("100", "ether") + ); + } + }, + constants.DAI_WHALE_ADDRESS + ); + + await tester.runTest( + "USDC Whale can deposit usdc into the V6 smart wallet", + tester.USDC, + "transfer", + "send", + [targetWalletAddress, web3.utils.toWei("100", "lovelace")], // six decimals + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.USDC_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("100", "lovelace") + ); + } + }, + constants.USDC_WHALE_ADDRESS + ); + + await tester.runTest( + "V6 UserSmartWallet can get a generic action ID", + UserSmartWalletV6, + "getNextGenericActionID", + "call", + [ + tester.DAI.options.address, + tester.DAI.methods + .approve(tester.CDAI.options.address, 0) + .encodeABI(), + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet can call executeAction", + UserSmartWalletV6, + "executeAction", + "send", + [ + tester.DAI.options.address, + tester.DAI.methods + .approve(tester.CDAI.options.address, 0) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ); + + await tester.runTest( + "V6 user smart wallet can trigger repayAndDeposit to deposit all new funds", + UserSmartWalletV6, + "repayAndDeposit", + "send", + [], + true, + receipt => { + //console.log(receipt.status, receipt.gasUsed) + if (testingContext !== "coverage") { + let events = []; + Object.values(receipt.events).forEach(value => { + const log = constants.EVENT_DETAILS[value.raw.topics[0]]; + const decoded = web3.eth.abi.decodeLog( + log.abi, + value.raw.data, + value.raw.topics + ); + events.push({ + address: contractNames[value.address], + eventName: log.name, + returnValues: decoded + }); + }); + + assert.strictEqual(events[0].address, "DAI"); + assert.strictEqual(events[0].eventName, "Approval"); + + assert.strictEqual(events[1].address, "CDAI"); + assert.strictEqual(events[1].eventName, "AccrueInterest"); + + assert.strictEqual(events[2].address, "DAI"); + assert.strictEqual(events[2].eventName, "Transfer"); + //assert.strictEqual(events[2].returnValues.value, web3.utils.toWei('100', 'ether')) + + assert.strictEqual(events[3].address, "CDAI"); + assert.strictEqual(events[3].eventName, "Mint"); + //assert.strictEqual(events[3].returnValues.mintTokens, web3.utils.toWei('100', 'ether')) + + assert.strictEqual(events[4].address, "CDAI"); + assert.strictEqual(events[4].eventName, "Transfer"); + + assert.strictEqual(events[5].address, "CUSDC"); + assert.strictEqual(events[5].eventName, "AccrueInterest"); + + assert.strictEqual(events[6].address, "USDC"); + assert.strictEqual(events[6].eventName, "Transfer"); + //assert.strictEqual(events[6].returnValues.value, web3.utils.toWei('100', 'lovelace')) + + assert.strictEqual(events[7].address, "CUSDC"); + assert.strictEqual(events[7].eventName, "Mint"); + //assert.strictEqual(events[7].returnValues.mintTokens, web3.utils.toWei('100', 'lovelace')) + + assert.strictEqual(events[8].address, "CUSDC"); + assert.strictEqual(events[8].eventName, "Transfer"); + } + } + ); + + await tester.runTest( + "Dai Whale can deposit dai into the V6 smart wallet", + tester.DAI, + "transfer", + "send", + [targetWalletAddress, web3.utils.toWei("100", "ether")], + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.DAI_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("100", "ether") + ); + } + }, + constants.DAI_WHALE_ADDRESS + ); + + await tester.runTest( + "V6 UserSmartWallet can get a generic action ID", + UserSmartWalletV6, + "getNextGenericActionID", + "call", + [constants.ESCAPE_HATCH_REGISTRY_ADDRESS, "0x", 0], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet cannot call executeAction and target Escape Hatch Registry", + UserSmartWalletV6, + "executeAction", + "send", + [ + constants.ESCAPE_HATCH_REGISTRY_ADDRESS, + "0x", + 0, + executeActionUserSignature, + executeActionSignature + ], + false + ); + + await tester.runTest( + "V6 UserSmartWallet can get a generic action ID", + UserSmartWalletV6, + "getNextGenericActionID", + "call", + [ + tester.DAI.options.address, + tester.DAI.methods + .approve(tester.CDAI.options.address, 0) + .encodeABI(), + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet can call executeAction", + UserSmartWalletV6, + "executeAction", + "send", + [ + tester.DAI.options.address, + tester.DAI.methods + .approve(tester.CDAI.options.address, 0) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ); + + await tester.runTest( + "V6 user smart wallet repayAndDeposit can still deposit without approval", + UserSmartWalletV6, + "repayAndDeposit", + "send", + [], + true, + receipt => { + //console.log(receipt.status, receipt.gasUsed) + if (testingContext !== "coverage") { + let events = []; + Object.values(receipt.events).forEach(value => { + const log = constants.EVENT_DETAILS[value.raw.topics[0]]; + const decoded = web3.eth.abi.decodeLog( + log.abi, + value.raw.data, + value.raw.topics + ); + events.push({ + address: contractNames[value.address], + eventName: log.name, + returnValues: decoded + }); + }); + + // TODO: verify + } + } + ); + + await tester.runTest( + "V6 UserSmartWallet can get a generic action ID", + UserSmartWalletV6, + "getNextGenericActionID", + "call", + [ + tester.DAI.options.address, + tester.DAI.methods + .approve(tester.CDAI.options.address, constants.FULL_APPROVAL) + .encodeABI(), + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet can call executeAction", + UserSmartWalletV6, + "executeAction", + "send", + [ + tester.DAI.options.address, + tester.DAI.methods + .approve(tester.CDAI.options.address, constants.FULL_APPROVAL) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ); + + await tester.runTest( + "V6 user smart wallet repayAndDeposit can deposit with approval added back", + UserSmartWalletV6, + "repayAndDeposit", + "send", + [], + true, + receipt => { + //console.log(receipt.status, receipt.gasUsed) + if (testingContext !== "coverage") { + let events = []; + Object.values(receipt.events).forEach(value => { + const log = constants.EVENT_DETAILS[value.raw.topics[0]]; + const decoded = web3.eth.abi.decodeLog( + log.abi, + value.raw.data, + value.raw.topics + ); + events.push({ + address: contractNames[value.address], + eventName: log.name, + returnValues: decoded + }); + }); + + // TODO: verify + } + } + ); + + await tester.runTest( + "V6 user smart wallet can trigger repayAndDeposit even with no funds", + UserSmartWalletV6, + "repayAndDeposit", + "send", + [], + true, + receipt => { + //console.log(receipt.status, receipt.gasUsed) + if (testingContext !== "coverage") { + let events = []; + Object.values(receipt.events).forEach(value => { + const log = constants.EVENT_DETAILS[value.raw.topics[0]]; + const decoded = web3.eth.abi.decodeLog( + log.abi, + value.raw.data, + value.raw.topics + ); + events.push({ + address: contractNames[value.address], + eventName: log.name, + returnValues: decoded + }); + }); + + assert.strictEqual(events.length, 0); + } + } + ); + + await tester.runTest( + "V6 UserSmartWallet can get custom action ID and it matches next action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 1, // SetUserSigningKey, + 0, + constants.NULL_ADDRESS, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + setUserSigningKeyUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + await tester.runTest( + "V6 UserSmartWallet cannot set the null address as a new user signing key", + UserSmartWalletV6, + "setUserSigningKey", + "send", + [ + constants.NULL_ADDRESS, + 0, + setUserSigningKeyUserSignature, + setUserSigningKeyDharmaSignature + ], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get next custom action ID to set a user signing key", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 1, // SetUserSigningKey, + constants.FULL_APPROVAL, // This value shouldn't matter + tester.addressTwo, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + await tester.runTest( + "UserSmartWallet can get the nonce", + UserSmartWalletV6, + "getNonce", + "call", + [], + true, + value => { + currentNonce = value; + } + ); + + await tester.runTest( + "V6 UserSmartWallet can get custom action ID and it matches next action ID", + UserSmartWalletV6, + "getCustomActionID", + "call", + [ + 1, // SetUserSigningKey, + 0, // Note that this value differs from above + tester.addressTwo, + currentNonce, + 0 + ], + true, + value => { + assert.strictEqual(value, customActionId); + } + ); + + setUserSigningKeyUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + await tester.runTest( + "V6 UserSmartWallet can set a new user signing key with signatures", + UserSmartWalletV6, + "setUserSigningKey", + "send", + [ + tester.addressTwo, + 0, + setUserSigningKeyUserSignature, + setUserSigningKeyDharmaSignature + ], + true, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get next custom action ID to cancel", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 0, // Cancel + constants.FULL_APPROVAL, // This value shouldn't matter + tester.originalAddress, // This value shouldn't matter either + 0 + ], + true, + value => { + customActionId = value; + } + ); + + await tester.runTest( + "UserSmartWallet can get the nonce", + UserSmartWalletV6, + "getNonce", + "call", + [], + true, + value => { + currentNonce = value; + } + ); + + await tester.runTest( + "V6 UserSmartWallet can get custom action ID and it matches next action ID", + UserSmartWalletV6, + "getCustomActionID", + "call", + [ + 0, // Cancel + 0, // Note that this value differs from above + tester.addressTwo, // This one too + currentNonce, + 0 + ], + true, + value => { + assert.strictEqual(value, customActionId); + } + ); + + cancelUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet secondary can cancel using a signature", + UserSmartWalletV6, + "cancel", + "send", + [0, cancelUserSignature], + true, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "UserSmartWallet nonce is incremented after cancelling", + UserSmartWalletV6, + "getNonce", + "call", + [], + true, + value => { + assert.strictEqual(parseInt(value), parseInt(currentNonce) + 1); + } + ); + + await tester.runTest( + "V6 UserSmartWallet secondary cannot call to withdraw dai without primary", + UserSmartWalletV6, + "withdrawDai", + "send", + ["1000000000000000000", tester.address, 0, "0x", "0x"], + false + ); + + await tester.runTest( + "V6 UserSmartWallet secondary cannot call to withdraw usdc without primary", + UserSmartWalletV6, + "withdrawUSDC", + "send", + [1, tester.address, 0, "0x", "0x"], + false + ); + + await tester.runTest( + "V6 UserSmartWallet secondary can no longer call to set userSigningKey without primary", + UserSmartWalletV6, + "setUserSigningKey", + "send", + [tester.address, 0, "0x", "0x"], + false + ); + + await tester.runTest( + "V6 UserSmartWallet can get a USDC withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + "1", // dust + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + 'V6 UserSmartWallet relay cannot withdraw "dust" USDC', + UserSmartWalletV6, + "withdrawUSDC", + "send", + [ + "1", + tester.address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get a USDC withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + "100000", + constants.NULL_ADDRESS, // bad recipient + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay cannot withdraw USDC to null address", + UserSmartWalletV6, + "withdrawUSDC", + "send", + [ + "100000", + constants.NULL_ADDRESS, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get a USDC withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + "100000", + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay can call with two signatures to withdraw USDC", + UserSmartWalletV6, + "withdrawUSDC", + "send", + [ + "100000", + tester.address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get a USDC withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + constants.FULL_APPROVAL, + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay cannot call with bad signature to withdraw USDC", + UserSmartWalletV6, + "withdrawUSDC", + "send", + [ + constants.FULL_APPROVAL, + tester.address, + 0, + usdcUserWithdrawalSignature, + "0xffffffff" + usdcWithdrawalSignature.slice(10) + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet cannot call with bad user signature to withdraw USDC", + UserSmartWalletV6, + "withdrawUSDC", + "send", + [ + constants.FULL_APPROVAL, + tester.address, + 0, + "0xffffffff" + usdcUserWithdrawalSignature.slice(10), + usdcWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet relay can call with two signatures to withdraw max USDC", + UserSmartWalletV6, + "withdrawUSDC", + "send", + [ + constants.FULL_APPROVAL, + tester.address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + /* TODO: get this working manually + const withdrawalMessage = ( + UserSmartWallet.options.address + // smart wallet address + constants.NULL_BYTES_32.slice(2) + // smart wallet version + address.slice(2) + // user dharma key + address.slice(2) + // dharma key registry key + '5'.padStart(64, '0') + // nonce + constants.NULL_BYTES_32.slice(2) + // minimum gas + '04' + // action type + 'f'.padStart(64, 'f') + // amount + address.slice(2) // recipient ) - const DharmaSmartWalletNoFactory = await tester.runTest( - `DharmaSmartWallet minimal upgradeable proxy deployment - no factory but with constructor`, - DharmaSmartWalletNoFactoryDeployer, - '', - 'deploy' + const saiWithdrawalSignature = tester.signHashedPrefixedHashedHexString( + withdrawalMessage, + address ) + */ - const DharmaSmartWalletImplementationTestWithConstructor = new web3.eth.Contract( - DharmaSmartWalletImplementationV6Artifact.abi, - DharmaSmartWalletNoFactory.options.address + await tester.runTest( + "V6 UserSmartWallet can get a Dai withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 10, // DaiWithdrawal + "1", + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + let daiWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + let daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + 'V6 UserSmartWallet relay cannot withdraw "dust" dai', + UserSmartWalletV6, + "withdrawDai", + "send", + [ + "1", + tester.address, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get a Dai withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 10, // DaiWithdrawal + "1000000000000000", + constants.NULL_ADDRESS, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + daiWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay cannot withdraw dai to null address", + UserSmartWalletV6, + "withdrawDai", + "send", + [ + "1000000000000000", + constants.NULL_ADDRESS, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get a Dai withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 10, // DaiWithdrawal + "1000000000000000", + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + daiWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay can call with signature to withdraw dai", + UserSmartWalletV6, + "withdrawDai", + "send", + [ + "1000000000000000", + tester.address, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt.events) + }, + tester.originalAddress + ); + + await tester.runTest( + 'V6 UserSmartWallet cannot get a non-custom "custom" next action ID', + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 2, // Generic, + constants.FULL_APPROVAL, + tester.address, + 0 + ], + false + ); + + await tester.runTest( + 'V6 UserSmartWallet cannot get a non-custom "custom" action ID', + UserSmartWalletV6, + "getCustomActionID", + "call", + [ + 2, // Generic, + constants.FULL_APPROVAL, + tester.address, + 0, + 0 + ], + false + ); + + await tester.runTest( + "V6 UserSmartWallet can get a Dai withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 10, // DaiWithdrawal + constants.FULL_APPROVAL, + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + daiWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay cannot call with bad signature to withdraw dai", + UserSmartWalletV6, + "withdrawDai", + "send", + [ + constants.FULL_APPROVAL, + tester.address, + 0, + daiUserWithdrawalSignature, + "0xffffffff" + daiWithdrawalSignature.slice(10) + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet relay cannot call with bad user signature to withdraw dai", + UserSmartWalletV6, + "withdrawDai", + "send", + [ + constants.FULL_APPROVAL, + tester.address, + 0, + "0xffffffff" + daiUserWithdrawalSignature.slice(10), + daiWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet relay can call with signature to withdraw sai", + UserSmartWalletV6, + "withdrawDai", + "send", + [ + constants.FULL_APPROVAL, + tester.address, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get a Ether withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 6, // ETHWithdrawal, + "0", // no amount + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + ethWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay cannot to withdraw ether with no amount", + UserSmartWalletV6, + "withdrawEther", + "send", + [ + "0", + tester.address, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get a Ether withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 6, // ETHWithdrawal, + "1", + constants.NULL_ADDRESS, // no recipient + 0 + ], + true, + value => { + customActionId = value; + } + ); + + ethWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay cannot to withdraw ether with no recipient", + UserSmartWalletV6, + "withdrawEther", + "send", + [ + "1", + constants.NULL_ADDRESS, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get a Ether withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 6, // ETHWithdrawal, + "1", + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + ethWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay cannot call with bad signature to withdraw eth", + UserSmartWalletV6, + "withdrawEther", + "send", + [ + "1", + tester.address, + 0, + ethUserWithdrawalSignature, + "0xffffffff" + ethWithdrawalSignature.slice(10) + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet relay cannot call with bad user signature to withdraw eth", + UserSmartWalletV6, + "withdrawEther", + "send", + [ + "1", + tester.address, + 0, + "0xffffffff" + ethUserWithdrawalSignature.slice(10), + ethWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet relay can call with signature to withdraw ether", + UserSmartWalletV6, + "withdrawEther", + "send", + [ + "1", + tester.address, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get a Ether withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 6, // ETHWithdrawal, + "1", + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + ethWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay cannot call with bad signature to withdraw eth", + UserSmartWalletV6, + "withdrawEther", + "send", + [ + "1", + tester.address, + 0, + ethUserWithdrawalSignature, + "0xffffffff" + ethWithdrawalSignature.slice(10) + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet relay cannot call with bad user signature to withdraw eth", + UserSmartWalletV6, + "withdrawEther", + "send", + [ + "1", + tester.address, + 0, + "0xffffffff" + ethUserWithdrawalSignature.slice(10), + ethWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet relay can call with signature to withdraw ether", + UserSmartWalletV6, + "withdrawEther", + "send", + [ + "1", + tester.address, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet cancel reverts with bad signature", + UserSmartWalletV6, + "cancel", + "send", + [0, "0x"], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet calls revert if insufficient action gas is supplied", + UserSmartWalletV6, + "cancel", + "send", + [constants.FULL_APPROVAL, "0x"], + false + ); + + await tester.runTest( + "V6 UserSmartWallet calls succeed if sufficient non-zero action gas supplied", + UserSmartWalletV6, + "cancel", + "send", + ["1", "0x"] + ); + + await tester.runTest( + "V6 UserSmartWallet can get a cancel custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 0, // Cancel, + "0", + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + cancelSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet can cancel using a signature", + UserSmartWalletV6, + "cancel", + "send", + ["0", cancelSignature], + true, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet calls to atomic methods revert", + UserSmartWalletV6, + "_withdrawDaiAtomic", + "send", + ["1", tester.address], + false + ); + + await tester.runTest( + "V6 UserSmartWallet calls to recover from random address revert", + UserSmartWalletV6, + "recover", + "send", + [tester.address], + false + ); + + await tester.runTest( + "DharmaSmartWalletFactoryV1 can deploy a V6 smart wallet using a Dharma Key", + DharmaSmartWalletFactoryV1, + "newSmartWallet", + "send", + [tester.addressTwo], + true, + receipt => { + //console.log(receipt.status, receipt.gasUsed) + if (testingContext !== "coverage") { + let events = []; + Object.values(receipt.events).forEach(value => { + const log = constants.EVENT_DETAILS[value.raw.topics[0]]; + const decoded = web3.eth.abi.decodeLog( + log.abi, + value.raw.data, + value.raw.topics + ); + events.push({ + address: contractNames[value.address], + eventName: log.name, + returnValues: decoded + }); + }); + + assert.strictEqual(events[0].eventName, "NewUserSigningKey"); + assert.strictEqual( + events[0].returnValues.userSigningKey, + tester.addressTwo + ); + //console.log(events) + + // TODO: test more events + } + } + ); + + await tester.runTest( + "V6 UserSmartWallet can get a generic action ID", + UserSmartWalletV6, + "getNextGenericActionID", + "call", + [ + tester.USDC.options.address, + tester.USDC.methods + .approve(tester.CUSDC.options.address, 0) + .encodeABI(), + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet cannot call executeAction and target a non-contract", + UserSmartWalletV6, + "executeAction", + "send", + [ + tester.address, + tester.USDC.methods + .approve(tester.CUSDC.options.address, 0) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ], + false + ); + + await tester.runTest( + "V6 UserSmartWallet cannot call executeAction and target itself", + UserSmartWalletV6, + "executeAction", + "send", + [ + UserSmartWalletV6.options.address, + tester.USDC.methods + .approve(tester.CUSDC.options.address, 0) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ], + false + ); + + await tester.runTest( + "V6 UserSmartWallet can call executeAction", + UserSmartWalletV6, + "executeAction", + "send", + [ + tester.USDC.options.address, + tester.USDC.methods + .approve(tester.CUSDC.options.address, 0) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ); + + await tester.runTest( + "V6 UserSmartWallet can get the next generic batch action ID", + UserSmartWalletV6, + "getNextGenericAtomicBatchActionID", + "call", + [ + [ + { + to: tester.SAI.options.address, + data: tester.SAI.methods.totalSupply().encodeABI() + } + ], + 0 + ], + true, + value => { + customActionId = value; + } + ); + + await tester.runTest( + "UserSmartWallet can get the nonce", + UserSmartWalletV6, + "getNonce", + "call", + [], + true, + value => { + currentNonce = value; + } + ); + + await tester.runTest( + "V6 UserSmartWallet generic batch action ID with nonce matches next ID", + UserSmartWalletV6, + "getGenericAtomicBatchActionID", + "call", + [ + [ + { + to: tester.SAI.options.address, + data: tester.SAI.methods.totalSupply().encodeABI() + } + ], + currentNonce, + 0 + ], + true, + value => { + assert.strictEqual(value, customActionId); + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet can call executeActionWithAtomicBatchCalls", + UserSmartWalletV6, + "executeActionWithAtomicBatchCalls", + "send", + [ + [ + { + to: tester.SAI.options.address, + data: tester.SAI.methods.totalSupply().encodeABI() + } + ], + 0, + executeActionUserSignature, + executeActionSignature + ] + ); + + await tester.runTest( + "USDC Whale can deposit usdc into the deployed smart wallet", + tester.USDC, + "transfer", + "send", + [targetWalletAddress, web3.utils.toWei("100", "lovelace")], // six decimals + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.USDC_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("100", "lovelace") + ); + } + }, + constants.USDC_WHALE_ADDRESS + ); + + await tester.runTest( + "new user smart wallet can trigger repayAndDeposit to deposit all new funds", + UserSmartWalletV6, + "repayAndDeposit", + "send", + [], + true, + receipt => { + //console.log(receipt.status, receipt.gasUsed) + if (testingContext !== "coverage") { + let events = []; + Object.values(receipt.events).forEach(value => { + const log = constants.EVENT_DETAILS[value.raw.topics[0]]; + const decoded = web3.eth.abi.decodeLog( + log.abi, + value.raw.data, + value.raw.topics + ); + events.push({ + address: contractNames[value.address], + eventName: log.name, + returnValues: decoded + }); + }); + assert.strictEqual(events[0].address, "USDC"); + assert.strictEqual(events[0].eventName, "Approval"); + assert.strictEqual( + events[0].returnValues.value, + constants.FULL_APPROVAL + ); + + assert.strictEqual(events[1].address, "CUSDC"); + assert.strictEqual(events[1].eventName, "AccrueInterest"); + + assert.strictEqual(events[2].address, "USDC"); + assert.strictEqual(events[2].eventName, "Transfer"); + assert.strictEqual( + events[2].returnValues.value, + web3.utils.toWei("100", "lovelace") + ); + + assert.strictEqual(events[3].address, "CUSDC"); + assert.strictEqual(events[3].eventName, "Mint"); + assert.strictEqual( + events[3].returnValues.mintTokens, + web3.utils.toWei("100", "lovelace") + ); + + assert.strictEqual(events[4].address, "CUSDC"); + assert.strictEqual(events[4].eventName, "Transfer"); + } + } + ); + + await tester.runTest( + "Check blacklister address", + tester.FIAT_TOKEN, + "blacklister", + "call", + [], + true, + value => { + blacklister = value; + } + ); + + await tester.runTest( + "Check pauser address", + tester.FIAT_TOKEN, + "pauser", + "call", + [], + true, + value => { + pauser = value; + } + ); + + await tester.runTest( + "blacklist mock address", + tester.FIAT_TOKEN, + "blacklist", + "send", + [constants.MOCK_USDC_BLACKLISTED_ADDRESS], + true, + receipt => {}, + blacklister + ); + + await tester.runTest( + "DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time", + DharmaSmartWalletFactoryV1, + "getNextSmartWallet", + "call", + [constants.MOCK_USDC_BLACKLISTED_ADDRESS], + true, + value => { + targetBlacklistAddress = value; + } + ); + + const BlacklistedUserSmartWalletV6 = new web3.eth.Contract( + DharmaSmartWalletImplementationV6Artifact.abi, + targetBlacklistAddress + ); + + await tester.runTest( + "USDC Whale can deposit usdc into the yet-to-be-blacklisted smart wallet", + tester.USDC, + "transfer", + "send", + [targetBlacklistAddress, web3.utils.toWei("100", "lovelace")], // six decimals + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.USDC_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetBlacklistAddress + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("100", "lovelace") + ); + } + }, + constants.USDC_WHALE_ADDRESS + ); + + await tester.runTest( + "blacklist counterfactual deployment address", + tester.FIAT_TOKEN, + "blacklist", + "send", + [targetBlacklistAddress], + true, + receipt => {}, + blacklister + ); + + await tester.runTest( + "DharmaSmartWalletFactoryV1 can deploy to a blacklisted address", + DharmaSmartWalletFactoryV1, + "newSmartWallet", + "send", + [constants.MOCK_USDC_BLACKLISTED_ADDRESS], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ); + + await tester.runTest( + "blacklisted smart wallet will not approve USDC during repayAndDeposit", + BlacklistedUserSmartWalletV6, + "repayAndDeposit", + "send", + [], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ); + + await tester.runTest( + "un-blacklist counterfactual deployment address", + tester.FIAT_TOKEN, + "unBlacklist", + "send", + [targetBlacklistAddress], + true, + receipt => {}, + blacklister + ); + + await tester.runTest( + "pause USDC", + tester.FIAT_TOKEN, + "pause", + "send", + [], + true, + receipt => {}, + pauser + ); + + await tester.runTest( + "V6 UserSmartWallet can get a USDC withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + constants.FULL_APPROVAL, + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet attempt to withdraw max USDC when paused causes ExternalError", + UserSmartWalletV6, + "withdrawUSDC", + "send", + [ + constants.FULL_APPROVAL, + tester.address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "smart wallet will not approve USDC when paused during repayAndDeposit", + BlacklistedUserSmartWalletV6, + "repayAndDeposit", + "send", + [], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ); + + await tester.runTest( + "unpause USDC", + tester.FIAT_TOKEN, + "unpause", + "send", + [], + true, + receipt => {}, + pauser + ); + + await tester.runTest( + "unblacklisted, unpaused smart wallet approves USDC during repayAndDeposit", + BlacklistedUserSmartWalletV6, + "repayAndDeposit", + "send", + [], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ); + + await tester.runTest( + "V6 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + web3.utils.toWei("50", "lovelace"), + constants.MOCK_USDC_BLACKLISTED_ADDRESS, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay call to withdraw USDC to blacklisted address", + UserSmartWalletV6, + "withdrawUSDC", + "send", + [ + web3.utils.toWei("50", "lovelace"), + constants.MOCK_USDC_BLACKLISTED_ADDRESS, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt.events[0]) + //console.log(receipt.events.ExternalError) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get a USDC withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + constants.FULL_APPROVAL, + UserSmartWalletV6.options.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay call to withdraw USDC to itself", + UserSmartWalletV6, + "withdrawUSDC", + "send", + [ + constants.FULL_APPROVAL, + UserSmartWalletV6.options.address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + constants.FULL_APPROVAL, + constants.MOCK_USDC_BLACKLISTED_ADDRESS, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay call to withdraw USDC to blacklisted address", + UserSmartWalletV6, + "withdrawUSDC", + "send", + [ + constants.FULL_APPROVAL, + constants.MOCK_USDC_BLACKLISTED_ADDRESS, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt.events[0]) + //console.log(receipt.events.ExternalError) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get a Ether withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 6, // ETHWithdrawal, + "1", + targetWalletAddress, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + ethWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay cannot withdraw eth to a non-payable account", + UserSmartWalletV6, + "withdrawEther", + "send", + [ + "1", + targetWalletAddress, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time", + DharmaSmartWalletFactoryV1, + "getNextSmartWallet", + "call", + [targetWalletAddress], + true, + value => { + // TODO: verify against expected value + targetWalletAddressTwo = value; + } + ); + + await tester.runTest( + "DharmaSmartWalletFactoryV1 can deploy a V6 smart wallet using a contract key", + DharmaSmartWalletFactoryV1, + "newSmartWallet", + "send", + [targetWalletAddress] + ); + + const UserSmartWalletV6Two = new web3.eth.Contract( + DharmaSmartWalletImplementationV6Artifact.abi, + targetWalletAddressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet cancel reverts with bad contract signature", + UserSmartWalletV6Two, + "cancel", + "send", + [0, "0x"], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get a generic action ID", + UserSmartWalletV6, + "getNextGenericActionID", + "call", + [ + tester.SAI.options.address, + tester.SAI.methods + .transfer(tester.address, constants.FULL_APPROVAL) + .encodeABI(), + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet can call executeAction", + UserSmartWalletV6, + "executeAction", + "send", + [ + tester.SAI.options.address, + tester.SAI.methods + .transfer(tester.address, constants.FULL_APPROVAL) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ); + + await tester.runTest( + "V6 UserSmartWallet can get a Dai withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 10, // DaiWithdrawal + "1000000000000000000", + constants.NULL_ADDRESS, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + daiWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay cannot withdraw to the null address", + UserSmartWalletV6, + "withdrawDai", + "send", + [ + "1000000000000000000", + constants.NULL_ADDRESS, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt.events) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get a Dai withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 10, // DaiWithdrawal + "100000000000000000000000000000000000000", // too much + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + daiWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay cannot withdraw too much dai", + UserSmartWalletV6, + "withdrawDai", + "send", + [ + "100000000000000000000000000000000000000", // too much + tester.address, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt.events) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get a USDC withdrawal custom action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + "100000000000000000000000000000000000000", // too much + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet relay can call with two signatures to withdraw USDC", + UserSmartWalletV6, + "withdrawUSDC", + "send", + [ + "100000000000000000000000000000000000000", // too much + tester.address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get next generic batch action ID", + UserSmartWalletV6, + "getNextGenericAtomicBatchActionID", + "call", + [ + [ + { + to: tester.DAI.options.address, + data: tester.DAI.methods + .transfer( + tester.address, + "100000000000000000000000000000" + ) + .encodeABI() + } + ], + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet bad executeActionWithAtomicBatchCalls emits CallFailure", + UserSmartWalletV6, + "executeActionWithAtomicBatchCalls", + "send", + [ + [ + { + to: tester.DAI.options.address, + data: tester.DAI.methods + .transfer( + tester.address, + "100000000000000000000000000000" + ) + .encodeABI() + } + ], + 0, + executeActionUserSignature, + executeActionSignature + ], + true, + receipt => { + //console.log(receipt) + } + ); + + await tester.runTest( + "V6 UserSmartWallet can get a generic action ID", + UserSmartWalletV6, + "getNextGenericActionID", + "call", + [ + tester.Comptroller.options.address, + tester.Comptroller.methods + .enterMarkets([constants.CDAI_MAINNET_ADDRESS]) + .encodeABI(), + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet can call executeAction to enter dai market", + UserSmartWalletV6, + "executeAction", + "send", + [ + tester.Comptroller.options.address, + tester.Comptroller.methods + .enterMarkets([constants.CDAI_MAINNET_ADDRESS]) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ); + + await tester.runTest( + "Dai Whale can deposit dai into the smart wallet", + tester.DAI, + "transfer", + "send", + [targetWalletAddress, web3.utils.toWei("100", "ether")], + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.DAI_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("100", "ether") + ); + } + }, + constants.DAI_WHALE_ADDRESS + ); + + await tester.runTest( + "V6 UserSmartWallet can trigger repayAndDeposit to deposit all new funds", + UserSmartWalletV6, + "repayAndDeposit" + ); + + await tester.runTest( + "V6 UserSmartWallet can get a generic action ID", + UserSmartWalletV6, + "getNextGenericActionID", + "call", + [ + tester.CSAI_BORROW.options.address, + tester.CSAI_BORROW.methods + .borrow(web3.utils.toWei(".01", "ether")) + .encodeABI(), + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V6 UserSmartWallet can call executeAction to perform a borrow", + UserSmartWalletV6, + "executeAction", + "send", + [ + tester.CSAI_BORROW.options.address, + tester.CSAI_BORROW.methods + .borrow(web3.utils.toWei(".01", "ether")) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ], + true, + receipt => { + //console.log(receipt.events) + }, + tester.originalAddress + ); + + await tester.runTest( + "V6 UserSmartWallet can get an escape hatch action ID", + UserSmartWalletV6, + "getNextCustomActionID", + "call", + [ + 7, // SetEscapeHatch, + 0, + constants.NULL_ADDRESS, // no recipient + 0 + ], + true, + value => { + customActionId = value; + } + ); + + let escapeHatchSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + let escapeHatchUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "UserSmartWalletV6 can check the user signing key prior to upgrade", + UserSmartWalletV6, + "getUserSigningKey", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.addressTwo); + } + ); + + await tester.runTest( + "UserSmartWalletV6 nonce can be retrieved", + UserSmartWalletV6, + "getNonce", + "call", + [], + true, + value => { + originalNonce = value; + } + ); + + await testPerformingUpgrade( + tester, + DharmaSmartWalletImplementationV7, // new implementation + UserSmartWalletV7, + tester.DharmaUpgradeBeaconController, + tester.DharmaUpgradeBeacon.options.address, + 7 + ); + + await tester.runTest( + "V7 UserSmartWallet can get balances", + UserSmartWalletV7, + "getBalances", + "call", + [], + true, + value => { + //console.log(value) + } + ); + + await tester.runTest( + "V7 UserSmartWallet secondary can call to cancel", + UserSmartWalletV7, + "cancel", + "send", + [0, "0x"] + ); + + await tester.runTest( + "V7 UserSmartWallet nonce is now set to original + 1", + UserSmartWalletV7, + "getNonce", + "call", + [], + true, + value => { + assert.strictEqual(value, (parseInt(originalNonce) + 1).toString()); + } + ); + + await tester.runTest( + "V7 UserSmartWallet can get next custom action ID to set a user signing key", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 1, // SetUserSigningKey, + constants.FULL_APPROVAL, // This value shouldn't matter + tester.addressTwo, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + await tester.runTest( + "V7 UserSmartWallet can set a new user signing key with signatures", + UserSmartWalletV7, + "setUserSigningKey", + "send", + [tester.addressTwo, 0, "0x", setUserSigningKeyDharmaSignature], + true, + receipt => {}, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet has the new user signing key set", + UserSmartWalletV7, + "getUserSigningKey", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.addressTwo); + } + ); + + await tester.runTest( + "cSai can be sent to V7 UserSmartWallet", + tester.CSAI, + "transfer", + "send", + [UserSmartWalletV7.options.address, web3.utils.toWei("0.5", "mwei")] + ); + + await tester.runTest( + "V7 UserSmartWallet relay can trigger cSai to dDai migration before dDai approval", + UserSmartWalletV7, + "migrateCSaiToDDai", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get next custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 0, // DAIWithdrawal + constants.FULL_APPROVAL, + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + await tester.runTest( + "V7 UserSmartWallet can get custom action ID and it matches next action ID", + UserSmartWalletV7, + "getCustomActionID", + "call", + [ + 0, // DAIWithdrawal + constants.FULL_APPROVAL, + tester.address, + parseInt(originalNonce) + 2, + 0 + ], + true, + value => { + assert.strictEqual(value, customActionId); + } + ); + + await tester.runTest( + "V7 UserSmartWallet can get next generic action ID", + UserSmartWalletV7, + "getNextGenericActionID", + "call", + [tester.address, "0x", 0], + true, + value => { + genericActionID = value; + } + ); + + await tester.runTest( + "V7 UserSmartWallet can get generic action ID and it matches next action ID", + UserSmartWalletV7, + "getGenericActionID", + "call", + [tester.address, "0x", parseInt(originalNonce) + 2, 0], + true, + value => { + assert.strictEqual(value, genericActionID); + } + ); + + await tester.runTest( + "UserSmartWallet calls to atomic methods revert", + UserSmartWalletV7, + "_withdrawDaiAtomic", + "send", + ["1", tester.address], + false + ); + + // Give the Dai Whale some ETH so it can make transactions + await web3.eth.sendTransaction({ + from: tester.address, + to: constants.DAI_WHALE_ADDRESS, + value: web3.utils.toWei("1", "ether"), + gas: testingContext !== "coverage" ? "0xffff" : tester.gasLimit - 1, + gasPrice: 1 + }); + + await tester.runTest( + "Dai Whale can deposit Dai into the V7 smart wallet", + tester.DAI, + "transfer", + "send", + [targetWalletAddress, web3.utils.toWei("100", "ether")], + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.DAI_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("100", "ether") + ); + } + }, + constants.DAI_WHALE_ADDRESS + ); + + await tester.runTest( + "USDC Whale can deposit usdc into the V7 smart wallet", + tester.USDC, + "transfer", + "send", + [targetWalletAddress, web3.utils.toWei("100", "lovelace")], // six decimals + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.USDC_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("100", "lovelace") + ); + } + }, + constants.USDC_WHALE_ADDRESS + ); + + await tester.runTest( + "V7 UserSmartWallet can get a generic action ID", + UserSmartWalletV7, + "getNextGenericActionID", + "call", + [ + tester.DAI.options.address, + tester.DAI.methods + .approve(tester.CDAI.options.address, 0) + .encodeABI(), + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet can call executeAction", + UserSmartWalletV7, + "executeAction", + "send", + [ + tester.DAI.options.address, + tester.DAI.methods + .approve(tester.CDAI.options.address, 0) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ); + + await tester.runTest( + "V7 user smart wallet can trigger repayAndDeposit to deposit all new funds", + UserSmartWalletV7, + "repayAndDeposit", + "send", + [], + true, + receipt => { + // TODO: validate + } + ); + + await tester.runTest( + "Dai Whale can deposit dai into the V7 smart wallet", + tester.DAI, + "transfer", + "send", + [targetWalletAddress, web3.utils.toWei("100", "ether")], + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.DAI_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("100", "ether") + ); + } + }, + constants.DAI_WHALE_ADDRESS + ); + + await tester.runTest( + "V7 UserSmartWallet can get a generic action ID", + UserSmartWalletV7, + "getNextGenericActionID", + "call", + [constants.ESCAPE_HATCH_REGISTRY_ADDRESS, "0x", 0], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet cannot call executeAction and target Escape Hatch Registry", + UserSmartWalletV7, + "executeAction", + "send", + [ + constants.ESCAPE_HATCH_REGISTRY_ADDRESS, + "0x", + 0, + executeActionUserSignature, + executeActionSignature + ], + false + ); + + await tester.runTest( + "V7 UserSmartWallet can get a generic action ID", + UserSmartWalletV7, + "getNextGenericActionID", + "call", + [ + tester.DAI.options.address, + tester.DAI.methods + .approve(tester.CDAI.options.address, 0) + .encodeABI(), + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet can call executeAction", + UserSmartWalletV7, + "executeAction", + "send", + [ + tester.DAI.options.address, + tester.DAI.methods + .approve(tester.CDAI.options.address, 0) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ); + + await tester.runTest( + "V7 user smart wallet repayAndDeposit can still deposit without approval", + UserSmartWalletV7, + "repayAndDeposit", + "send", + [], + true, + receipt => { + // TODO: validate + } + ); + + await tester.runTest( + "V7 UserSmartWallet can get a generic action ID", + UserSmartWalletV7, + "getNextGenericActionID", + "call", + [ + tester.DAI.options.address, + tester.DAI.methods + .approve(tester.CDAI.options.address, constants.FULL_APPROVAL) + .encodeABI(), + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet can call executeAction", + UserSmartWalletV7, + "executeAction", + "send", + [ + tester.DAI.options.address, + tester.DAI.methods + .approve(tester.CDAI.options.address, constants.FULL_APPROVAL) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ); + + await tester.runTest( + "V7 user smart wallet repayAndDeposit can deposit with approval added back", + UserSmartWalletV7, + "repayAndDeposit", + "send", + [], + true, + receipt => { + // TODO: validate + } + ); + + await tester.runTest( + "V7 user smart wallet can trigger repayAndDeposit even with no funds", + UserSmartWalletV7, + "repayAndDeposit", + "send", + [], + true, + receipt => { + // TODO: validate + } + ); + + await tester.runTest( + "V7 UserSmartWallet can get custom action ID and it matches next action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 1, // SetUserSigningKey, + 0, + constants.NULL_ADDRESS, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + setUserSigningKeyUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + await tester.runTest( + "V7 UserSmartWallet cannot set the null address as a new user signing key", + UserSmartWalletV7, + "setUserSigningKey", + "send", + [ + constants.NULL_ADDRESS, + 0, + setUserSigningKeyUserSignature, + setUserSigningKeyDharmaSignature + ], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get next custom action ID to set a user signing key", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 1, // SetUserSigningKey, + constants.FULL_APPROVAL, // This value shouldn't matter + tester.addressTwo, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + await tester.runTest( + "UserSmartWallet can get the nonce", + UserSmartWalletV7, + "getNonce", + "call", + [], + true, + value => { + currentNonce = value; + } + ); + + await tester.runTest( + "V7 UserSmartWallet can get custom action ID and it matches next action ID", + UserSmartWalletV7, + "getCustomActionID", + "call", + [ + 1, // SetUserSigningKey, + 0, // Note that this value differs from above + tester.addressTwo, + currentNonce, + 0 + ], + true, + value => { + assert.strictEqual(value, customActionId); + } + ); + + setUserSigningKeyUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + await tester.runTest( + "V7 UserSmartWallet can set a new user signing key with signatures", + UserSmartWalletV7, + "setUserSigningKey", + "send", + [ + tester.addressTwo, + 0, + setUserSigningKeyUserSignature, + setUserSigningKeyDharmaSignature + ], + true, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get next custom action ID to cancel", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 0, // Cancel + constants.FULL_APPROVAL, // This value shouldn't matter + tester.originalAddress, // This value shouldn't matter either + 0 + ], + true, + value => { + customActionId = value; + } + ); + + await tester.runTest( + "UserSmartWallet can get the nonce", + UserSmartWalletV7, + "getNonce", + "call", + [], + true, + value => { + currentNonce = value; + } + ); + + await tester.runTest( + "V7 UserSmartWallet can get custom action ID and it matches next action ID", + UserSmartWalletV7, + "getCustomActionID", + "call", + [ + 0, // Cancel + 0, // Note that this value differs from above + tester.addressTwo, // This one too + currentNonce, + 0 + ], + true, + value => { + assert.strictEqual(value, customActionId); + } + ); + + cancelUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet secondary can cancel using a signature", + UserSmartWalletV7, + "cancel", + "send", + [0, cancelUserSignature], + true, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "UserSmartWallet nonce is incremented after cancelling", + UserSmartWalletV7, + "getNonce", + "call", + [], + true, + value => { + assert.strictEqual(parseInt(value), parseInt(currentNonce) + 1); + } + ); + + await tester.runTest( + "V7 UserSmartWallet secondary cannot call to withdraw dai without primary", + UserSmartWalletV7, + "withdrawDai", + "send", + ["1000000000000000000", tester.address, 0, "0x", "0x"], + false + ); + + await tester.runTest( + "V7 UserSmartWallet secondary cannot call to withdraw usdc without primary", + UserSmartWalletV7, + "withdrawUSDC", + "send", + [1, tester.address, 0, "0x", "0x"], + false + ); + + await tester.runTest( + "V7 UserSmartWallet secondary can no longer call to set userSigningKey without primary", + UserSmartWalletV7, + "setUserSigningKey", + "send", + [tester.address, 0, "0x", "0x"], + false + ); + + await tester.runTest( + "V7 UserSmartWallet can get a USDC withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + "1", // dust + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + 'V7 UserSmartWallet relay cannot withdraw "dust" USDC', + UserSmartWalletV7, + "withdrawUSDC", + "send", + [ + "1", + tester.address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get a USDC withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + "100000", + constants.NULL_ADDRESS, // bad recipient + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot withdraw USDC to null address", + UserSmartWalletV7, + "withdrawUSDC", + "send", + [ + "100000", + constants.NULL_ADDRESS, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get a USDC withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + "100000", + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay can call with two signatures to withdraw USDC", + UserSmartWalletV7, + "withdrawUSDC", + "send", + [ + "100000", + tester.address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get a USDC withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + constants.FULL_APPROVAL, + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot call with bad signature to withdraw USDC", + UserSmartWalletV7, + "withdrawUSDC", + "send", + [ + constants.FULL_APPROVAL, + tester.address, + 0, + usdcUserWithdrawalSignature, + "0xffffffff" + usdcWithdrawalSignature.slice(10) + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet cannot call with bad user signature to withdraw USDC", + UserSmartWalletV7, + "withdrawUSDC", + "send", + [ + constants.FULL_APPROVAL, + tester.address, + 0, + "0xffffffff" + usdcUserWithdrawalSignature.slice(10), + usdcWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet relay can call with two signatures to withdraw max USDC", + UserSmartWalletV7, + "withdrawUSDC", + "send", + [ + constants.FULL_APPROVAL, + tester.address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + /* TODO: get this working manually + const withdrawalMessage = ( + UserSmartWallet.options.address + // smart wallet address + constants.NULL_BYTES_32.slice(2) + // smart wallet version + address.slice(2) + // user dharma key + address.slice(2) + // dharma key registry key + '5'.padStart(64, '0') + // nonce + constants.NULL_BYTES_32.slice(2) + // minimum gas + '04' + // action type + 'f'.padStart(64, 'f') + // amount + address.slice(2) // recipient ) - await tester.runTest( - 'test passes', - DharmaSmartWalletImplementationTestWithConstructor, - 'getVersion', - 'call', - [], - true, - value => { - assert.ok(value.length > 0) - } + const saiWithdrawalSignature = tester.signHashedPrefixedHashedHexString( + withdrawalMessage, + address ) + */ - await tester.runTest( - 'new user smart wallet can be called and has the correct dharma key set', - DharmaSmartWalletImplementationTestWithConstructor, - 'getUserSigningKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, '0x9999999999999999999999999999999999999999') - } - ) - - const DharmaSmartWalletFactoryV1 = await tester.runTest( - `DharmaSmartWalletFactoryV1 contract deployment`, - tester.DharmaSmartWalletFactoryV1Deployer, - '', - 'deploy', - [] - ) - - let targetWalletAddress; - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', - DharmaSmartWalletFactoryV1, - 'getNextSmartWallet', - 'call', - [tester.address], - true, - value => { - // TODO: verify against expected value - targetWalletAddress = value - } - ) - - const UserSmartWalletV6 = new web3.eth.Contract( - DharmaSmartWalletImplementationV6Artifact.abi, - targetWalletAddress - ) - - const UserSmartWalletV7 = new web3.eth.Contract( - DharmaSmartWalletImplementationV7Artifact.abi, - targetWalletAddress - ) - - await testPerformingUpgrade( - tester, - DharmaSmartWalletImplementationV6, // new implementation - UserSmartWalletV6, - tester.DharmaUpgradeBeaconController, - tester.DharmaUpgradeBeacon.options.address, - 6, - true - ) - - contractNames[DharmaSmartWalletFactoryV1.options.address] = 'Smart Wallet Factory' - contractNames[targetWalletAddress] = 'Smart Wallet' - - const ethWhaleBalance = await web3.eth.getBalance(constants.ETH_WHALE_ADDRESS) - const saiWhaleBalance = await web3.eth.getBalance(constants.SAI_WHALE_ADDRESS) - const daiWhaleBalance = await web3.eth.getBalance(constants.DAI_WHALE_ADDRESS) - const usdcWhaleBalance = await web3.eth.getBalance(constants.USDC_WHALE_ADDRESS) - - if (ethWhaleBalance === '0') { - await web3.eth.sendTransaction({ - from: tester.address, - to: constants.ETH_WHALE_ADDRESS, - value: web3.utils.toWei('.2', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : tester.gasLimit - 1, - gasPrice: 1 - }) - console.log(' ✓ Eth Whale can receive eth if needed') - } - - if (saiWhaleBalance === '0') { - await web3.eth.sendTransaction({ - from: tester.address, - to: constants.SAI_WHALE_ADDRESS, - value: web3.utils.toWei('.1', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : tester.gasLimit - 1, - gasPrice: 1 - }) - console.log(' ✓ Sai Whale can receive eth if needed') - } - - if (daiWhaleBalance === '0') { - await web3.eth.sendTransaction({ - from: tester.address, - to: constants.DAI_WHALE_ADDRESS, - value: web3.utils.toWei('.1', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : tester.gasLimit - 1, - gasPrice: 1 - }) - console.log(' ✓ Dai Whale can receive eth if needed') - } - - if (usdcWhaleBalance === '0') { - await web3.eth.sendTransaction({ - from: tester.address, - to: constants.USDC_WHALE_ADDRESS, - value: web3.utils.toWei('.1', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : tester.gasLimit - 1, - gasPrice: 1 - }) - console.log(' ✓ USDC Whale can receive eth if needed') - } - - await web3.eth.sendTransaction({ - from: constants.ETH_WHALE_ADDRESS, - to: targetWalletAddress, - value: web3.utils.toWei('.1', 'ether'), - gas: (testingContext !== 'coverage') ? '0x5208' : tester.gasLimit - 1, - gasPrice: 1 - }) - console.log(' ✓ Eth Whale can deposit eth into the yet-to-be-deployed smart wallet') - - await tester.runTest( - 'Dai Whale can deposit dai into the yet-to-be-deployed smart wallet', - tester.DAI, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'ether')], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.DAI_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'ether') - ) - } - }, - constants.DAI_WHALE_ADDRESS - ) - - await tester.runTest( - 'USDC Whale can deposit usdc into the yet-to-be-deployed smart wallet', - tester.USDC, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.USDC_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'lovelace') - ) - } - }, - constants.USDC_WHALE_ADDRESS - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 cannot deploy a new smart wallet with no key', - DharmaSmartWalletFactoryV1, - 'newSmartWallet', - 'send', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can deploy a new smart wallet using a Dharma Key', - DharmaSmartWalletFactoryV1, - 'newSmartWallet', - 'send', - [tester.address], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - if (typeof log === 'undefined') { - console.log(value) - } - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - - assert.strictEqual(events[0].address, 'Smart Wallet') - assert.strictEqual(events[0].eventName, 'NewUserSigningKey') - assert.strictEqual(events[0].returnValues.userSigningKey, tester.address) - - assert.strictEqual(events[1].address, 'DAI') - assert.strictEqual(events[1].eventName, 'Approval') - assert.strictEqual(events[1].returnValues.value, constants.FULL_APPROVAL) - - assert.strictEqual(events[2].address, 'CDAI') - assert.strictEqual(events[2].eventName, 'AccrueInterest') - - assert.strictEqual(events[3].address, 'DAI') - assert.strictEqual(events[3].eventName, 'Transfer') - assert.strictEqual(events[3].returnValues.value, web3.utils.toWei('100', 'ether')) - - assert.strictEqual(events[4].address, 'CDAI') - assert.strictEqual(events[4].eventName, 'Mint') - assert.strictEqual(events[4].returnValues.mintTokens, web3.utils.toWei('100', 'ether')) - - assert.strictEqual(events[5].address, 'CDAI') - assert.strictEqual(events[5].eventName, 'Transfer') - - assert.strictEqual(events[6].address, 'USDC') - assert.strictEqual(events[6].eventName, 'Approval') - assert.strictEqual(events[6].returnValues.value, constants.FULL_APPROVAL) - - assert.strictEqual(events[7].address, 'CUSDC') - assert.strictEqual(events[7].eventName, 'AccrueInterest') - - assert.strictEqual(events[8].address, 'USDC') - assert.strictEqual(events[8].eventName, 'Transfer') - assert.strictEqual(events[8].returnValues.value, web3.utils.toWei('100', 'lovelace')) - - assert.strictEqual(events[9].address, 'CUSDC') - assert.strictEqual(events[9].eventName, 'Mint') - assert.strictEqual(events[9].returnValues.mintTokens, web3.utils.toWei('100', 'lovelace')) - - assert.strictEqual(events[10].address, 'CUSDC') - assert.strictEqual(events[10].eventName, 'Transfer') - } - } - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 gets a new smart wallet address with same key', - DharmaSmartWalletFactoryV1, - 'getNextSmartWallet', - 'call', - [tester.address], - true, - value => { - // TODO: verify against expected value - assert.ok(targetWalletAddress !== value) - } - ) - - let originalNonce = 0 - await tester.runTest( - 'UserSmartWalletV6 nonce can be retrieved and starts at zero', - UserSmartWalletV6, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, originalNonce.toString()); - } - ) - - await tester.runTest( - 'V6 UserSmartWallet can get balances', - UserSmartWalletV6, - 'getBalances', - 'call', - [], - true, - value => { - //console.log(value) - } - ) - - await tester.runTest( - 'V6 UserSmartWallet secondary can call to cancel', - UserSmartWalletV6, - 'cancel', - 'send', - [ - 0, - '0x' - ] - ) - - await tester.runTest( - 'V6 UserSmartWallet nonce is now set to original + 1', - UserSmartWalletV6, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, (parseInt(originalNonce) + 1).toString()) - } - ) - - await tester.runTest( - 'V6 UserSmartWallet can get next custom action ID to set a user signing key', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 1, // SetUserSigningKey, - constants.FULL_APPROVAL, // This value shouldn't matter - tester.addressTwo, - 0 - ], - true, - value => { - customActionId = value - } - ) - - setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - await tester.runTest( - 'V6 UserSmartWallet can set a new user signing key with signatures', - UserSmartWalletV6, - 'setUserSigningKey', - 'send', - [ - tester.addressTwo, - 0, - '0x', - setUserSigningKeyDharmaSignature - ] - ) - - await tester.runTest( - 'V6 UserSmartWallet has the new user signing key set', - UserSmartWalletV6, - 'getUserSigningKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.addressTwo) - } - ) - - await tester.runTest( - 'cSai can be sent to V6 UserSmartWallet', - tester.CSAI, - 'transfer', - 'send', - [UserSmartWalletV6.options.address, web3.utils.toWei('0.5', 'mwei')] - ) - - await tester.runTest( - 'V6 UserSmartWallet relay can trigger cSai to cDai migration before cDai approval', - UserSmartWalletV6, - 'migrateCSaiToCDai', - 'send', - [], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get next custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 0, // DAIWithdrawal - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - await tester.runTest( - 'V6 UserSmartWallet can get custom action ID and it matches next action ID', - UserSmartWalletV6, - 'getCustomActionID', - 'call', - [ - 0, // DAIWithdrawal - constants.FULL_APPROVAL, - tester.address, - parseInt(originalNonce) + 2, - 0 - ], - true, - value => { - assert.strictEqual(value, customActionId) - } - ) - - await tester.runTest( - 'V6 UserSmartWallet can get next generic action ID', - UserSmartWalletV6, - 'getNextGenericActionID', - 'call', - [ - tester.address, - '0x', - 0 - ], - true, - value => { - genericActionID = value - } - ) - - await tester.runTest( - 'V6 UserSmartWallet can get generic action ID and it matches next action ID', - UserSmartWalletV6, - 'getGenericActionID', - 'call', - [ - tester.address, - '0x', - parseInt(originalNonce) + 2, - 0 - ], - true, - value => { - assert.strictEqual(value, genericActionID) - } - ) - - await tester.runTest( - 'UserSmartWallet calls to atomic methods revert', - UserSmartWalletV6, - '_withdrawDaiAtomic', - 'send', - [ - '1', - tester.address - ], - false - ) - - // Give the Dai Whale some ETH so it can make transactions - await web3.eth.sendTransaction({ - from: tester.address, - to: constants.DAI_WHALE_ADDRESS, - value: web3.utils.toWei('1', 'ether'), - gas: (testingContext !== 'coverage') ? '0xffff' : tester.gasLimit - 1, - gasPrice: 1 - }) - - await tester.runTest( - 'Dai Whale can deposit Dai into the V6 smart wallet', - tester.DAI, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'ether')], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.DAI_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'ether') - ) - } - }, - constants.DAI_WHALE_ADDRESS - ) - - await tester.runTest( - 'USDC Whale can deposit usdc into the V6 smart wallet', - tester.USDC, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.USDC_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'lovelace') - ) - } - }, - constants.USDC_WHALE_ADDRESS - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a generic action ID', - UserSmartWalletV6, - 'getNextGenericActionID', - 'call', - [ - tester.DAI.options.address, - tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet can call executeAction', - UserSmartWalletV6, - 'executeAction', - 'send', - [ - tester.DAI.options.address, - tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'V6 user smart wallet can trigger repayAndDeposit to deposit all new funds', - UserSmartWalletV6, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - - assert.strictEqual(events[0].address, 'DAI') - assert.strictEqual(events[0].eventName, 'Approval') - - assert.strictEqual(events[1].address, 'CDAI') - assert.strictEqual(events[1].eventName, 'AccrueInterest') - - assert.strictEqual(events[2].address, 'DAI') - assert.strictEqual(events[2].eventName, 'Transfer') - //assert.strictEqual(events[2].returnValues.value, web3.utils.toWei('100', 'ether')) - - assert.strictEqual(events[3].address, 'CDAI') - assert.strictEqual(events[3].eventName, 'Mint') - //assert.strictEqual(events[3].returnValues.mintTokens, web3.utils.toWei('100', 'ether')) - - assert.strictEqual(events[4].address, 'CDAI') - assert.strictEqual(events[4].eventName, 'Transfer') - - assert.strictEqual(events[5].address, 'CUSDC') - assert.strictEqual(events[5].eventName, 'AccrueInterest') - - assert.strictEqual(events[6].address, 'USDC') - assert.strictEqual(events[6].eventName, 'Transfer') - //assert.strictEqual(events[6].returnValues.value, web3.utils.toWei('100', 'lovelace')) - - assert.strictEqual(events[7].address, 'CUSDC') - assert.strictEqual(events[7].eventName, 'Mint') - //assert.strictEqual(events[7].returnValues.mintTokens, web3.utils.toWei('100', 'lovelace')) - - assert.strictEqual(events[8].address, 'CUSDC') - assert.strictEqual(events[8].eventName, 'Transfer') - } - } - ) - - await tester.runTest( - 'Dai Whale can deposit dai into the V6 smart wallet', - tester.DAI, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'ether')], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.DAI_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'ether') - ) - } - }, - constants.DAI_WHALE_ADDRESS - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a generic action ID', - UserSmartWalletV6, - 'getNextGenericActionID', - 'call', - [ - constants.ESCAPE_HATCH_REGISTRY_ADDRESS, - '0x', - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet cannot call executeAction and target Escape Hatch Registry', - UserSmartWalletV6, - 'executeAction', - 'send', - [ - constants.ESCAPE_HATCH_REGISTRY_ADDRESS, - '0x', - 0, - executeActionUserSignature, - executeActionSignature - ], - false - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a generic action ID', - UserSmartWalletV6, - 'getNextGenericActionID', - 'call', - [ - tester.DAI.options.address, - tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet can call executeAction', - UserSmartWalletV6, - 'executeAction', - 'send', - [ - tester.DAI.options.address, - tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'V6 user smart wallet repayAndDeposit can still deposit without approval', - UserSmartWalletV6, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - - // TODO: verify - } - } - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a generic action ID', - UserSmartWalletV6, - 'getNextGenericActionID', - 'call', - [ - tester.DAI.options.address, - tester.DAI.methods.approve(tester.CDAI.options.address, constants.FULL_APPROVAL).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet can call executeAction', - UserSmartWalletV6, - 'executeAction', - 'send', - [ - tester.DAI.options.address, - tester.DAI.methods.approve(tester.CDAI.options.address, constants.FULL_APPROVAL).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'V6 user smart wallet repayAndDeposit can deposit with approval added back', - UserSmartWalletV6, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - - // TODO: verify - } - } - ) - - await tester.runTest( - 'V6 user smart wallet can trigger repayAndDeposit even with no funds', - UserSmartWalletV6, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - - assert.strictEqual(events.length, 0) - } - } - ) - - await tester.runTest( - 'V6 UserSmartWallet can get custom action ID and it matches next action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 1, // SetUserSigningKey, - 0, - constants.NULL_ADDRESS, - 0 - ], - true, - value => { - customActionId = value - } - ) - - setUserSigningKeyUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - await tester.runTest( - 'V6 UserSmartWallet cannot set the null address as a new user signing key', - UserSmartWalletV6, - 'setUserSigningKey', - 'send', - [ - constants.NULL_ADDRESS, - 0, - setUserSigningKeyUserSignature, - setUserSigningKeyDharmaSignature - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get next custom action ID to set a user signing key', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 1, // SetUserSigningKey, - constants.FULL_APPROVAL, // This value shouldn't matter - tester.addressTwo, - 0 - ], - true, - value => { - customActionId = value - } - ) - - await tester.runTest( - 'UserSmartWallet can get the nonce', - UserSmartWalletV6, - 'getNonce', - 'call', - [], - true, - value => { - currentNonce = value - } - ) - - await tester.runTest( - 'V6 UserSmartWallet can get custom action ID and it matches next action ID', - UserSmartWalletV6, - 'getCustomActionID', - 'call', - [ - 1, // SetUserSigningKey, - 0, // Note that this value differs from above - tester.addressTwo, - currentNonce, - 0 - ], - true, - value => { - assert.strictEqual(value, customActionId) - } - ) - - setUserSigningKeyUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - await tester.runTest( - 'V6 UserSmartWallet can set a new user signing key with signatures', - UserSmartWalletV6, - 'setUserSigningKey', - 'send', - [ - tester.addressTwo, - 0, - setUserSigningKeyUserSignature, - setUserSigningKeyDharmaSignature - ], - true, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get next custom action ID to cancel', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 0, // Cancel - constants.FULL_APPROVAL, // This value shouldn't matter - tester.originalAddress, // This value shouldn't matter either - 0 - ], - true, - value => { - customActionId = value - } - ) - - await tester.runTest( - 'UserSmartWallet can get the nonce', - UserSmartWalletV6, - 'getNonce', - 'call', - [], - true, - value => { - currentNonce = value - } - ) - - await tester.runTest( - 'V6 UserSmartWallet can get custom action ID and it matches next action ID', - UserSmartWalletV6, - 'getCustomActionID', - 'call', - [ - 0, // Cancel - 0, // Note that this value differs from above - tester.addressTwo, // This one too - currentNonce, - 0 - ], - true, - value => { - assert.strictEqual(value, customActionId) - } - ) - - cancelUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet secondary can cancel using a signature', - UserSmartWalletV6, - 'cancel', - 'send', - [ - 0, - cancelUserSignature - ], - true, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'UserSmartWallet nonce is incremented after cancelling', - UserSmartWalletV6, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(parseInt(value), parseInt(currentNonce) + 1) - } - ) - - await tester.runTest( - 'V6 UserSmartWallet secondary cannot call to withdraw dai without primary', - UserSmartWalletV6, - 'withdrawDai', - 'send', - [ - '1000000000000000000', - tester.address, - 0, - '0x', - '0x' - ], - false - ) - - await tester.runTest( - 'V6 UserSmartWallet secondary cannot call to withdraw usdc without primary', - UserSmartWalletV6, - 'withdrawUSDC', - 'send', - [ - 1, - tester.address, - 0, - '0x', - '0x' - ], - false - ) - - await tester.runTest( - 'V6 UserSmartWallet secondary can no longer call to set userSigningKey without primary', - UserSmartWalletV6, - 'setUserSigningKey', - 'send', - [ - tester.address, - 0, - '0x', - '0x' - ], - false - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - '1', // dust - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot withdraw "dust" USDC', - UserSmartWalletV6, - 'withdrawUSDC', - 'send', - [ - '1', - tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - '100000', - constants.NULL_ADDRESS, // bad recipient - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot withdraw USDC to null address', - UserSmartWalletV6, - 'withdrawUSDC', - 'send', - [ - '100000', - constants.NULL_ADDRESS, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - '100000', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay can call with two signatures to withdraw USDC', - UserSmartWalletV6, - 'withdrawUSDC', - 'send', - [ - '100000', - tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot call with bad signature to withdraw USDC', - UserSmartWalletV6, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - usdcUserWithdrawalSignature, - '0xffffffff' + usdcWithdrawalSignature.slice(10) - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet cannot call with bad user signature to withdraw USDC', - UserSmartWalletV6, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - '0xffffffff' + usdcUserWithdrawalSignature.slice(10), - usdcWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet relay can call with two signatures to withdraw max USDC', - UserSmartWalletV6, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - /* TODO: get this working manually - const withdrawalMessage = ( - UserSmartWallet.options.address + // smart wallet address - constants.NULL_BYTES_32.slice(2) + // smart wallet version - address.slice(2) + // user dharma key - address.slice(2) + // dharma key registry key - '5'.padStart(64, '0') + // nonce - constants.NULL_BYTES_32.slice(2) + // minimum gas - '04' + // action type - 'f'.padStart(64, 'f') + // amount - address.slice(2) // recipient - ) - - const saiWithdrawalSignature = tester.signHashedPrefixedHashedHexString( - withdrawalMessage, - address - ) - */ - - await tester.runTest( - 'V6 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 10, // DaiWithdrawal - '1', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - let daiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - let daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot withdraw "dust" dai', - UserSmartWalletV6, - 'withdrawDai', - 'send', - [ - '1', - tester.address, - 0, - daiUserWithdrawalSignature, - daiWithdrawalSignature - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 10, // DaiWithdrawal - '1000000000000000', - constants.NULL_ADDRESS, - 0 - ], - true, - value => { - customActionId = value - } - ) - - daiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot withdraw dai to null address', - UserSmartWalletV6, - 'withdrawDai', - 'send', - [ - '1000000000000000', - constants.NULL_ADDRESS, - 0, - daiUserWithdrawalSignature, - daiWithdrawalSignature - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 10, // DaiWithdrawal - '1000000000000000', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - daiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay can call with signature to withdraw dai', - UserSmartWalletV6, - 'withdrawDai', - 'send', - [ - '1000000000000000', - tester.address, - 0, - daiUserWithdrawalSignature, - daiWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt.events) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet cannot get a non-custom "custom" next action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 2, // Generic, - constants.FULL_APPROVAL, - tester.address, - 0 - ], - false - ) - - await tester.runTest( - 'V6 UserSmartWallet cannot get a non-custom "custom" action ID', - UserSmartWalletV6, - 'getCustomActionID', - 'call', - [ - 2, // Generic, - constants.FULL_APPROVAL, - tester.address, - 0, - 0 - ], - false - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 10, // DaiWithdrawal - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - daiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot call with bad signature to withdraw dai', - UserSmartWalletV6, - 'withdrawDai', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - daiUserWithdrawalSignature, - '0xffffffff' + daiWithdrawalSignature.slice(10) - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot call with bad user signature to withdraw dai', - UserSmartWalletV6, - 'withdrawDai', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - '0xffffffff' + daiUserWithdrawalSignature.slice(10), - daiWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet relay can call with signature to withdraw sai', - UserSmartWalletV6, - 'withdrawDai', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - daiUserWithdrawalSignature, - daiWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a Ether withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 6, // ETHWithdrawal, - '0', // no amount - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - ethWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot to withdraw ether with no amount', - UserSmartWalletV6, - 'withdrawEther', - 'send', - [ - '0', - tester.address, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a Ether withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 6, // ETHWithdrawal, - '1', - constants.NULL_ADDRESS, // no recipient - 0 - ], - true, - value => { - customActionId = value - } - ) - - ethWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot to withdraw ether with no recipient', - UserSmartWalletV6, - 'withdrawEther', - 'send', - [ - '1', - constants.NULL_ADDRESS, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a Ether withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 6, // ETHWithdrawal, - '1', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - ethWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot call with bad signature to withdraw eth', - UserSmartWalletV6, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - ethUserWithdrawalSignature, - '0xffffffff' + ethWithdrawalSignature.slice(10) - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot call with bad user signature to withdraw eth', - UserSmartWalletV6, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - '0xffffffff' + ethUserWithdrawalSignature.slice(10), - ethWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet relay can call with signature to withdraw ether', - UserSmartWalletV6, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a Ether withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 6, // ETHWithdrawal, - '1', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - ethWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot call with bad signature to withdraw eth', - UserSmartWalletV6, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - ethUserWithdrawalSignature, - '0xffffffff' + ethWithdrawalSignature.slice(10) - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot call with bad user signature to withdraw eth', - UserSmartWalletV6, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - '0xffffffff' + ethUserWithdrawalSignature.slice(10), - ethWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet relay can call with signature to withdraw ether', - UserSmartWalletV6, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet cancel reverts with bad signature', - UserSmartWalletV6, - 'cancel', - 'send', - [ - 0, - '0x' - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet calls revert if insufficient action gas is supplied', - UserSmartWalletV6, - 'cancel', - 'send', - [ - constants.FULL_APPROVAL, - '0x' - ], - false - ) - - await tester.runTest( - 'V6 UserSmartWallet calls succeed if sufficient non-zero action gas supplied', - UserSmartWalletV6, - 'cancel', - 'send', - [ - '1', - '0x' - ] - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a cancel custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 0, // Cancel, - '0', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - cancelSignature = tester.signHashedPrefixedHexString(customActionId, tester.addressTwo) - - await tester.runTest( - 'V6 UserSmartWallet can cancel using a signature', - UserSmartWalletV6, - 'cancel', - 'send', - [ - '0', - cancelSignature - ], - true, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet calls to atomic methods revert', - UserSmartWalletV6, - '_withdrawDaiAtomic', - 'send', - [ - '1', - tester.address - ], - false - ) - - await tester.runTest( - 'V6 UserSmartWallet calls to recover from random address revert', - UserSmartWalletV6, - 'recover', - 'send', - [ - tester.address - ], - false - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can deploy a V6 smart wallet using a Dharma Key', - DharmaSmartWalletFactoryV1, - 'newSmartWallet', - 'send', - [tester.addressTwo], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - - assert.strictEqual(events[0].eventName, 'NewUserSigningKey') - assert.strictEqual(events[0].returnValues.userSigningKey, tester.addressTwo) - //console.log(events) - - // TODO: test more events - } - } - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a generic action ID', - UserSmartWalletV6, - 'getNextGenericActionID', - 'call', - [ - tester.USDC.options.address, - tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet cannot call executeAction and target a non-contract', - UserSmartWalletV6, - 'executeAction', - 'send', - [ - tester.address, - tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ], - false - ) - - await tester.runTest( - 'V6 UserSmartWallet cannot call executeAction and target itself', - UserSmartWalletV6, - 'executeAction', - 'send', - [ - UserSmartWalletV6.options.address, - tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ], - false - ) - - await tester.runTest( - 'V6 UserSmartWallet can call executeAction', - UserSmartWalletV6, - 'executeAction', - 'send', - [ - tester.USDC.options.address, - tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'V6 UserSmartWallet can get the next generic batch action ID', - UserSmartWalletV6, - 'getNextGenericAtomicBatchActionID', - 'call', - [ - [{to: tester.SAI.options.address, data: tester.SAI.methods.totalSupply().encodeABI()}], - 0 - ], - true, - value => { - customActionId = value - } - ) - - await tester.runTest( - 'UserSmartWallet can get the nonce', - UserSmartWalletV6, - 'getNonce', - 'call', - [], - true, - value => { - currentNonce = value - } - ) - - await tester.runTest( - 'V6 UserSmartWallet generic batch action ID with nonce matches next ID', - UserSmartWalletV6, - 'getGenericAtomicBatchActionID', - 'call', - [ - [{to: tester.SAI.options.address, data: tester.SAI.methods.totalSupply().encodeABI()}], - currentNonce, - 0 - ], - true, - value => { - assert.strictEqual(value, customActionId) - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet can call executeActionWithAtomicBatchCalls', - UserSmartWalletV6, - 'executeActionWithAtomicBatchCalls', - 'send', - [ - [{to: tester.SAI.options.address, data: tester.SAI.methods.totalSupply().encodeABI()}], - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'USDC Whale can deposit usdc into the deployed smart wallet', - tester.USDC, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.USDC_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'lovelace') - ) - } - }, - constants.USDC_WHALE_ADDRESS - ) - - await tester.runTest( - 'new user smart wallet can trigger repayAndDeposit to deposit all new funds', - UserSmartWalletV6, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - assert.strictEqual(events[0].address, 'USDC') - assert.strictEqual(events[0].eventName, 'Approval') - assert.strictEqual(events[0].returnValues.value, constants.FULL_APPROVAL) - - assert.strictEqual(events[1].address, 'CUSDC') - assert.strictEqual(events[1].eventName, 'AccrueInterest') - - assert.strictEqual(events[2].address, 'USDC') - assert.strictEqual(events[2].eventName, 'Transfer') - assert.strictEqual(events[2].returnValues.value, web3.utils.toWei('100', 'lovelace')) - - assert.strictEqual(events[3].address, 'CUSDC') - assert.strictEqual(events[3].eventName, 'Mint') - assert.strictEqual(events[3].returnValues.mintTokens, web3.utils.toWei('100', 'lovelace')) - - assert.strictEqual(events[4].address, 'CUSDC') - assert.strictEqual(events[4].eventName, 'Transfer') - } - } - ) - - await tester.runTest( - 'Check blacklister address', - tester.FIAT_TOKEN, - 'blacklister', - 'call', - [], - true, - value => { - blacklister = value - } - ) - - await tester.runTest( - 'Check pauser address', - tester.FIAT_TOKEN, - 'pauser', - 'call', - [], - true, - value => { - pauser = value - } - ) - - await tester.runTest( - 'blacklist mock address', - tester.FIAT_TOKEN, - 'blacklist', - 'send', - [constants.MOCK_USDC_BLACKLISTED_ADDRESS], - true, - receipt => {}, - blacklister - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', - DharmaSmartWalletFactoryV1, - 'getNextSmartWallet', - 'call', - [constants.MOCK_USDC_BLACKLISTED_ADDRESS], - true, - value => { - targetBlacklistAddress = value - } - ) - - const BlacklistedUserSmartWalletV6 = new web3.eth.Contract( - DharmaSmartWalletImplementationV6Artifact.abi, - targetBlacklistAddress - ) - - await tester.runTest( - 'USDC Whale can deposit usdc into the yet-to-be-blacklisted smart wallet', - tester.USDC, - 'transfer', - 'send', - [targetBlacklistAddress, web3.utils.toWei('100', 'lovelace')], // six decimals - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.USDC_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetBlacklistAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'lovelace') - ) - } - }, - constants.USDC_WHALE_ADDRESS - ) - - await tester.runTest( - 'blacklist counterfactual deployment address', - tester.FIAT_TOKEN, - 'blacklist', - 'send', - [targetBlacklistAddress], - true, - receipt => {}, - blacklister - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can deploy to a blacklisted address', - DharmaSmartWalletFactoryV1, - 'newSmartWallet', - 'send', - [constants.MOCK_USDC_BLACKLISTED_ADDRESS], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - 'blacklisted smart wallet will not approve USDC during repayAndDeposit', - BlacklistedUserSmartWalletV6, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - 'un-blacklist counterfactual deployment address', - tester.FIAT_TOKEN, - 'unBlacklist', - 'send', - [targetBlacklistAddress], - true, - receipt => {}, - blacklister - ) - - await tester.runTest( - 'pause USDC', - tester.FIAT_TOKEN, - 'pause', - 'send', - [], - true, - receipt => {}, - pauser - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet attempt to withdraw max USDC when paused causes ExternalError', - UserSmartWalletV6, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'smart wallet will not approve USDC when paused during repayAndDeposit', - BlacklistedUserSmartWalletV6, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - 'unpause USDC', - tester.FIAT_TOKEN, - 'unpause', - 'send', - [], - true, - receipt => {}, - pauser - ) - - await tester.runTest( - 'unblacklisted, unpaused smart wallet approves USDC during repayAndDeposit', - BlacklistedUserSmartWalletV6, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - web3.utils.toWei('50', 'lovelace'), - constants.MOCK_USDC_BLACKLISTED_ADDRESS, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay call to withdraw USDC to blacklisted address', - UserSmartWalletV6, - 'withdrawUSDC', - 'send', - [ - web3.utils.toWei('50', 'lovelace'), - constants.MOCK_USDC_BLACKLISTED_ADDRESS, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt.events[0]) - //console.log(receipt.events.ExternalError) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - constants.FULL_APPROVAL, - UserSmartWalletV6.options.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay call to withdraw USDC to itself', - UserSmartWalletV6, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - UserSmartWalletV6.options.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - constants.FULL_APPROVAL, - constants.MOCK_USDC_BLACKLISTED_ADDRESS, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay call to withdraw USDC to blacklisted address', - UserSmartWalletV6, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - constants.MOCK_USDC_BLACKLISTED_ADDRESS, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt.events[0]) - //console.log(receipt.events.ExternalError) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a Ether withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 6, // ETHWithdrawal, - '1', - targetWalletAddress, - 0 - ], - true, - value => { - customActionId = value - } - ) - - ethWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot withdraw eth to a non-payable account', - UserSmartWalletV6, - 'withdrawEther', - 'send', - [ - '1', - targetWalletAddress, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', - DharmaSmartWalletFactoryV1, - 'getNextSmartWallet', - 'call', - [targetWalletAddress], - true, - value => { - // TODO: verify against expected value - targetWalletAddressTwo = value - } - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can deploy a V6 smart wallet using a contract key', - DharmaSmartWalletFactoryV1, - 'newSmartWallet', - 'send', - [targetWalletAddress] - ) - - const UserSmartWalletV6Two = new web3.eth.Contract( - DharmaSmartWalletImplementationV6Artifact.abi, - targetWalletAddressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet cancel reverts with bad contract signature', - UserSmartWalletV6Two, - 'cancel', - 'send', - [ - 0, - '0x' - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a generic action ID', - UserSmartWalletV6, - 'getNextGenericActionID', - 'call', - [ - tester.SAI.options.address, - tester.SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet can call executeAction', - UserSmartWalletV6, - 'executeAction', - 'send', - [ - tester.SAI.options.address, - tester.SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 10, // DaiWithdrawal - '1000000000000000000', - constants.NULL_ADDRESS, - 0 - ], - true, - value => { - customActionId = value - } - ) - - daiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot withdraw to the null address', - UserSmartWalletV6, - 'withdrawDai', - 'send', - [ - '1000000000000000000', - constants.NULL_ADDRESS, - 0, - daiUserWithdrawalSignature, - daiWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt.events) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 10, // DaiWithdrawal - '100000000000000000000000000000000000000', // too much - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - daiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay cannot withdraw too much dai', - UserSmartWalletV6, - 'withdrawDai', - 'send', - [ - '100000000000000000000000000000000000000', // too much - tester.address, - 0, - daiUserWithdrawalSignature, - daiWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt.events) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - '100000000000000000000000000000000000000', // too much - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet relay can call with two signatures to withdraw USDC', - UserSmartWalletV6, - 'withdrawUSDC', - 'send', - [ - '100000000000000000000000000000000000000', // too much - tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get next generic batch action ID', - UserSmartWalletV6, - 'getNextGenericAtomicBatchActionID', - 'call', - [ - [{ - to: tester.DAI.options.address, - data: tester.DAI.methods.transfer( - tester.address, '100000000000000000000000000000' - ).encodeABI() - }], - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet bad executeActionWithAtomicBatchCalls emits CallFailure', - UserSmartWalletV6, - 'executeActionWithAtomicBatchCalls', - 'send', - [ - [{ - to: tester.DAI.options.address, - data: tester.DAI.methods.transfer( - tester.address, '100000000000000000000000000000' - ).encodeABI() - }], - 0, - executeActionUserSignature, - executeActionSignature - ], - true, - receipt => { - //console.log(receipt) - } - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a generic action ID', - UserSmartWalletV6, - 'getNextGenericActionID', - 'call', - [ - tester.Comptroller.options.address, - tester.Comptroller.methods.enterMarkets( - [constants.CDAI_MAINNET_ADDRESS] - ).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet can call executeAction to enter dai market', - UserSmartWalletV6, - 'executeAction', - 'send', - [ - tester.Comptroller.options.address, - tester.Comptroller.methods.enterMarkets( - [constants.CDAI_MAINNET_ADDRESS] - ).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'Dai Whale can deposit dai into the smart wallet', - tester.DAI, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'ether')], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.DAI_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'ether') - ) - } - }, - constants.DAI_WHALE_ADDRESS - ) - - await tester.runTest( - 'V6 UserSmartWallet can trigger repayAndDeposit to deposit all new funds', - UserSmartWalletV6, - 'repayAndDeposit' - ) - - await tester.runTest( - 'V6 UserSmartWallet can get a generic action ID', - UserSmartWalletV6, - 'getNextGenericActionID', - 'call', - [ - tester.CSAI_BORROW.options.address, - tester.CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V6 UserSmartWallet can call executeAction to perform a borrow', - UserSmartWalletV6, - 'executeAction', - 'send', - [ - tester.CSAI_BORROW.options.address, - tester.CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ], - true, - receipt => { - //console.log(receipt.events) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V6 UserSmartWallet can get an escape hatch action ID', - UserSmartWalletV6, - 'getNextCustomActionID', - 'call', - [ - 7, // SetEscapeHatch, - 0, - constants.NULL_ADDRESS, // no recipient - 0 - ], - true, - value => { - customActionId = value - } - ) - - let escapeHatchSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - let escapeHatchUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'UserSmartWalletV6 can check the user signing key prior to upgrade', - UserSmartWalletV6, - 'getUserSigningKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.addressTwo) - } - ) - - await tester.runTest( - 'UserSmartWalletV6 nonce can be retrieved', - UserSmartWalletV6, - 'getNonce', - 'call', - [], - true, - value => { - originalNonce = value; - } - ) - - await testPerformingUpgrade( - tester, - DharmaSmartWalletImplementationV7, // new implementation - UserSmartWalletV7, - tester.DharmaUpgradeBeaconController, - tester.DharmaUpgradeBeacon.options.address, - 7 - ) - - await tester.runTest( - 'V7 UserSmartWallet can get balances', - UserSmartWalletV7, - 'getBalances', - 'call', - [], - true, - value => { - //console.log(value) - } - ) - - await tester.runTest( - 'V7 UserSmartWallet secondary can call to cancel', - UserSmartWalletV7, - 'cancel', - 'send', - [ - 0, - '0x' - ] - ) - - await tester.runTest( - 'V7 UserSmartWallet nonce is now set to original + 1', - UserSmartWalletV7, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, (parseInt(originalNonce) + 1).toString()) - } - ) - - await tester.runTest( - 'V7 UserSmartWallet can get next custom action ID to set a user signing key', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 1, // SetUserSigningKey, - constants.FULL_APPROVAL, // This value shouldn't matter - tester.addressTwo, - 0 - ], - true, - value => { - customActionId = value - } - ) - - setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - await tester.runTest( - 'V7 UserSmartWallet can set a new user signing key with signatures', - UserSmartWalletV7, - 'setUserSigningKey', - 'send', - [ - tester.addressTwo, - 0, - '0x', - setUserSigningKeyDharmaSignature - ], - true, - receipt => {}, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet has the new user signing key set', - UserSmartWalletV7, - 'getUserSigningKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.addressTwo) - } - ) - - await tester.runTest( - 'cSai can be sent to V7 UserSmartWallet', - tester.CSAI, - 'transfer', - 'send', - [UserSmartWalletV7.options.address, web3.utils.toWei('0.5', 'mwei')] - ) - - await tester.runTest( - 'V7 UserSmartWallet relay can trigger cSai to dDai migration before dDai approval', - UserSmartWalletV7, - 'migrateCSaiToDDai', - 'send', - [], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get next custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 0, // DAIWithdrawal - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - await tester.runTest( - 'V7 UserSmartWallet can get custom action ID and it matches next action ID', - UserSmartWalletV7, - 'getCustomActionID', - 'call', - [ - 0, // DAIWithdrawal - constants.FULL_APPROVAL, - tester.address, - parseInt(originalNonce) + 2, - 0 - ], - true, - value => { - assert.strictEqual(value, customActionId) - } - ) - - await tester.runTest( - 'V7 UserSmartWallet can get next generic action ID', - UserSmartWalletV7, - 'getNextGenericActionID', - 'call', - [ - tester.address, - '0x', - 0 - ], - true, - value => { - genericActionID = value - } - ) - - await tester.runTest( - 'V7 UserSmartWallet can get generic action ID and it matches next action ID', - UserSmartWalletV7, - 'getGenericActionID', - 'call', - [ - tester.address, - '0x', - parseInt(originalNonce) + 2, - 0 - ], - true, - value => { - assert.strictEqual(value, genericActionID) - } - ) - - await tester.runTest( - 'UserSmartWallet calls to atomic methods revert', - UserSmartWalletV7, - '_withdrawDaiAtomic', - 'send', - [ - '1', - tester.address - ], - false - ) - - // Give the Dai Whale some ETH so it can make transactions - await web3.eth.sendTransaction({ - from: tester.address, - to: constants.DAI_WHALE_ADDRESS, - value: web3.utils.toWei('1', 'ether'), - gas: (testingContext !== 'coverage') ? '0xffff' : tester.gasLimit - 1, - gasPrice: 1 - }) - - await tester.runTest( - 'Dai Whale can deposit Dai into the V7 smart wallet', - tester.DAI, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'ether')], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.DAI_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'ether') - ) - } - }, - constants.DAI_WHALE_ADDRESS - ) - - await tester.runTest( - 'USDC Whale can deposit usdc into the V7 smart wallet', - tester.USDC, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.USDC_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'lovelace') - ) - } - }, - constants.USDC_WHALE_ADDRESS - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a generic action ID', - UserSmartWalletV7, - 'getNextGenericActionID', - 'call', - [ - tester.DAI.options.address, - tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet can call executeAction', - UserSmartWalletV7, - 'executeAction', - 'send', - [ - tester.DAI.options.address, - tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'V7 user smart wallet can trigger repayAndDeposit to deposit all new funds', - UserSmartWalletV7, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - // TODO: validate - } - ) - - await tester.runTest( - 'Dai Whale can deposit dai into the V7 smart wallet', - tester.DAI, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'ether')], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.DAI_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'ether') - ) - } - }, - constants.DAI_WHALE_ADDRESS - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a generic action ID', - UserSmartWalletV7, - 'getNextGenericActionID', - 'call', - [ - constants.ESCAPE_HATCH_REGISTRY_ADDRESS, - '0x', - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet cannot call executeAction and target Escape Hatch Registry', - UserSmartWalletV7, - 'executeAction', - 'send', - [ - constants.ESCAPE_HATCH_REGISTRY_ADDRESS, - '0x', - 0, - executeActionUserSignature, - executeActionSignature - ], - false - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a generic action ID', - UserSmartWalletV7, - 'getNextGenericActionID', - 'call', - [ - tester.DAI.options.address, - tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet can call executeAction', - UserSmartWalletV7, - 'executeAction', - 'send', - [ - tester.DAI.options.address, - tester.DAI.methods.approve(tester.CDAI.options.address, 0).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'V7 user smart wallet repayAndDeposit can still deposit without approval', - UserSmartWalletV7, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - // TODO: validate - } - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a generic action ID', - UserSmartWalletV7, - 'getNextGenericActionID', - 'call', - [ - tester.DAI.options.address, - tester.DAI.methods.approve(tester.CDAI.options.address, constants.FULL_APPROVAL).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet can call executeAction', - UserSmartWalletV7, - 'executeAction', - 'send', - [ - tester.DAI.options.address, - tester.DAI.methods.approve(tester.CDAI.options.address, constants.FULL_APPROVAL).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'V7 user smart wallet repayAndDeposit can deposit with approval added back', - UserSmartWalletV7, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - // TODO: validate - } - ) - - await tester.runTest( - 'V7 user smart wallet can trigger repayAndDeposit even with no funds', - UserSmartWalletV7, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - // TODO: validate - } - ) - - await tester.runTest( - 'V7 UserSmartWallet can get custom action ID and it matches next action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 1, // SetUserSigningKey, - 0, - constants.NULL_ADDRESS, - 0 - ], - true, - value => { - customActionId = value - } - ) - - setUserSigningKeyUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - await tester.runTest( - 'V7 UserSmartWallet cannot set the null address as a new user signing key', - UserSmartWalletV7, - 'setUserSigningKey', - 'send', - [ - constants.NULL_ADDRESS, - 0, - setUserSigningKeyUserSignature, - setUserSigningKeyDharmaSignature - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get next custom action ID to set a user signing key', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 1, // SetUserSigningKey, - constants.FULL_APPROVAL, // This value shouldn't matter - tester.addressTwo, - 0 - ], - true, - value => { - customActionId = value - } - ) - - await tester.runTest( - 'UserSmartWallet can get the nonce', - UserSmartWalletV7, - 'getNonce', - 'call', - [], - true, - value => { - currentNonce = value - } - ) - - await tester.runTest( - 'V7 UserSmartWallet can get custom action ID and it matches next action ID', - UserSmartWalletV7, - 'getCustomActionID', - 'call', - [ - 1, // SetUserSigningKey, - 0, // Note that this value differs from above - tester.addressTwo, - currentNonce, - 0 - ], - true, - value => { - assert.strictEqual(value, customActionId) - } - ) - - setUserSigningKeyUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - setUserSigningKeyDharmaSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - await tester.runTest( - 'V7 UserSmartWallet can set a new user signing key with signatures', - UserSmartWalletV7, - 'setUserSigningKey', - 'send', - [ - tester.addressTwo, - 0, - setUserSigningKeyUserSignature, - setUserSigningKeyDharmaSignature - ], - true, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get next custom action ID to cancel', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 0, // Cancel - constants.FULL_APPROVAL, // This value shouldn't matter - tester.originalAddress, // This value shouldn't matter either - 0 - ], - true, - value => { - customActionId = value - } - ) - - await tester.runTest( - 'UserSmartWallet can get the nonce', - UserSmartWalletV7, - 'getNonce', - 'call', - [], - true, - value => { - currentNonce = value - } - ) - - await tester.runTest( - 'V7 UserSmartWallet can get custom action ID and it matches next action ID', - UserSmartWalletV7, - 'getCustomActionID', - 'call', - [ - 0, // Cancel - 0, // Note that this value differs from above - tester.addressTwo, // This one too - currentNonce, - 0 - ], - true, - value => { - assert.strictEqual(value, customActionId) - } - ) - - cancelUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet secondary can cancel using a signature', - UserSmartWalletV7, - 'cancel', - 'send', - [ - 0, - cancelUserSignature - ], - true, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'UserSmartWallet nonce is incremented after cancelling', - UserSmartWalletV7, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(parseInt(value), parseInt(currentNonce) + 1) - } - ) - - await tester.runTest( - 'V7 UserSmartWallet secondary cannot call to withdraw dai without primary', - UserSmartWalletV7, - 'withdrawDai', - 'send', - [ - '1000000000000000000', - tester.address, - 0, - '0x', - '0x' - ], - false - ) - - await tester.runTest( - 'V7 UserSmartWallet secondary cannot call to withdraw usdc without primary', - UserSmartWalletV7, - 'withdrawUSDC', - 'send', - [ - 1, - tester.address, - 0, - '0x', - '0x' - ], - false - ) - - await tester.runTest( - 'V7 UserSmartWallet secondary can no longer call to set userSigningKey without primary', - UserSmartWalletV7, - 'setUserSigningKey', - 'send', - [ - tester.address, - 0, - '0x', - '0x' - ], - false - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - '1', // dust - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot withdraw "dust" USDC', - UserSmartWalletV7, - 'withdrawUSDC', - 'send', - [ - '1', - tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - '100000', - constants.NULL_ADDRESS, // bad recipient - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot withdraw USDC to null address', - UserSmartWalletV7, - 'withdrawUSDC', - 'send', - [ - '100000', - constants.NULL_ADDRESS, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - '100000', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay can call with two signatures to withdraw USDC', - UserSmartWalletV7, - 'withdrawUSDC', - 'send', - [ - '100000', - tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot call with bad signature to withdraw USDC', - UserSmartWalletV7, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - usdcUserWithdrawalSignature, - '0xffffffff' + usdcWithdrawalSignature.slice(10) - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet cannot call with bad user signature to withdraw USDC', - UserSmartWalletV7, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - '0xffffffff' + usdcUserWithdrawalSignature.slice(10), - usdcWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet relay can call with two signatures to withdraw max USDC', - UserSmartWalletV7, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - /* TODO: get this working manually - const withdrawalMessage = ( - UserSmartWallet.options.address + // smart wallet address - constants.NULL_BYTES_32.slice(2) + // smart wallet version - address.slice(2) + // user dharma key - address.slice(2) + // dharma key registry key - '5'.padStart(64, '0') + // nonce - constants.NULL_BYTES_32.slice(2) + // minimum gas - '04' + // action type - 'f'.padStart(64, 'f') + // amount - address.slice(2) // recipient - ) - - const saiWithdrawalSignature = tester.signHashedPrefixedHashedHexString( - withdrawalMessage, - address - ) - */ - - await tester.runTest( - 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 10, // DaiWithdrawal - '1', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - daiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot withdraw "dust" dai', - UserSmartWalletV7, - 'withdrawDai', - 'send', - [ - '1', - tester.address, - 0, - daiUserWithdrawalSignature, - daiWithdrawalSignature - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 10, // DaiWithdrawal - '1000000000000000', - constants.NULL_ADDRESS, - 0 - ], - true, - value => { - customActionId = value - } - ) - - daiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot withdraw dai to null address', - UserSmartWalletV7, - 'withdrawDai', - 'send', - [ - '1000000000000000', - constants.NULL_ADDRESS, - 0, - daiUserWithdrawalSignature, - daiWithdrawalSignature - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 10, // DaiWithdrawal - '1000000000000000', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - daiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay can call with signature to withdraw dai', - UserSmartWalletV7, - 'withdrawDai', - 'send', - [ - '1000000000000000', - tester.address, - 0, - daiUserWithdrawalSignature, - daiWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt.events) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet cannot get a non-custom "custom" next action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 2, // Generic, - constants.FULL_APPROVAL, - tester.address, - 0 - ], - false - ) - - await tester.runTest( - 'V7 UserSmartWallet cannot get a non-custom "custom" action ID', - UserSmartWalletV7, - 'getCustomActionID', - 'call', - [ - 2, // Generic, - constants.FULL_APPROVAL, - tester.address, - 0, - 0 - ], - false - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 10, // DaiWithdrawal - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - daiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot call with bad signature to withdraw dai', - UserSmartWalletV7, - 'withdrawDai', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - daiUserWithdrawalSignature, - '0xffffffff' + daiWithdrawalSignature.slice(10) - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot call with bad user signature to withdraw dai', - UserSmartWalletV7, - 'withdrawDai', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - '0xffffffff' + daiUserWithdrawalSignature.slice(10), - daiWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet relay can call with signature to withdraw sai', - UserSmartWalletV7, - 'withdrawDai', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - daiUserWithdrawalSignature, - daiWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a Ether withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 6, // ETHWithdrawal, - '0', // no amount - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - ethWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot to withdraw ether with no amount', - UserSmartWalletV7, - 'withdrawEther', - 'send', - [ - '0', - tester.address, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a Ether withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 6, // ETHWithdrawal, - '1', - constants.NULL_ADDRESS, // no recipient - 0 - ], - true, - value => { - customActionId = value - } - ) - - ethWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot to withdraw ether with no recipient', - UserSmartWalletV7, - 'withdrawEther', - 'send', - [ - '1', - constants.NULL_ADDRESS, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a Ether withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 6, // ETHWithdrawal, - '1', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - ethWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot call with bad signature to withdraw eth', - UserSmartWalletV7, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - ethUserWithdrawalSignature, - '0xffffffff' + ethWithdrawalSignature.slice(10) - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot call with bad user signature to withdraw eth', - UserSmartWalletV7, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - '0xffffffff' + ethUserWithdrawalSignature.slice(10), - ethWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet relay can call with signature to withdraw ether', - UserSmartWalletV7, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a Ether withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 6, // ETHWithdrawal, - '1', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - ethWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot call with bad signature to withdraw eth', - UserSmartWalletV7, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - ethUserWithdrawalSignature, - '0xffffffff' + ethWithdrawalSignature.slice(10) - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot call with bad user signature to withdraw eth', - UserSmartWalletV7, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - '0xffffffff' + ethUserWithdrawalSignature.slice(10), - ethWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet relay can call with signature to withdraw ether', - UserSmartWalletV7, - 'withdrawEther', - 'send', - [ - '1', - tester.address, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet cancel reverts with bad signature', - UserSmartWalletV7, - 'cancel', - 'send', - [ - 0, - '0x' - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet calls revert if insufficient action gas is supplied', - UserSmartWalletV7, - 'cancel', - 'send', - [ - constants.FULL_APPROVAL, - '0x' - ], - false - ) - - await tester.runTest( - 'V7 UserSmartWallet calls succeed if sufficient non-zero action gas supplied', - UserSmartWalletV7, - 'cancel', - 'send', - [ - '1', - '0x' - ] - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a cancel custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 0, // Cancel, - '0', - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - cancelSignature = tester.signHashedPrefixedHexString(customActionId, tester.addressTwo) - - await tester.runTest( - 'V7 UserSmartWallet can cancel using a signature', - UserSmartWalletV7, - 'cancel', - 'send', - [ - '0', - cancelSignature - ], - true, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet calls to atomic methods revert', - UserSmartWalletV7, - '_withdrawDaiAtomic', - 'send', - [ - '1', - tester.address - ], - false - ) - - await tester.runTest( - 'V7 UserSmartWallet calls to recover from random address revert', - UserSmartWalletV7, - 'recover', - 'send', - [ - tester.address - ], - false - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can deploy a V7 smart wallet using a Dharma Key', - DharmaSmartWalletFactoryV1, - 'newSmartWallet', - 'send', - [tester.addressTwo], - true, - receipt => { - //console.log(receipt.status, receipt.gasUsed) - if (testingContext !== 'coverage') { - let events = [] - Object.values(receipt.events).forEach((value) => { - const log = constants.EVENT_DETAILS[value.raw.topics[0]] - const decoded = web3.eth.abi.decodeLog( - log.abi, value.raw.data, value.raw.topics - ) - events.push({ - address: contractNames[value.address], - eventName: log.name, - returnValues: decoded - }) - }) - - assert.strictEqual(events[0].eventName, 'NewUserSigningKey') - assert.strictEqual(events[0].returnValues.userSigningKey, tester.addressTwo) - //console.log(events) - - // TODO: test more events - } - } - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a generic action ID', - UserSmartWalletV7, - 'getNextGenericActionID', - 'call', - [ - tester.USDC.options.address, - tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet cannot call executeAction and target a non-contract', - UserSmartWalletV7, - 'executeAction', - 'send', - [ - tester.address, - tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ], - false - ) - - await tester.runTest( - 'V7 UserSmartWallet cannot call executeAction and target itself', - UserSmartWalletV7, - 'executeAction', - 'send', - [ - UserSmartWalletV7.options.address, - tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ], - false - ) - - await tester.runTest( - 'V7 UserSmartWallet can call executeAction', - UserSmartWalletV7, - 'executeAction', - 'send', - [ - tester.USDC.options.address, - tester.USDC.methods.approve(tester.CUSDC.options.address, 0).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'V7 UserSmartWallet can get the next generic batch action ID', - UserSmartWalletV7, - 'getNextGenericAtomicBatchActionID', - 'call', - [ - [{to: tester.SAI.options.address, data: tester.SAI.methods.totalSupply().encodeABI()}], - 0 - ], - true, - value => { - customActionId = value - } - ) - - await tester.runTest( - 'UserSmartWallet can get the nonce', - UserSmartWalletV7, - 'getNonce', - 'call', - [], - true, - value => { - currentNonce = value - } - ) - - await tester.runTest( - 'V7 UserSmartWallet generic batch action ID with nonce matches next ID', - UserSmartWalletV7, - 'getGenericAtomicBatchActionID', - 'call', - [ - [{to: tester.SAI.options.address, data: tester.SAI.methods.totalSupply().encodeABI()}], - currentNonce, - 0 - ], - true, - value => { - assert.strictEqual(value, customActionId) - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet can call executeActionWithAtomicBatchCalls', - UserSmartWalletV7, - 'executeActionWithAtomicBatchCalls', - 'send', - [ - [{to: tester.SAI.options.address, data: tester.SAI.methods.totalSupply().encodeABI()}], - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'USDC Whale can deposit usdc into the deployed smart wallet', - tester.USDC, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'lovelace')], // six decimals - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.USDC_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'lovelace') - ) - } - }, - constants.USDC_WHALE_ADDRESS - ) - - await tester.runTest( - 'new user smart wallet can trigger repayAndDeposit to deposit all new funds', - UserSmartWalletV7, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - // TODO: validate - } - ) - - await tester.runTest( - 'Check blacklister address', - tester.FIAT_TOKEN, - 'blacklister', - 'call', - [], - true, - value => { - blacklister = value - } - ) - - await tester.runTest( - 'Check pauser address', - tester.FIAT_TOKEN, - 'pauser', - 'call', - [], - true, - value => { - pauser = value - } - ) - - await tester.runTest( - 'blacklist mock address', - tester.FIAT_TOKEN, - 'blacklist', - 'send', - [constants.MOCK_USDC_BLACKLISTED_ADDRESS], - true, - receipt => {}, - blacklister - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', - DharmaSmartWalletFactoryV1, - 'getNextSmartWallet', - 'call', - [constants.MOCK_USDC_BLACKLISTED_ADDRESS], - true, - value => { - targetBlacklistAddress = value - } - ) - - const BlacklistedUserSmartWalletV7 = new web3.eth.Contract( - DharmaSmartWalletImplementationV7Artifact.abi, - targetBlacklistAddress - ) - - await tester.runTest( - 'USDC Whale can deposit usdc into the yet-to-be-blacklisted smart wallet', - tester.USDC, - 'transfer', - 'send', - [targetBlacklistAddress, web3.utils.toWei('100', 'lovelace')], // six decimals - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.USDC_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetBlacklistAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'lovelace') - ) - } - }, - constants.USDC_WHALE_ADDRESS - ) - - await tester.runTest( - 'blacklist counterfactual deployment address', - tester.FIAT_TOKEN, - 'blacklist', - 'send', - [targetBlacklistAddress], - true, - receipt => {}, - blacklister - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can deploy to a blacklisted address', - DharmaSmartWalletFactoryV1, - 'newSmartWallet', - 'send', - [constants.MOCK_USDC_BLACKLISTED_ADDRESS], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - 'blacklisted smart wallet will not approve USDC during repayAndDeposit', - BlacklistedUserSmartWalletV7, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - 'un-blacklist counterfactual deployment address', - tester.FIAT_TOKEN, - 'unBlacklist', - 'send', - [targetBlacklistAddress], - true, - receipt => {}, - blacklister - ) - - await tester.runTest( - 'pause USDC', - tester.FIAT_TOKEN, - 'pause', - 'send', - [], - true, - receipt => {}, - pauser - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - constants.FULL_APPROVAL, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet attempt to withdraw max USDC when paused causes ExternalError', - UserSmartWalletV7, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'smart wallet will not approve USDC when paused during repayAndDeposit', - BlacklistedUserSmartWalletV7, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - 'unpause USDC', - tester.FIAT_TOKEN, - 'unpause', - 'send', - [], - true, - receipt => {}, - pauser - ) - - await tester.runTest( - 'unblacklisted, unpaused smart wallet approves USDC during repayAndDeposit', - BlacklistedUserSmartWalletV7, - 'repayAndDeposit', - 'send', - [], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - web3.utils.toWei('50', 'lovelace'), - constants.MOCK_USDC_BLACKLISTED_ADDRESS, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay call to withdraw USDC to blacklisted address', - UserSmartWalletV7, - 'withdrawUSDC', - 'send', - [ - web3.utils.toWei('50', 'lovelace'), - constants.MOCK_USDC_BLACKLISTED_ADDRESS, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt.events[0]) - //console.log(receipt.events.ExternalError) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - constants.FULL_APPROVAL, - UserSmartWalletV7.options.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay call to withdraw USDC to itself', - UserSmartWalletV7, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - UserSmartWalletV7.options.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - constants.FULL_APPROVAL, - constants.MOCK_USDC_BLACKLISTED_ADDRESS, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay call to withdraw USDC to blacklisted address', - UserSmartWalletV7, - 'withdrawUSDC', - 'send', - [ - constants.FULL_APPROVAL, - constants.MOCK_USDC_BLACKLISTED_ADDRESS, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt.events[0]) - //console.log(receipt.events.ExternalError) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a Ether withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 6, // ETHWithdrawal, - '1', - targetWalletAddress, - 0 - ], - true, - value => { - customActionId = value - } - ) - - ethWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot withdraw eth to a non-payable account', - UserSmartWalletV7, - 'withdrawEther', - 'send', - [ - '1', - targetWalletAddress, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time', - DharmaSmartWalletFactoryV1, - 'getNextSmartWallet', - 'call', - [targetWalletAddress], - true, - value => { - // TODO: verify against expected value - targetWalletAddressTwo = value - } - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can deploy a V7 smart wallet using a contract key', - DharmaSmartWalletFactoryV1, - 'newSmartWallet', - 'send', - [targetWalletAddress] - ) - - const UserSmartWalletV7Two = new web3.eth.Contract( - DharmaSmartWalletImplementationV7Artifact.abi, - targetWalletAddressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet cancel reverts with bad contract signature', - UserSmartWalletV7Two, - 'cancel', - 'send', - [ - 0, - '0x' - ], - false, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a generic action ID', - UserSmartWalletV7, - 'getNextGenericActionID', - 'call', - [ - tester.SAI.options.address, - tester.SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet can call executeAction', - UserSmartWalletV7, - 'executeAction', - 'send', - [ - tester.SAI.options.address, - tester.SAI.methods.transfer(tester.address, constants.FULL_APPROVAL).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 10, // DaiWithdrawal - '1000000000000000000', - constants.NULL_ADDRESS, - 0 - ], - true, - value => { - customActionId = value - } - ) - - daiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot withdraw to the null address', - UserSmartWalletV7, - 'withdrawDai', - 'send', - [ - '1000000000000000000', - constants.NULL_ADDRESS, - 0, - daiUserWithdrawalSignature, - daiWithdrawalSignature - ], - false, - receipt => { - // TODO: verify logs - //console.log(receipt.events) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a Dai withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 10, // DaiWithdrawal - '100000000000000000000000000000000000000', // too much - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - daiWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot withdraw too much dai', - UserSmartWalletV7, - 'withdrawDai', - 'send', - [ - '100000000000000000000000000000000000000', // too much - tester.address, - 0, - daiUserWithdrawalSignature, - daiWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt.events) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a USDC withdrawal custom action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 5, // USDCWithdrawal, - '100000000000000000000000000000000000000', // too much - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - usdcWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay can call with two signatures to withdraw USDC', - UserSmartWalletV7, - 'withdrawUSDC', - 'send', - [ - '100000000000000000000000000000000000000', // too much - tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get next generic batch action ID', - UserSmartWalletV7, - 'getNextGenericAtomicBatchActionID', - 'call', - [ - [{ - to: tester.DAI.options.address, - data: tester.DAI.methods.transfer( - tester.address, '100000000000000000000000000000' - ).encodeABI() - }], - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet bad executeActionWithAtomicBatchCalls emits CallFailure', - UserSmartWalletV7, - 'executeActionWithAtomicBatchCalls', - 'send', - [ - [{ - to: tester.DAI.options.address, - data: tester.DAI.methods.transfer( - tester.address, '100000000000000000000000000000' - ).encodeABI() - }], - 0, - executeActionUserSignature, - executeActionSignature - ], - true, - receipt => { - //console.log(receipt) - } - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a generic action ID', - UserSmartWalletV7, - 'getNextGenericActionID', - 'call', - [ - tester.Comptroller.options.address, - tester.Comptroller.methods.enterMarkets( - [constants.CDAI_MAINNET_ADDRESS] - ).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet can call executeAction to enter dai market', - UserSmartWalletV7, - 'executeAction', - 'send', - [ - tester.Comptroller.options.address, - tester.Comptroller.methods.enterMarkets( - [constants.CDAI_MAINNET_ADDRESS] - ).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ] - ) - - await tester.runTest( - 'Dai Whale can deposit dai into the smart wallet', - tester.DAI, - 'transfer', - 'send', - [targetWalletAddress, web3.utils.toWei('100', 'ether')], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.DAI_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - targetWalletAddress - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('100', 'ether') - ) - } - }, - constants.DAI_WHALE_ADDRESS - ) - - await tester.runTest( - 'V7 UserSmartWallet can trigger repayAndDeposit to deposit all new funds', - UserSmartWalletV7, - 'repayAndDeposit' - ) - - await tester.runTest( - 'V7 UserSmartWallet can get a generic action ID', - UserSmartWalletV7, - 'getNextGenericActionID', - 'call', - [ - tester.CSAI_BORROW.options.address, - tester.CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), - 0 - ], - true, - value => { - customActionId = value - } - ) - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet can call executeAction to perform a borrow', - UserSmartWalletV7, - 'executeAction', - 'send', - [ - tester.CSAI_BORROW.options.address, - tester.CSAI_BORROW.methods.borrow(web3.utils.toWei('.01', 'ether')).encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature - ], - true, - receipt => { - //console.log(receipt.events) - }, - tester.originalAddress - ) - - - - - await tester.runTest( - 'V7 UserSmartWallet can get an escape hatch action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 7, // SetEscapeHatch, - 0, - constants.NULL_ADDRESS, // no recipient - 0 - ], - true, - value => { - customActionId = value - } - ) - - escapeHatchSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - escapeHatchUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot set an escape hatch with no account', - UserSmartWalletV7, - 'setEscapeHatch', - 'send', - [ - constants.NULL_ADDRESS, - 0, - escapeHatchUserSignature, - escapeHatchSignature - ], - false, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get an escape hatch action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 7, // SetEscapeHatch, - 0, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - escapeHatchSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - escapeHatchUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet cannot call escape before escape hatch is set', - UserSmartWalletV7, - 'escape', - 'send', - [], - false, - receipt => { - // TODO: verify logs - } - ) - - await tester.runTest( - 'V7 UserSmartWallet relay can set an escape hatch', - UserSmartWalletV7, - 'setEscapeHatch', - 'send', - [ - tester.address, - 0, - escapeHatchUserSignature, - escapeHatchSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet non-escape hatch account cannot call escape', - UserSmartWalletV7, - 'escape', - 'send', - [], - false, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet escape hatch account can call escape', - UserSmartWalletV7, - 'escape', - 'send', - [], - true, - receipt => { - // TODO: verify logs - }, - tester.address - ) - - await tester.runTest( - 'V7 UserSmartWallet escape hatch account can call escape again', - UserSmartWalletV7, - 'escape', - 'send', - [], - true, - receipt => { - // TODO: verify logs - }, - tester.address - ) - - await tester.runTest( - 'V7 UserSmartWallet can get an escape hatch action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 8, // RemoveEscapeHatch, - 0, - constants.NULL_ADDRESS, - 0 - ], - true, - value => { - customActionId = value - } - ) - - escapeHatchSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - escapeHatchUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay can remove an escape hatch', - UserSmartWalletV7, - 'removeEscapeHatch', - 'send', - [ - 0, - escapeHatchUserSignature, - escapeHatchSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet cannot call escape once escape hatch is removed', - UserSmartWalletV7, - 'escape', - 'send', - [], - false, - receipt => { - // TODO: verify logs - } - ) - - await tester.runTest( - 'V7 UserSmartWallet can get an escape hatch action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 9, // DisableEscapeHatch, - 0, - constants.NULL_ADDRESS, - 0 - ], - true, - value => { - customActionId = value - } - ) - - escapeHatchSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - escapeHatchUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay can disable the escape hatch', - UserSmartWalletV7, - 'permanentlyDisableEscapeHatch', - 'send', - [ - 0, - escapeHatchUserSignature, - escapeHatchSignature - ], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet can get an escape hatch action ID', - UserSmartWalletV7, - 'getNextCustomActionID', - 'call', - [ - 7, // SetEscapeHatch, - 0, - tester.address, - 0 - ], - true, - value => { - customActionId = value - } - ) - - escapeHatchSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ) - - escapeHatchUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ) - - await tester.runTest( - 'V7 UserSmartWallet relay cannot set an escape hatch once disabled', - UserSmartWalletV7, - 'setEscapeHatch', - 'send', - [ - tester.address, - 0, - escapeHatchUserSignature, - escapeHatchSignature - ], - false, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet relay can trigger sai to dai migration as a no-op', - UserSmartWalletV7, - 'migrateSaiToDai', - 'send', - [], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet relay can trigger cSai to dDai migration as a no-op', - UserSmartWalletV7, - 'migrateCSaiToDDai', - 'send', - [], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'cSai can be sent to V7 UserSmartWallet', - tester.CSAI, - 'transfer', - 'send', - [UserSmartWalletV7.options.address, web3.utils.toWei('0.5', 'mwei')] - ) - - await tester.runTest( - 'Sai Whale can deposit sai into the V7 user smart wallet', - tester.SAI, - 'transfer', - 'send', - [UserSmartWalletV7.options.address, web3.utils.toWei('1', 'ether')], - true, - receipt => { - if (testingContext !== 'coverage') { - assert.strictEqual( - receipt.events.Transfer.returnValues.from, - constants.SAI_WHALE_ADDRESS - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.to, - UserSmartWalletV7.options.address - ) - assert.strictEqual( - receipt.events.Transfer.returnValues.value, - web3.utils.toWei('1', 'ether') - ) - } - }, - constants.SAI_WHALE_ADDRESS - ) - - await tester.runTest( - 'V7 UserSmartWallet relay can trigger sai to dai migration', - UserSmartWalletV7, - 'migrateSaiToDai', - 'send', - [], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - await tester.runTest( - 'V7 UserSmartWallet relay can trigger cSai to dDai migration', - UserSmartWalletV7, - 'migrateCSaiToDDai', - 'send', - [], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ) - - // Initiate account recovery - await tester.runTest( - 'smart wallet account recovery can be initiated', - tester.DharmaAccountRecoveryManagerV2, - 'initiateAccountRecovery', - 'send', - [ - UserSmartWalletV7.options.address, - tester.originalAddress, - 0 // extraTime in seconds - ], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - await tester.runTest( - 'smart wallet account recovery cannot be performed right away', - tester.DharmaAccountRecoveryManagerV2, - 'recover', - 'send', - [ - UserSmartWalletV7.options.address, - tester.originalAddress - ], - false - ) - - // advance time by 3 days - await tester.advanceTime((60 * 60 * 24 * 3) + 5) - - // recover account - await tester.runTest( - 'smart wallet account recovery can be performed after three days', - tester.DharmaAccountRecoveryManagerV2, - 'recover', - 'send', - [ - UserSmartWalletV7.options.address, - tester.originalAddress - ], - true, - receipt => { - // TODO: verify - //console.log(receipt.events) - } - ) - - // ZZZZZ - - // COVERAGE TESTING - deployments - const DharmaUpgradeBeaconControllerManagerCoverage = await tester.runTest( - `DharmaUpgradeBeaconControllerManager contract deployment`, - tester.DharmaUpgradeBeaconControllerManagerDeployer, - '', - 'deploy' - ) - - const DharmaUpgradeBeaconControllerCoverage = await tester.runTest( - `DharmaUpgradeBeaconController contract deployment`, - tester.DharmaUpgradeBeaconControllerDeployer, - '', - 'deploy' - ) - - const DharmaUpgradeBeaconCoverage = await tester.runTest( - `DharmaUpgradeBeacon (smart wallet) contract deployment`, - tester.DharmaUpgradeBeaconDeployer, - '', - 'deploy' - ) - - const DharmaKeyRingUpgradeBeaconCoverage = await tester.runTest( - `DharmaKeyRingUpgradeBeacon contract deployment`, - tester.DharmaKeyRingUpgradeBeaconDeployer, - '', - 'deploy' - ) - - const DharmaUpgradeBeaconEnvoy = await tester.runTest( - `DharmaUpgradeBeaconEnvoy contract deployment`, - tester.DharmaUpgradeBeaconEnvoyDeployer, - '', - 'deploy' - ) - - await testUpgradeBeaconController( - tester, - DharmaUpgradeBeaconControllerCoverage, // controller manager - tester.DharmaUpgradeBeaconController, // smart wallet controller contract - tester.DharmaKeyRingUpgradeBeaconController, // key ring controller contract - DharmaUpgradeBeaconEnvoy, // envoy contract - DharmaUpgradeBeaconCoverage.options.address, // owned smart wallet beacon - DharmaKeyRingUpgradeBeaconCoverage.options.address, // owned key ring beacon - BadBeaconTwo.options.address // "bad" beacon - ); - - const DharmaKeyRegistryV2Coverage = await tester.runTest( - `DharmaKeyRegistryV2 contract deployment`, - tester.DharmaKeyRegistryV2Deployer, - '', - 'deploy' - ) - - const AdharmaSmartWalletImplementation = await tester.runTest( - `AdharmaSmartWalletImplementation contract deployment`, - tester.AdharmaSmartWalletImplementationDeployer, - '', - 'deploy' - ) - - const AdharmaKeyRingImplementation = await tester.runTest( - `AdharmaKeyRingImplementation contract deployment`, - tester.AdharmaKeyRingImplementationDeployer, - '', - 'deploy' - ) - - const DharmaSmartWalletFactoryV1Coverage = await tester.runTest( - `DharmaSmartWalletFactoryV1 contract deployment`, - tester.DharmaSmartWalletFactoryV1Deployer, - '', - 'deploy', - [] - ) - - const DharmaKeyRingFactoryV1 = await tester.runTest( - `DharmaKeyRingFactoryV1 contract deployment`, - tester.DharmaKeyRingFactoryV1Deployer, - '', - 'deploy', - [] - ) - - const DharmaKeyRingFactoryV2 = await tester.runTest( - `DharmaKeyRingFactoryV2 contract deployment`, - tester.DharmaKeyRingFactoryV2Deployer, - '', - 'deploy', - [] - ) - - await tester.runTest( - `DharmaKeyRingFactoryV1 cannot create a V1 key ring with no key`, - DharmaKeyRingFactoryV1, - 'newKeyRing', - 'send', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaKeyRingFactoryV1 cannot create a V1 key ring and set a new null key`, - DharmaKeyRingFactoryV1, - 'newKeyRingAndAdditionalKey', - 'send', - [tester.address, constants.NULL_ADDRESS, '0x'], - false - ) - - await tester.runTest( - `DharmaKeyRingFactoryV1 cannot create a V1 key ring and set a duplicate key`, - DharmaKeyRingFactoryV1, - 'newKeyRingAndAdditionalKey', - 'send', - [tester.address, tester.address, '0x'], - false - ) - - await tester.runTest( - `DharmaKeyRingFactoryV1 can get the address of the next key ring`, - DharmaKeyRingFactoryV1, - 'getNextKeyRing', - 'call', - [tester.address], - true, - value => { - nextKeyRing = value; - } - ) - - await tester.runTest( - `DharmaKeyRingFactoryV1 can create a V1 key ring`, - DharmaKeyRingFactoryV1, - 'newKeyRing', - 'send', - [tester.address] - ) - - const KeyRingInstance = new web3.eth.Contract( - DharmaKeyRingImplementationV1Artifact.abi, - nextKeyRing - ) - - await tester.runTest( - `DharmaKeyRingFactoryV1 gets new key ring after a deploy with same input`, - DharmaKeyRingFactoryV1, - 'getNextKeyRing', - 'call', - [tester.address], - true, - value => { - assert.ok(nextKeyRing !== value) - } - ) - - await tester.runTest( - `KeyRingInstance can get the version of the key ring`, - KeyRingInstance, - 'getVersion', - 'call', - [], - true, - value => { - assert.strictEqual(value, '1') - } - ) - - await tester.runTest( - `KeyRingInstance can get the nonce of the key ring`, - KeyRingInstance, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - `KeyRingInstance can get the key count of the key ring`, - KeyRingInstance, - 'getKeyCount', - 'call', - [], - true, - value => { - assert.strictEqual(value.adminKeyCount, '1') - assert.strictEqual(value.standardKeyCount, '1') - } - ) - - await tester.runTest( - `KeyRingInstance can does not verify a bad signature`, - KeyRingInstance, - 'isValidSignature', - 'call', - [ - web3.eth.abi.encodeParameters( - ['bytes32', 'uint8', 'bytes'], - [constants.NULL_BYTES_32, 1, '0x'] - ), - '0x' - ], - false - ) - - await tester.runTest( - `KeyRingInstance can get an adminActionID using getNextAdminActionID`, - KeyRingInstance, - 'getNextAdminActionID', - 'call', - [1, 1], - true, - value => { - adminActionID = value - } - ) - - await tester.runTest( - `KeyRingInstance getAdminActionID matches getNextAdminActionID`, - KeyRingInstance, - 'getAdminActionID', - 'call', - [1, 1, 0], - true, - value => { - assert.strictEqual(value, adminActionID) - } - ) - - await tester.runTest( - `KeyRingInstance cannot add a non-dual key in V1`, - KeyRingInstance, - 'takeAdminAction', - 'send', - [1, 1, '0x'], - false - ) - - await tester.runTest( - `KeyRingInstance cannot add key that already exists`, - KeyRingInstance, - 'takeAdminAction', - 'send', - [6, tester.address, '0x'], - false - ) - - const takeAdminActionSignature = tester.signHashedPrefixedHexString( - adminActionID, - tester.address - ) - - await tester.runTest( - `KeyRingInstance can verify a valid signature`, - KeyRingInstance, - 'isValidSignature', - 'call', - [ - web3.eth.abi.encodeParameters( - ['bytes32', 'uint8', 'bytes'], - [ - web3.utils.keccak256( - // prefix => "\x19Ethereum Signed Message:\n32" - "0x19457468657265756d205369676e6564204d6573736167653a0a3332" + - adminActionID.slice(2), - {encoding: "hex"} - ), 1, '0x'] - ), - takeAdminActionSignature - ], - true, - value => { - assert.strictEqual(value, '0x20c13b0b') - } - ) - - await tester.runTest( - `KeyRingInstance can add a new key with a valid signature`, - KeyRingInstance, - 'takeAdminAction', - 'send', - [6, 1, takeAdminActionSignature], - true - ) - - await tester.runTest( - `DharmaKeyRingFactoryV2 cannot create a V1 key ring with no key`, - DharmaKeyRingFactoryV2, - 'newKeyRing', - 'send', - [constants.NULL_ADDRESS, constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaKeyRingFactoryV2 cannot create a V1 key ring and set a new null key`, - DharmaKeyRingFactoryV2, - 'newKeyRingAndAdditionalKey', - 'send', - [tester.address, constants.NULL_ADDRESS, constants.NULL_ADDRESS, '0x'], - false - ) - - await tester.runTest( - `DharmaKeyRingFactoryV2 cannot create a V1 key ring and set a duplicate key`, - DharmaKeyRingFactoryV2, - 'newKeyRingAndAdditionalKey', - 'send', - [tester.address, constants.NULL_ADDRESS, tester.address, '0x'], - false - ) - - await tester.runTest( - `DharmaKeyRingFactoryV2 can get the address of the next key ring`, - DharmaKeyRingFactoryV2, - 'getNextKeyRing', - 'call', - [tester.address], - true, - value => { - nextKeyRing = value; - } - ) - - await tester.runTest( - `DharmaKeyRingFactoryV2 can create a V1 key ring if the target address matches`, - DharmaKeyRingFactoryV2, - 'newKeyRing', - 'send', - [tester.address, nextKeyRing] - ) - - const KeyRingInstanceFromV2Factory = new web3.eth.Contract( - DharmaKeyRingImplementationV1Artifact.abi, - nextKeyRing - ) - - await tester.runTest( - `DharmaKeyRingFactoryV2 won't deploy a V1 key ring if the target address has one`, - DharmaKeyRingFactoryV2, - 'newKeyRing', - 'send', - [tester.address, KeyRingInstanceFromV2Factory.options.address] - ) - - await tester.runTest( - `DharmaKeyRingFactoryV2 can call getFirstKeyRingAdminActionID`, - DharmaKeyRingFactoryV2, - 'getFirstKeyRingAdminActionID', - 'call', - [tester.address, tester.address] - ) - - await tester.runTest( - `DharmaKeyRingFactoryV2 reverts when no new key ring supplied`, - DharmaKeyRingFactoryV2, - 'getNextKeyRing', - 'call', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaKeyRingFactoryV2 gets new key ring after a deploy with same input`, - DharmaKeyRingFactoryV2, - 'getNextKeyRing', - 'call', - [tester.address], - true, - value => { - assert.ok(nextKeyRing !== value) - } - ) - - await tester.runTest( - `DharmaKeyRingFactoryV2 can call newKeyRingAndDaiWithdrawal`, - DharmaKeyRingFactoryV2, - 'newKeyRingAndDaiWithdrawal', - 'send', - [tester.address, tester.address, tester.address, 0, tester.address, 0, '0x', '0x'], - false - ) - - await tester.runTest( - `DharmaKeyRingFactoryV2 can call newKeyRingAndUSDCWithdrawal`, - DharmaKeyRingFactoryV2, - 'newKeyRingAndUSDCWithdrawal', - 'send', - [tester.address, tester.address, tester.address, 0, tester.address, 0, '0x', '0x'], - false - ) - - await tester.runTest( - `AdharmaSmartWalletImplementation cannot be initialized directly post-deployment`, - AdharmaSmartWalletImplementation, - 'initialize', - 'send', - [tester.address], - false - ) - - await tester.runTest( - `AdharmaSmartWalletImplementation cannot be used to perform calls directly`, - AdharmaSmartWalletImplementation, - 'performCall', - 'send', - [tester.address, 1, '0x'], - false - ) - - await tester.runTest( - `AdharmaKeyRingImplementation cannot be initialized directly post-deployment`, - AdharmaKeyRingImplementation, - 'initialize', - 'send', - [1, 1, [tester.address], [3]], - false - ) - - await tester.runTest( - `AdharmaKeyRingImplementation cannot be used to take action directly`, - AdharmaKeyRingImplementation, - 'takeAction', - 'send', - [tester.address, 1, '0x', '0x'], - false - ) - - await tester.runTest( - `UpgradeBeaconProxyV1 contract deployment fails with no init data`, - tester.UpgradeBeaconProxyV1Deployer, - '', - 'deploy', - ['0x'], - false - ) - - await tester.runTest( - `KeyRingUpgradeBeaconProxyV1 contract deployment fails with no init data`, - tester.KeyRingUpgradeBeaconProxyV1Deployer, - '', - 'deploy', - ['0x'], - false - ) - - const UpgradeBeaconProxyV1 = await tester.runTest( - `UpgradeBeaconProxyV1 contract deployment (direct)`, - tester.UpgradeBeaconProxyV1Deployer, - '', - 'deploy', - [web3.eth.abi.encodeFunctionCall({ - name: 'initialize', - type: 'function', - inputs: [{ - type: 'address', - name: 'userSigningKey' - }] - }, [tester.address])] - ) - - const UpgradeBeaconProxyV1Implementation = new web3.eth.Contract( - DharmaSmartWalletImplementationV6Artifact.abi, - UpgradeBeaconProxyV1.options.address - ) - - await tester.runTest( - `UpgradeBeaconProxyV1 can retrieve its user signing key`, - UpgradeBeaconProxyV1Implementation, - 'getUserSigningKey', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - const KeyRingUpgradeBeaconProxyV1 = await tester.runTest( - `KeyRingUpgradeBeaconProxyV1 contract deployment (direct)`, - tester.KeyRingUpgradeBeaconProxyV1Deployer, - '', - 'deploy', - [web3.eth.abi.encodeFunctionCall({ - name: 'initialize', - type: 'function', - inputs: [{ - type: 'uint128', - name: 'adminThreshold' - },{ - type: 'uint128', - name: 'executorThreshold' - },{ - type: 'address[]', - name: 'keys' - },{ - type: 'uint8[]', - name: 'keyTypes' - }] - }, [1, 1, [tester.address], [3]])] - ) - - const KeyRingUpgradeBeaconProxyV1Implementation = new web3.eth.Contract( - DharmaKeyRingImplementationV1Artifact.abi, - KeyRingUpgradeBeaconProxyV1.options.address - ) - - await tester.runTest( - `KeyRingUpgradeBeaconProxyV1 can retrieve its user signing key`, - KeyRingUpgradeBeaconProxyV1Implementation, - 'getKeyType', - 'call', - [tester.address], - true, - values => { - assert.ok(values.standard) - assert.ok(values.admin) - } - ) - - // NOTE: these two either need to have the runtime requirement stripped out, - // or to use coverage without instrumentation. Skip coverage for now, as they - // are not yet in use. - // (actually, they're not working yet, period... skip them for now) - /* - if (testingContext !== 'coverage') { - const DharmaSmartWalletFactoryV2 = await tester.runTest( - `DharmaSmartWalletFactoryV2 contract deployment`, - DharmaSmartWalletFactoryV2Deployer, - '', - 'deploy', - [] - ) - - const DharmaKeyRingFactoryV3 = await tester.runTest( - `DharmaKeyRingFactoryV3 contract deployment`, - DharmaKeyRingFactoryV3Deployer, - '', - 'deploy', - [] - ) - } - */ - - await testKeyRegistryV2( - tester, DharmaKeyRegistryV2Coverage, tester.DharmaKeyRegistryV2.options.address - ) - - const DharmaAccountRecoveryManagerV2Coverage = await tester.runTest( - `DharmaAccountRecoveryManagerV2 contract deployment`, - tester.DharmaAccountRecoveryManagerV2Deployer, - '', - 'deploy' - ) - - await testAccountRecoveryManager( - tester, - DharmaAccountRecoveryManagerV2Coverage, - UserSmartWalletV6.options.address - ); - - - await testUpgradeBeaconControllerManagerPartOne( - tester, DharmaUpgradeBeaconControllerManagerCoverage - ) - - const MockDharmaKeyRingFactory = await tester.runTest( - `MockDharmaKeyRingFactory contract deployment`, - tester.MockDharmaKeyRingFactoryDeployer, - '', - 'deploy', - [] - ) - - await tester.runTest( - `MockDharmaKeyRingFactory cannot deploy a DharmaV1 key ring with no keys`, - MockDharmaKeyRingFactory, - 'newKeyRing', - 'send', - [1, 1, [], []], - false - ) - - await tester.runTest( - `MockDharmaKeyRingFactory cannot deploy a DharmaV1 key ring with null address as key`, - MockDharmaKeyRingFactory, - 'newKeyRing', - 'send', - [1, 1, [constants.NULL_ADDRESS], [3]], - false - ) - - await tester.runTest( - `MockDharmaKeyRingFactory cannot deploy a DharmaV1 key ring with non-dual key`, - MockDharmaKeyRingFactory, - 'newKeyRing', - 'send', - [1, 1, [tester.address], [1]], - false - ) - - await tester.runTest( - `MockDharmaKeyRingFactory cannot deploy a DharmaV1 key ring with admin threshold > 1`, - MockDharmaKeyRingFactory, - 'newKeyRing', - 'send', - [2, 1, [tester.address], [3]], - false - ) - - await tester.runTest( - `MockDharmaKeyRingFactory cannot deploy a DharmaV1 key ring with executor threshold > 1`, - MockDharmaKeyRingFactory, - 'newKeyRing', - 'send', - [1, 2, [tester.address], [3]], - false - ) - - await tester.runTest( - 'Dharma Upgrade Beacon Controller can upgrade to AdharmaSmartWalletImplementation', - tester.DharmaUpgradeBeaconController, - 'upgrade', - 'send', - [ - tester.DharmaUpgradeBeacon.options.address, - AdharmaSmartWalletImplementation.options.address - ] - ) - - await tester.runTest( - 'Dharma Key Ring Upgrade Beacon Controller can upgrade to AdharmaKeyRingImplementation', - tester.DharmaKeyRingUpgradeBeaconController, - 'upgrade', - 'send', - [ - tester.DharmaKeyRingUpgradeBeacon.options.address, - AdharmaKeyRingImplementation.options.address - ] - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 cannot deploy an Adharma smart wallet with no key', - DharmaSmartWalletFactoryV1, - 'newSmartWallet', - 'send', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - 'DharmaSmartWalletFactoryV1 can deploy an Adharma smart wallet', - DharmaSmartWalletFactoryV1, - 'newSmartWallet', - 'send', - [tester.address] - ) - - await tester.runTest( - `DharmaKeyRingFactoryV1 cannot create a V1 key ring with no key`, - DharmaKeyRingFactoryV1, - 'newKeyRing', - 'send', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaKeyRingFactoryV1 cannot create an Adharma key ring and set a new null key`, - DharmaKeyRingFactoryV1, - 'newKeyRingAndAdditionalKey', - 'send', - [tester.address, constants.NULL_ADDRESS, '0x'], - false - ) - - await tester.runTest( - `DharmaKeyRingFactoryV1 reverts when no new key ring supplied`, - DharmaKeyRingFactoryV1, - 'getNextKeyRing', - 'call', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaKeyRingFactoryV1 can call newKeyRingAndDaiWithdrawal`, - DharmaKeyRingFactoryV1, - 'newKeyRingAndDaiWithdrawal', - 'send', - [tester.address, tester.address, 0, tester.address, 0, '0x', '0x'], - false - ) - - await tester.runTest( - `DharmaKeyRingFactoryV1 can call newKeyRingAndUSDCWithdrawal`, - DharmaKeyRingFactoryV1, - 'newKeyRingAndUSDCWithdrawal', - 'send', - [tester.address, tester.address, 0, tester.address, 0, '0x', '0x'], - false - ) - - await tester.runTest( - `DharmaKeyRingFactoryV1 can create an Adharma key ring`, - DharmaKeyRingFactoryV1, - 'newKeyRing', - 'send', - [tester.address] - ) - - const UserSmartWalletAdharma = new web3.eth.Contract( - AdharmaSmartWalletImplementationArtifact.abi, - UserSmartWalletV6.options.address - ) - - await tester.runTest( - `Adharma Smart Wallet can be used to perform calls`, - UserSmartWalletAdharma, - 'performCall', - 'send', - [UserSmartWalletAdharma.options.address, 0, '0x'], - true, - receipt => {}, - tester.originalAddress - ) - - await tester.runTest( - `Adharma Smart Wallet can be used to perform failing calls`, - UserSmartWalletAdharma, - 'performCall', - 'send', - [BadBeacon.options.address, 0, '0x'], - false, - receipt => {}, - tester.originalAddress - ) - - const KeyRingAdharma = new web3.eth.Contract( - AdharmaKeyRingImplementationArtifact.abi, - KeyRingInstance.options.address - ) - - await tester.runTest( - `Adharma Key Ring can be used to take an action`, - KeyRingAdharma, - 'takeAction', - 'send', - [tester.address, 0, '0x', '0x'] - ) - - await tester.runTest( - `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with no keys`, - MockDharmaKeyRingFactory, - 'newKeyRing', - 'send', - [0, 0, [], []], - false - ) - - await tester.runTest( - `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with admin threshold of 0`, - MockDharmaKeyRingFactory, - 'newKeyRing', - 'send', - [0, 1, [tester.address], [3]], - false - ) - - await tester.runTest( - `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with executor threshold of 0`, - MockDharmaKeyRingFactory, - 'newKeyRing', - 'send', - [1, 0, [tester.address], [3]], - false - ) - - await tester.runTest( - `MockDharmaKeyRingFactory cannot deploy an Adharma key ring where length of keys and types are not equal`, - MockDharmaKeyRingFactory, - 'newKeyRing', - 'send', - [1, 1, [tester.address, tester.addressTwo], [3]], - false - ) - - await tester.runTest( - `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with duplicate keys`, - MockDharmaKeyRingFactory, - 'newKeyRing', - 'send', - [1, 1, [tester.address, tester.address], [3, 3]], - false - ) - - await tester.runTest( - `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with no admin key`, - MockDharmaKeyRingFactory, - 'newKeyRing', - 'send', - [1, 1, [tester.address], [1]], - false - ) - - await tester.runTest( - `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with less admin keys than threshold`, - MockDharmaKeyRingFactory, - 'newKeyRing', - 'send', - [2, 1, [tester.address], [3]], - false - ) - - await tester.runTest( - `MockDharmaKeyRingFactory can deploy an Adharma key ring with multiple keys`, - MockDharmaKeyRingFactory, - 'newKeyRing', - 'send', - [2, 2, [tester.address, tester.addressTwo], [3, 3]] - ) - - await tester.runTest( - `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with no standard key`, - MockDharmaKeyRingFactory, - 'newKeyRing', - 'send', - [1, 1, [tester.address], [2]], - false - ) - - await tester.runTest( - `TimelockEdgecaseTester contract deployment edge case 1`, - tester.TimelockEdgecaseTesterDeployer, - '', - 'deploy', - [0], - false - ) - - await tester.runTest( - `TimelockEdgecaseTester contract deployment edge case 2`, - tester.TimelockEdgecaseTesterDeployer, - '', - 'deploy', - [1], - false - ) - - await tester.runTest( - `TimelockEdgecaseTester contract deployment edge case 3`, - tester.TimelockEdgecaseTesterDeployer, - '', - 'deploy', - [2], - false - ) - - const DharmaUpgradeMultisig = await tester.runTest( - `DharmaUpgradeMultisig contract deployment`, - tester.DharmaUpgradeMultisigDeployer, - '', - 'deploy', - [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] - ) - - const DharmaAccountRecoveryMultisig = await tester.runTest( - `DharmaAccountRecoveryMultisig contract deployment`, - tester.DharmaAccountRecoveryMultisigDeployer, - '', - 'deploy', - [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour]] - ) - - const DharmaAccountRecoveryOperatorMultisig = await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig contract deployment`, - tester.DharmaAccountRecoveryOperatorMultisigDeployer, - '', - 'deploy', - [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour]] - ) - - const DharmaKeyRegistryMultisig = await tester.runTest( - `DharmaKeyRegistryMultisig contract deployment`, - tester.DharmaKeyRegistryMultisigDeployer, - '', - 'deploy', - [[tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive]] - ) - - rawData = '0x' - executorGasLimit = 100000000000 - - const bizarreSigs = ( - '0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0' + - '7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A11b' + - '7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0' + - '7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A01a' - ) - - await tester.runTest( - `DharmaUpgradeMultisig can get the initial nonce`, - DharmaUpgradeMultisig, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - `DharmaUpgradeMultisig can get the owners`, - DharmaUpgradeMultisig, - 'getOwners', - 'call', - [], - true, - value => { - assert.deepEqual( - value, [tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive] - ) - } - ) - - await tester.runTest( - `DharmaUpgradeMultisig can get an owner`, - DharmaUpgradeMultisig, - 'isOwner', - 'call', - [tester.ownerOne], - true, - value => { - assert.ok(value) - } - ) - - await tester.runTest( - `DharmaUpgradeMultisig returns false for a non-owner`, - DharmaUpgradeMultisig, - 'isOwner', - 'call', - [tester.address], - true, - value => { - assert.ok(!value) - } - ) - - await tester.runTest( - `DharmaUpgradeMultisig can get the threshold`, - DharmaUpgradeMultisig, - 'getThreshold', - 'call', - [], - true, - value => { - assert.strictEqual(value, '3') - } - ) - - await tester.runTest( - `DharmaUpgradeMultisig can get the destination`, - DharmaUpgradeMultisig, - 'getDestination', - 'call', - [], - true, - value => { - assert.strictEqual(value, constants.UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS) - } - ) - - // Generate the messsage hash based on the supplied parameters. - hashInputs = ( - DharmaUpgradeMultisig.options.address + - '0'.padStart(64, '0') + - tester.address.slice(2) + - executorGasLimit.toString(16).padStart(64, '0') + - rawData.slice(2) - ) - - hash = util.bufferToHex(util.keccak256(hashInputs)) - - await tester.runTest( - `DharmaUpgradeMultisig can get a hash`, - DharmaUpgradeMultisig, - 'getNextHash', - 'call', - [rawData, tester.address, executorGasLimit], - true, - value => { - assert.strictEqual(value, hash) - } - ) - - await tester.runTest( - `DharmaUpgradeMultisig can get a hash with a specific nonce`, - DharmaUpgradeMultisig, - 'getHash', - 'call', - [rawData, tester.address, executorGasLimit, 0], - true, - value => { - assert.strictEqual(value, hash) - } - ) - - ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) - ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) - ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) - ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) + ownerThreeSig.slice(2) - unownedSig = tester.signHashedPrefixedHexString(hash, tester.address) - unownedSigs = unownedSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - - await tester.runTest( - `DharmaUpgradeMultisig cannot call execute from non-executor`, - DharmaUpgradeMultisig, - 'execute', - 'send', - [rawData, tester.addressTwo, executorGasLimit, ownerSigs], - false - ) - - await tester.runTest( - `DharmaUpgradeMultisig cannot call execute with oddly-sized signatures`, - DharmaUpgradeMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigs + '1234'], - false - ) - - await tester.runTest( - `DharmaUpgradeMultisig cannot call execute with non-compliant signatures`, - DharmaUpgradeMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, bizarreSigs], - false - ) - - await tester.runTest( - `DharmaUpgradeMultisig cannot call execute without enough signatures`, - DharmaUpgradeMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigs.slice(0, -130)], - false - ) - - await tester.runTest( - `DharmaUpgradeMultisig cannot call execute without owner signatures`, - DharmaUpgradeMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, unownedSigs], - false - ) - - await tester.runTest( - `DharmaUpgradeMultisig cannot call execute with out-of-order signatures`, - DharmaUpgradeMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigsOutOfOrder], - false - ) - - await tester.runTest( - `DharmaUpgradeMultisig can call execute`, - DharmaUpgradeMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigs] - ) - - await tester.runTest( - `DharmaUpgradeMultisig nonce is incremented`, - DharmaUpgradeMultisig, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, '1') - } - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig can get the initial nonce`, - DharmaKeyRegistryMultisig, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig can get the owners`, - DharmaKeyRegistryMultisig, - 'getOwners', - 'call', - [], - true, - value => { - assert.deepEqual( - value, [tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour, tester.ownerFive] - ) - } - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig can get an owner`, - DharmaKeyRegistryMultisig, - 'isOwner', - 'call', - [tester.ownerOne], - true, - value => { - assert.ok(value) - } - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig returns false for a non-owner`, - DharmaKeyRegistryMultisig, - 'isOwner', - 'call', - [tester.address], - true, - value => { - assert.ok(!value) - } - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig can get the threshold`, - DharmaKeyRegistryMultisig, - 'getThreshold', - 'call', - [], - true, - value => { - assert.strictEqual(value, '3') - } - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig can get the destination`, - DharmaKeyRegistryMultisig, - 'getDestination', - 'call', - [], - true, - value => { - assert.strictEqual(value, constants.KEY_REGISTRY_V2_ADDRESS) - } - ) - - // Generate the messsage hash based on the supplied parameters. - hashInputs = ( - DharmaKeyRegistryMultisig.options.address + - '0'.padStart(64, '0') + - tester.address.slice(2) + - executorGasLimit.toString(16).padStart(64, '0') + - rawData.slice(2) - ) - - hash = util.bufferToHex(util.keccak256(hashInputs)) - - await tester.runTest( - `DharmaKeyRegistryMultisig can get a hash`, - DharmaKeyRegistryMultisig, - 'getNextHash', - 'call', - [rawData, tester.address, executorGasLimit], - true, - value => { - assert.strictEqual(value, hash) - } - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig can get a hash with a specific nonce`, - DharmaKeyRegistryMultisig, - 'getHash', - 'call', - [rawData, tester.address, executorGasLimit, 0], - true, - value => { - assert.strictEqual(value, hash) - } - ) - - ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) - ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) - ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) - ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) + ownerThreeSig.slice(2) - unownedSig = tester.signHashedPrefixedHexString(hash, tester.address) - unownedSigs = unownedSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - - await tester.runTest( - `DharmaKeyRegistryMultisig cannot call execute from non-executor`, - DharmaKeyRegistryMultisig, - 'execute', - 'send', - [rawData, tester.addressTwo, executorGasLimit, ownerSigs], - false - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig cannot call execute with oddly-sized signatures`, - DharmaKeyRegistryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigs + '1234'], - false - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig cannot call execute with non-compliant signatures`, - DharmaKeyRegistryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, bizarreSigs], - false - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig cannot call execute without enough signatures`, - DharmaKeyRegistryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigs.slice(0, -130)], - false - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig cannot call execute without owner signatures`, - DharmaKeyRegistryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, unownedSigs], - false - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig cannot call execute with out-of-order signatures`, - DharmaKeyRegistryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigsOutOfOrder], - false - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig can call execute`, - DharmaKeyRegistryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigs] - ) - - await tester.runTest( - `DharmaKeyRegistryMultisig nonce is incremented`, - DharmaKeyRegistryMultisig, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, '1') - } - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig can get the initial nonce`, - DharmaAccountRecoveryMultisig, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, '0') - } - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig can get the owners`, - DharmaAccountRecoveryMultisig, - 'getOwners', - 'call', - [], - true, - value => { - assert.deepEqual( - value, [tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour] - ) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig can get an owner`, - DharmaAccountRecoveryMultisig, - 'isOwner', - 'call', - [tester.ownerOne], - true, - value => { - assert.ok(value) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig returns false for a non-owner`, - DharmaAccountRecoveryMultisig, - 'isOwner', - 'call', - [tester.address], - true, - value => { - assert.ok(!value) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig can get the threshold`, - DharmaAccountRecoveryMultisig, - 'getThreshold', - 'call', - [], - true, - value => { - assert.strictEqual(value, '3') - } - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig can get the destination`, - DharmaAccountRecoveryMultisig, - 'getDestination', - 'call', - [], - true, - value => { - assert.strictEqual(value, constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS) - } - ) - - // Generate the messsage hash based on the supplied parameters. - hashInputs = ( - DharmaAccountRecoveryMultisig.options.address + - '0'.padStart(64, '0') + - tester.address.slice(2) + - executorGasLimit.toString(16).padStart(64, '0') + - rawData.slice(2) - ) - - hash = util.bufferToHex(util.keccak256(hashInputs)) - - await tester.runTest( - `DharmaAccountRecoveryMultisig can get a hash`, - DharmaAccountRecoveryMultisig, - 'getNextHash', - 'call', - [rawData, tester.address, executorGasLimit], - true, - value => { - assert.strictEqual(value, hash) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig can get a hash with a specific nonce`, - DharmaAccountRecoveryMultisig, - 'getHash', - 'call', - [rawData, tester.address, executorGasLimit, 0], - true, - value => { - assert.strictEqual(value, hash) - } - ) + await tester.runTest( + "V7 UserSmartWallet can get a Dai withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 10, // DaiWithdrawal + "1", + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + daiWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + 'V7 UserSmartWallet relay cannot withdraw "dust" dai', + UserSmartWalletV7, + "withdrawDai", + "send", + [ + "1", + tester.address, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get a Dai withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 10, // DaiWithdrawal + "1000000000000000", + constants.NULL_ADDRESS, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + daiWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot withdraw dai to null address", + UserSmartWalletV7, + "withdrawDai", + "send", + [ + "1000000000000000", + constants.NULL_ADDRESS, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get a Dai withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 10, // DaiWithdrawal + "1000000000000000", + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + daiWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay can call with signature to withdraw dai", + UserSmartWalletV7, + "withdrawDai", + "send", + [ + "1000000000000000", + tester.address, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt.events) + }, + tester.originalAddress + ); + + await tester.runTest( + 'V7 UserSmartWallet cannot get a non-custom "custom" next action ID', + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 2, // Generic, + constants.FULL_APPROVAL, + tester.address, + 0 + ], + false + ); + + await tester.runTest( + 'V7 UserSmartWallet cannot get a non-custom "custom" action ID', + UserSmartWalletV7, + "getCustomActionID", + "call", + [ + 2, // Generic, + constants.FULL_APPROVAL, + tester.address, + 0, + 0 + ], + false + ); + + await tester.runTest( + "V7 UserSmartWallet can get a Dai withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 10, // DaiWithdrawal + constants.FULL_APPROVAL, + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + daiWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot call with bad signature to withdraw dai", + UserSmartWalletV7, + "withdrawDai", + "send", + [ + constants.FULL_APPROVAL, + tester.address, + 0, + daiUserWithdrawalSignature, + "0xffffffff" + daiWithdrawalSignature.slice(10) + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot call with bad user signature to withdraw dai", + UserSmartWalletV7, + "withdrawDai", + "send", + [ + constants.FULL_APPROVAL, + tester.address, + 0, + "0xffffffff" + daiUserWithdrawalSignature.slice(10), + daiWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet relay can call with signature to withdraw sai", + UserSmartWalletV7, + "withdrawDai", + "send", + [ + constants.FULL_APPROVAL, + tester.address, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get a Ether withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 6, // ETHWithdrawal, + "0", // no amount + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + ethWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot to withdraw ether with no amount", + UserSmartWalletV7, + "withdrawEther", + "send", + [ + "0", + tester.address, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get a Ether withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 6, // ETHWithdrawal, + "1", + constants.NULL_ADDRESS, // no recipient + 0 + ], + true, + value => { + customActionId = value; + } + ); + + ethWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot to withdraw ether with no recipient", + UserSmartWalletV7, + "withdrawEther", + "send", + [ + "1", + constants.NULL_ADDRESS, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get a Ether withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 6, // ETHWithdrawal, + "1", + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + ethWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot call with bad signature to withdraw eth", + UserSmartWalletV7, + "withdrawEther", + "send", + [ + "1", + tester.address, + 0, + ethUserWithdrawalSignature, + "0xffffffff" + ethWithdrawalSignature.slice(10) + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot call with bad user signature to withdraw eth", + UserSmartWalletV7, + "withdrawEther", + "send", + [ + "1", + tester.address, + 0, + "0xffffffff" + ethUserWithdrawalSignature.slice(10), + ethWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet relay can call with signature to withdraw ether", + UserSmartWalletV7, + "withdrawEther", + "send", + [ + "1", + tester.address, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get a Ether withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 6, // ETHWithdrawal, + "1", + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + ethWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot call with bad signature to withdraw eth", + UserSmartWalletV7, + "withdrawEther", + "send", + [ + "1", + tester.address, + 0, + ethUserWithdrawalSignature, + "0xffffffff" + ethWithdrawalSignature.slice(10) + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot call with bad user signature to withdraw eth", + UserSmartWalletV7, + "withdrawEther", + "send", + [ + "1", + tester.address, + 0, + "0xffffffff" + ethUserWithdrawalSignature.slice(10), + ethWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet relay can call with signature to withdraw ether", + UserSmartWalletV7, + "withdrawEther", + "send", + [ + "1", + tester.address, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet cancel reverts with bad signature", + UserSmartWalletV7, + "cancel", + "send", + [0, "0x"], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet calls revert if insufficient action gas is supplied", + UserSmartWalletV7, + "cancel", + "send", + [constants.FULL_APPROVAL, "0x"], + false + ); + + await tester.runTest( + "V7 UserSmartWallet calls succeed if sufficient non-zero action gas supplied", + UserSmartWalletV7, + "cancel", + "send", + ["1", "0x"] + ); + + await tester.runTest( + "V7 UserSmartWallet can get a cancel custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 0, // Cancel, + "0", + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + cancelSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet can cancel using a signature", + UserSmartWalletV7, + "cancel", + "send", + ["0", cancelSignature], + true, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet calls to atomic methods revert", + UserSmartWalletV7, + "_withdrawDaiAtomic", + "send", + ["1", tester.address], + false + ); + + await tester.runTest( + "V7 UserSmartWallet calls to recover from random address revert", + UserSmartWalletV7, + "recover", + "send", + [tester.address], + false + ); + + await tester.runTest( + "DharmaSmartWalletFactoryV1 can deploy a V7 smart wallet using a Dharma Key", + DharmaSmartWalletFactoryV1, + "newSmartWallet", + "send", + [tester.addressTwo], + true, + receipt => { + //console.log(receipt.status, receipt.gasUsed) + if (testingContext !== "coverage") { + let events = []; + Object.values(receipt.events).forEach(value => { + const log = constants.EVENT_DETAILS[value.raw.topics[0]]; + const decoded = web3.eth.abi.decodeLog( + log.abi, + value.raw.data, + value.raw.topics + ); + events.push({ + address: contractNames[value.address], + eventName: log.name, + returnValues: decoded + }); + }); + + assert.strictEqual(events[0].eventName, "NewUserSigningKey"); + assert.strictEqual( + events[0].returnValues.userSigningKey, + tester.addressTwo + ); + //console.log(events) + + // TODO: test more events + } + } + ); + + await tester.runTest( + "V7 UserSmartWallet can get a generic action ID", + UserSmartWalletV7, + "getNextGenericActionID", + "call", + [ + tester.USDC.options.address, + tester.USDC.methods + .approve(tester.CUSDC.options.address, 0) + .encodeABI(), + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet cannot call executeAction and target a non-contract", + UserSmartWalletV7, + "executeAction", + "send", + [ + tester.address, + tester.USDC.methods + .approve(tester.CUSDC.options.address, 0) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ], + false + ); + + await tester.runTest( + "V7 UserSmartWallet cannot call executeAction and target itself", + UserSmartWalletV7, + "executeAction", + "send", + [ + UserSmartWalletV7.options.address, + tester.USDC.methods + .approve(tester.CUSDC.options.address, 0) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ], + false + ); + + await tester.runTest( + "V7 UserSmartWallet can call executeAction", + UserSmartWalletV7, + "executeAction", + "send", + [ + tester.USDC.options.address, + tester.USDC.methods + .approve(tester.CUSDC.options.address, 0) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ); + + await tester.runTest( + "V7 UserSmartWallet can get the next generic batch action ID", + UserSmartWalletV7, + "getNextGenericAtomicBatchActionID", + "call", + [ + [ + { + to: tester.SAI.options.address, + data: tester.SAI.methods.totalSupply().encodeABI() + } + ], + 0 + ], + true, + value => { + customActionId = value; + } + ); + + await tester.runTest( + "UserSmartWallet can get the nonce", + UserSmartWalletV7, + "getNonce", + "call", + [], + true, + value => { + currentNonce = value; + } + ); + + await tester.runTest( + "V7 UserSmartWallet generic batch action ID with nonce matches next ID", + UserSmartWalletV7, + "getGenericAtomicBatchActionID", + "call", + [ + [ + { + to: tester.SAI.options.address, + data: tester.SAI.methods.totalSupply().encodeABI() + } + ], + currentNonce, + 0 + ], + true, + value => { + assert.strictEqual(value, customActionId); + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet can call executeActionWithAtomicBatchCalls", + UserSmartWalletV7, + "executeActionWithAtomicBatchCalls", + "send", + [ + [ + { + to: tester.SAI.options.address, + data: tester.SAI.methods.totalSupply().encodeABI() + } + ], + 0, + executeActionUserSignature, + executeActionSignature + ] + ); + + await tester.runTest( + "USDC Whale can deposit usdc into the deployed smart wallet", + tester.USDC, + "transfer", + "send", + [targetWalletAddress, web3.utils.toWei("100", "lovelace")], // six decimals + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.USDC_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("100", "lovelace") + ); + } + }, + constants.USDC_WHALE_ADDRESS + ); + + await tester.runTest( + "new user smart wallet can trigger repayAndDeposit to deposit all new funds", + UserSmartWalletV7, + "repayAndDeposit", + "send", + [], + true, + receipt => { + // TODO: validate + } + ); + + await tester.runTest( + "Check blacklister address", + tester.FIAT_TOKEN, + "blacklister", + "call", + [], + true, + value => { + blacklister = value; + } + ); + + await tester.runTest( + "Check pauser address", + tester.FIAT_TOKEN, + "pauser", + "call", + [], + true, + value => { + pauser = value; + } + ); + + await tester.runTest( + "blacklist mock address", + tester.FIAT_TOKEN, + "blacklist", + "send", + [constants.MOCK_USDC_BLACKLISTED_ADDRESS], + true, + receipt => {}, + blacklister + ); + + await tester.runTest( + "DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time", + DharmaSmartWalletFactoryV1, + "getNextSmartWallet", + "call", + [constants.MOCK_USDC_BLACKLISTED_ADDRESS], + true, + value => { + targetBlacklistAddress = value; + } + ); + + const BlacklistedUserSmartWalletV7 = new web3.eth.Contract( + DharmaSmartWalletImplementationV7Artifact.abi, + targetBlacklistAddress + ); + + await tester.runTest( + "USDC Whale can deposit usdc into the yet-to-be-blacklisted smart wallet", + tester.USDC, + "transfer", + "send", + [targetBlacklistAddress, web3.utils.toWei("100", "lovelace")], // six decimals + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.USDC_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetBlacklistAddress + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("100", "lovelace") + ); + } + }, + constants.USDC_WHALE_ADDRESS + ); + + await tester.runTest( + "blacklist counterfactual deployment address", + tester.FIAT_TOKEN, + "blacklist", + "send", + [targetBlacklistAddress], + true, + receipt => {}, + blacklister + ); + + await tester.runTest( + "DharmaSmartWalletFactoryV1 can deploy to a blacklisted address", + DharmaSmartWalletFactoryV1, + "newSmartWallet", + "send", + [constants.MOCK_USDC_BLACKLISTED_ADDRESS], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ); + + await tester.runTest( + "blacklisted smart wallet will not approve USDC during repayAndDeposit", + BlacklistedUserSmartWalletV7, + "repayAndDeposit", + "send", + [], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ); + + await tester.runTest( + "un-blacklist counterfactual deployment address", + tester.FIAT_TOKEN, + "unBlacklist", + "send", + [targetBlacklistAddress], + true, + receipt => {}, + blacklister + ); + + await tester.runTest( + "pause USDC", + tester.FIAT_TOKEN, + "pause", + "send", + [], + true, + receipt => {}, + pauser + ); + + await tester.runTest( + "V7 UserSmartWallet can get a USDC withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + constants.FULL_APPROVAL, + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet attempt to withdraw max USDC when paused causes ExternalError", + UserSmartWalletV7, + "withdrawUSDC", + "send", + [ + constants.FULL_APPROVAL, + tester.address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "smart wallet will not approve USDC when paused during repayAndDeposit", + BlacklistedUserSmartWalletV7, + "repayAndDeposit", + "send", + [], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ); + + await tester.runTest( + "unpause USDC", + tester.FIAT_TOKEN, + "unpause", + "send", + [], + true, + receipt => {}, + pauser + ); + + await tester.runTest( + "unblacklisted, unpaused smart wallet approves USDC during repayAndDeposit", + BlacklistedUserSmartWalletV7, + "repayAndDeposit", + "send", + [], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ); + + await tester.runTest( + "V7 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + web3.utils.toWei("50", "lovelace"), + constants.MOCK_USDC_BLACKLISTED_ADDRESS, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay call to withdraw USDC to blacklisted address", + UserSmartWalletV7, + "withdrawUSDC", + "send", + [ + web3.utils.toWei("50", "lovelace"), + constants.MOCK_USDC_BLACKLISTED_ADDRESS, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt.events[0]) + //console.log(receipt.events.ExternalError) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get a USDC withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + constants.FULL_APPROVAL, + UserSmartWalletV7.options.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay call to withdraw USDC to itself", + UserSmartWalletV7, + "withdrawUSDC", + "send", + [ + constants.FULL_APPROVAL, + UserSmartWalletV7.options.address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get a blacklisted USDC withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + constants.FULL_APPROVAL, + constants.MOCK_USDC_BLACKLISTED_ADDRESS, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay call to withdraw USDC to blacklisted address", + UserSmartWalletV7, + "withdrawUSDC", + "send", + [ + constants.FULL_APPROVAL, + constants.MOCK_USDC_BLACKLISTED_ADDRESS, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt.events[0]) + //console.log(receipt.events.ExternalError) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get a Ether withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 6, // ETHWithdrawal, + "1", + targetWalletAddress, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + ethWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + ethUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot withdraw eth to a non-payable account", + UserSmartWalletV7, + "withdrawEther", + "send", + [ + "1", + targetWalletAddress, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "DharmaSmartWalletFactoryV1 can get a new smart wallet address ahead of time", + DharmaSmartWalletFactoryV1, + "getNextSmartWallet", + "call", + [targetWalletAddress], + true, + value => { + // TODO: verify against expected value + targetWalletAddressTwo = value; + } + ); + + await tester.runTest( + "DharmaSmartWalletFactoryV1 can deploy a V7 smart wallet using a contract key", + DharmaSmartWalletFactoryV1, + "newSmartWallet", + "send", + [targetWalletAddress] + ); + + const UserSmartWalletV7Two = new web3.eth.Contract( + DharmaSmartWalletImplementationV7Artifact.abi, + targetWalletAddressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet cancel reverts with bad contract signature", + UserSmartWalletV7Two, + "cancel", + "send", + [0, "0x"], + false, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get a generic action ID", + UserSmartWalletV7, + "getNextGenericActionID", + "call", + [ + tester.SAI.options.address, + tester.SAI.methods + .transfer(tester.address, constants.FULL_APPROVAL) + .encodeABI(), + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet can call executeAction", + UserSmartWalletV7, + "executeAction", + "send", + [ + tester.SAI.options.address, + tester.SAI.methods + .transfer(tester.address, constants.FULL_APPROVAL) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ); + + await tester.runTest( + "V7 UserSmartWallet can get a Dai withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 10, // DaiWithdrawal + "1000000000000000000", + constants.NULL_ADDRESS, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + daiWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot withdraw to the null address", + UserSmartWalletV7, + "withdrawDai", + "send", + [ + "1000000000000000000", + constants.NULL_ADDRESS, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + false, + receipt => { + // TODO: verify logs + //console.log(receipt.events) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get a Dai withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 10, // DaiWithdrawal + "100000000000000000000000000000000000000", // too much + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + daiWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + daiUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot withdraw too much dai", + UserSmartWalletV7, + "withdrawDai", + "send", + [ + "100000000000000000000000000000000000000", // too much + tester.address, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt.events) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get a USDC withdrawal custom action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 5, // USDCWithdrawal, + "100000000000000000000000000000000000000", // too much + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + usdcWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + usdcUserWithdrawalSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay can call with two signatures to withdraw USDC", + UserSmartWalletV7, + "withdrawUSDC", + "send", + [ + "100000000000000000000000000000000000000", // too much + tester.address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get next generic batch action ID", + UserSmartWalletV7, + "getNextGenericAtomicBatchActionID", + "call", + [ + [ + { + to: tester.DAI.options.address, + data: tester.DAI.methods + .transfer( + tester.address, + "100000000000000000000000000000" + ) + .encodeABI() + } + ], + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet bad executeActionWithAtomicBatchCalls emits CallFailure", + UserSmartWalletV7, + "executeActionWithAtomicBatchCalls", + "send", + [ + [ + { + to: tester.DAI.options.address, + data: tester.DAI.methods + .transfer( + tester.address, + "100000000000000000000000000000" + ) + .encodeABI() + } + ], + 0, + executeActionUserSignature, + executeActionSignature + ], + true, + receipt => { + //console.log(receipt) + } + ); + + await tester.runTest( + "V7 UserSmartWallet can get a generic action ID", + UserSmartWalletV7, + "getNextGenericActionID", + "call", + [ + tester.Comptroller.options.address, + tester.Comptroller.methods + .enterMarkets([constants.CDAI_MAINNET_ADDRESS]) + .encodeABI(), + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet can call executeAction to enter dai market", + UserSmartWalletV7, + "executeAction", + "send", + [ + tester.Comptroller.options.address, + tester.Comptroller.methods + .enterMarkets([constants.CDAI_MAINNET_ADDRESS]) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ); + + await tester.runTest( + "Dai Whale can deposit dai into the smart wallet", + tester.DAI, + "transfer", + "send", + [targetWalletAddress, web3.utils.toWei("100", "ether")], + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.DAI_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + targetWalletAddress + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("100", "ether") + ); + } + }, + constants.DAI_WHALE_ADDRESS + ); + + await tester.runTest( + "V7 UserSmartWallet can trigger repayAndDeposit to deposit all new funds", + UserSmartWalletV7, + "repayAndDeposit" + ); + + await tester.runTest( + "V7 UserSmartWallet can get a generic action ID", + UserSmartWalletV7, + "getNextGenericActionID", + "call", + [ + tester.CSAI_BORROW.options.address, + tester.CSAI_BORROW.methods + .borrow(web3.utils.toWei(".01", "ether")) + .encodeABI(), + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet can call executeAction to perform a borrow", + UserSmartWalletV7, + "executeAction", + "send", + [ + tester.CSAI_BORROW.options.address, + tester.CSAI_BORROW.methods + .borrow(web3.utils.toWei(".01", "ether")) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ], + true, + receipt => { + //console.log(receipt.events) + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get an escape hatch action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 7, // SetEscapeHatch, + 0, + constants.NULL_ADDRESS, // no recipient + 0 + ], + true, + value => { + customActionId = value; + } + ); + + escapeHatchSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + escapeHatchUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot set an escape hatch with no account", + UserSmartWalletV7, + "setEscapeHatch", + "send", + [ + constants.NULL_ADDRESS, + 0, + escapeHatchUserSignature, + escapeHatchSignature + ], + false, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get an escape hatch action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 7, // SetEscapeHatch, + 0, + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + escapeHatchSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + escapeHatchUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet cannot call escape before escape hatch is set", + UserSmartWalletV7, + "escape", + "send", + [], + false, + receipt => { + // TODO: verify logs + } + ); + + await tester.runTest( + "V7 UserSmartWallet relay can set an escape hatch", + UserSmartWalletV7, + "setEscapeHatch", + "send", + [tester.address, 0, escapeHatchUserSignature, escapeHatchSignature], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet non-escape hatch account cannot call escape", + UserSmartWalletV7, + "escape", + "send", + [], + false, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet escape hatch account can call escape", + UserSmartWalletV7, + "escape", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.address + ); + + await tester.runTest( + "V7 UserSmartWallet escape hatch account can call escape again", + UserSmartWalletV7, + "escape", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.address + ); + + await tester.runTest( + "V7 UserSmartWallet can get an escape hatch action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 8, // RemoveEscapeHatch, + 0, + constants.NULL_ADDRESS, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + escapeHatchSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + escapeHatchUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay can remove an escape hatch", + UserSmartWalletV7, + "removeEscapeHatch", + "send", + [0, escapeHatchUserSignature, escapeHatchSignature], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet cannot call escape once escape hatch is removed", + UserSmartWalletV7, + "escape", + "send", + [], + false, + receipt => { + // TODO: verify logs + } + ); + + await tester.runTest( + "V7 UserSmartWallet can get an escape hatch action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 9, // DisableEscapeHatch, + 0, + constants.NULL_ADDRESS, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + escapeHatchSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + escapeHatchUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay can disable the escape hatch", + UserSmartWalletV7, + "permanentlyDisableEscapeHatch", + "send", + [0, escapeHatchUserSignature, escapeHatchSignature], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet can get an escape hatch action ID", + UserSmartWalletV7, + "getNextCustomActionID", + "call", + [ + 7, // SetEscapeHatch, + 0, + tester.address, + 0 + ], + true, + value => { + customActionId = value; + } + ); + + escapeHatchSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + escapeHatchUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet relay cannot set an escape hatch once disabled", + UserSmartWalletV7, + "setEscapeHatch", + "send", + [tester.address, 0, escapeHatchUserSignature, escapeHatchSignature], + false, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet relay can trigger sai to dai migration as a no-op", + UserSmartWalletV7, + "migrateSaiToDai", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet relay can trigger cSai to dDai migration as a no-op", + UserSmartWalletV7, + "migrateCSaiToDDai", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "cSai can be sent to V7 UserSmartWallet", + tester.CSAI, + "transfer", + "send", + [UserSmartWalletV7.options.address, web3.utils.toWei("0.5", "mwei")] + ); + + await tester.runTest( + "Sai Whale can deposit sai into the V7 user smart wallet", + tester.SAI, + "transfer", + "send", + [UserSmartWalletV7.options.address, web3.utils.toWei("1", "ether")], + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.SAI_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + UserSmartWalletV7.options.address + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("1", "ether") + ); + } + }, + constants.SAI_WHALE_ADDRESS + ); + + await tester.runTest( + "V7 UserSmartWallet relay can trigger sai to dai migration", + UserSmartWalletV7, + "migrateSaiToDai", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet relay can trigger cSai to dDai migration", + UserSmartWalletV7, + "migrateCSaiToDDai", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + // Initiate account recovery + await tester.runTest( + "smart wallet account recovery can be initiated", + tester.DharmaAccountRecoveryManagerV2, + "initiateAccountRecovery", + "send", + [ + UserSmartWalletV7.options.address, + tester.originalAddress, + 0 // extraTime in seconds + ], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ); + + await tester.runTest( + "smart wallet account recovery cannot be performed right away", + tester.DharmaAccountRecoveryManagerV2, + "recover", + "send", + [UserSmartWalletV7.options.address, tester.originalAddress], + false + ); + + // advance time by 3 days + await tester.advanceTime(60 * 60 * 24 * 3 + 5); + + // recover account + await tester.runTest( + "smart wallet account recovery can be performed after three days", + tester.DharmaAccountRecoveryManagerV2, + "recover", + "send", + [UserSmartWalletV7.options.address, tester.originalAddress], + true, + receipt => { + // TODO: verify + //console.log(receipt.events) + } + ); + + // ZZZZZ + + // COVERAGE TESTING - deployments + const DharmaUpgradeBeaconControllerManagerCoverage = await tester.runTest( + `DharmaUpgradeBeaconControllerManager contract deployment`, + tester.DharmaUpgradeBeaconControllerManagerDeployer, + "", + "deploy" + ); + + const DharmaUpgradeBeaconControllerCoverage = await tester.runTest( + `DharmaUpgradeBeaconController contract deployment`, + tester.DharmaUpgradeBeaconControllerDeployer, + "", + "deploy" + ); + + const DharmaUpgradeBeaconCoverage = await tester.runTest( + `DharmaUpgradeBeacon (smart wallet) contract deployment`, + tester.DharmaUpgradeBeaconDeployer, + "", + "deploy" + ); + + const DharmaKeyRingUpgradeBeaconCoverage = await tester.runTest( + `DharmaKeyRingUpgradeBeacon contract deployment`, + tester.DharmaKeyRingUpgradeBeaconDeployer, + "", + "deploy" + ); + + const DharmaUpgradeBeaconEnvoy = await tester.runTest( + `DharmaUpgradeBeaconEnvoy contract deployment`, + tester.DharmaUpgradeBeaconEnvoyDeployer, + "", + "deploy" + ); + + await testUpgradeBeaconController( + tester, + DharmaUpgradeBeaconControllerCoverage, // controller manager + tester.DharmaUpgradeBeaconController, // smart wallet controller contract + tester.DharmaKeyRingUpgradeBeaconController, // key ring controller contract + DharmaUpgradeBeaconEnvoy, // envoy contract + DharmaUpgradeBeaconCoverage.options.address, // owned smart wallet beacon + DharmaKeyRingUpgradeBeaconCoverage.options.address, // owned key ring beacon + BadBeaconTwo.options.address // "bad" beacon + ); + + const DharmaKeyRegistryV2Coverage = await tester.runTest( + `DharmaKeyRegistryV2 contract deployment`, + tester.DharmaKeyRegistryV2Deployer, + "", + "deploy" + ); + + const AdharmaSmartWalletImplementation = await tester.runTest( + `AdharmaSmartWalletImplementation contract deployment`, + tester.AdharmaSmartWalletImplementationDeployer, + "", + "deploy" + ); + + const AdharmaKeyRingImplementation = await tester.runTest( + `AdharmaKeyRingImplementation contract deployment`, + tester.AdharmaKeyRingImplementationDeployer, + "", + "deploy" + ); + + const DharmaSmartWalletFactoryV1Coverage = await tester.runTest( + `DharmaSmartWalletFactoryV1 contract deployment`, + tester.DharmaSmartWalletFactoryV1Deployer, + "", + "deploy", + [] + ); + + const DharmaKeyRingFactoryV1 = await tester.runTest( + `DharmaKeyRingFactoryV1 contract deployment`, + tester.DharmaKeyRingFactoryV1Deployer, + "", + "deploy", + [] + ); + + const DharmaKeyRingFactoryV2 = await tester.runTest( + `DharmaKeyRingFactoryV2 contract deployment`, + tester.DharmaKeyRingFactoryV2Deployer, + "", + "deploy", + [] + ); + + await tester.runTest( + `DharmaKeyRingFactoryV1 cannot create a V1 key ring with no key`, + DharmaKeyRingFactoryV1, + "newKeyRing", + "send", + [constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + `DharmaKeyRingFactoryV1 cannot create a V1 key ring and set a new null key`, + DharmaKeyRingFactoryV1, + "newKeyRingAndAdditionalKey", + "send", + [tester.address, constants.NULL_ADDRESS, "0x"], + false + ); + + await tester.runTest( + `DharmaKeyRingFactoryV1 cannot create a V1 key ring and set a duplicate key`, + DharmaKeyRingFactoryV1, + "newKeyRingAndAdditionalKey", + "send", + [tester.address, tester.address, "0x"], + false + ); + + await tester.runTest( + `DharmaKeyRingFactoryV1 can get the address of the next key ring`, + DharmaKeyRingFactoryV1, + "getNextKeyRing", + "call", + [tester.address], + true, + value => { + nextKeyRing = value; + } + ); + + await tester.runTest( + `DharmaKeyRingFactoryV1 can create a V1 key ring`, + DharmaKeyRingFactoryV1, + "newKeyRing", + "send", + [tester.address] + ); + + const KeyRingInstance = new web3.eth.Contract( + DharmaKeyRingImplementationV1Artifact.abi, + nextKeyRing + ); + + await tester.runTest( + `DharmaKeyRingFactoryV1 gets new key ring after a deploy with same input`, + DharmaKeyRingFactoryV1, + "getNextKeyRing", + "call", + [tester.address], + true, + value => { + assert.ok(nextKeyRing !== value); + } + ); + + await tester.runTest( + `KeyRingInstance can get the version of the key ring`, + KeyRingInstance, + "getVersion", + "call", + [], + true, + value => { + assert.strictEqual(value, "1"); + } + ); + + await tester.runTest( + `KeyRingInstance can get the nonce of the key ring`, + KeyRingInstance, + "getNonce", + "call", + [], + true, + value => { + assert.strictEqual(value, "0"); + } + ); + + await tester.runTest( + `KeyRingInstance can get the key count of the key ring`, + KeyRingInstance, + "getKeyCount", + "call", + [], + true, + value => { + assert.strictEqual(value.adminKeyCount, "1"); + assert.strictEqual(value.standardKeyCount, "1"); + } + ); + + await tester.runTest( + `KeyRingInstance can does not verify a bad signature`, + KeyRingInstance, + "isValidSignature", + "call", + [ + web3.eth.abi.encodeParameters( + ["bytes32", "uint8", "bytes"], + [constants.NULL_BYTES_32, 1, "0x"] + ), + "0x" + ], + false + ); + + await tester.runTest( + `KeyRingInstance can get an adminActionID using getNextAdminActionID`, + KeyRingInstance, + "getNextAdminActionID", + "call", + [1, 1], + true, + value => { + adminActionID = value; + } + ); + + await tester.runTest( + `KeyRingInstance getAdminActionID matches getNextAdminActionID`, + KeyRingInstance, + "getAdminActionID", + "call", + [1, 1, 0], + true, + value => { + assert.strictEqual(value, adminActionID); + } + ); + + await tester.runTest( + `KeyRingInstance cannot add a non-dual key in V1`, + KeyRingInstance, + "takeAdminAction", + "send", + [1, 1, "0x"], + false + ); + + await tester.runTest( + `KeyRingInstance cannot add key that already exists`, + KeyRingInstance, + "takeAdminAction", + "send", + [6, tester.address, "0x"], + false + ); + + const takeAdminActionSignature = tester.signHashedPrefixedHexString( + adminActionID, + tester.address + ); + + await tester.runTest( + `KeyRingInstance can verify a valid signature`, + KeyRingInstance, + "isValidSignature", + "call", + [ + web3.eth.abi.encodeParameters( + ["bytes32", "uint8", "bytes"], + [ + web3.utils.keccak256( + // prefix => "\x19Ethereum Signed Message:\n32" + "0x19457468657265756d205369676e6564204d6573736167653a0a3332" + + adminActionID.slice(2), + { encoding: "hex" } + ), + 1, + "0x" + ] + ), + takeAdminActionSignature + ], + true, + value => { + assert.strictEqual(value, "0x20c13b0b"); + } + ); + + await tester.runTest( + `KeyRingInstance can add a new key with a valid signature`, + KeyRingInstance, + "takeAdminAction", + "send", + [6, 1, takeAdminActionSignature], + true + ); + + await tester.runTest( + `DharmaKeyRingFactoryV2 cannot create a V1 key ring with no key`, + DharmaKeyRingFactoryV2, + "newKeyRing", + "send", + [constants.NULL_ADDRESS, constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + `DharmaKeyRingFactoryV2 cannot create a V1 key ring and set a new null key`, + DharmaKeyRingFactoryV2, + "newKeyRingAndAdditionalKey", + "send", + [tester.address, constants.NULL_ADDRESS, constants.NULL_ADDRESS, "0x"], + false + ); + + await tester.runTest( + `DharmaKeyRingFactoryV2 cannot create a V1 key ring and set a duplicate key`, + DharmaKeyRingFactoryV2, + "newKeyRingAndAdditionalKey", + "send", + [tester.address, constants.NULL_ADDRESS, tester.address, "0x"], + false + ); + + await tester.runTest( + `DharmaKeyRingFactoryV2 can get the address of the next key ring`, + DharmaKeyRingFactoryV2, + "getNextKeyRing", + "call", + [tester.address], + true, + value => { + nextKeyRing = value; + } + ); + + await tester.runTest( + `DharmaKeyRingFactoryV2 can create a V1 key ring if the target address matches`, + DharmaKeyRingFactoryV2, + "newKeyRing", + "send", + [tester.address, nextKeyRing] + ); + + const KeyRingInstanceFromV2Factory = new web3.eth.Contract( + DharmaKeyRingImplementationV1Artifact.abi, + nextKeyRing + ); + + await tester.runTest( + `DharmaKeyRingFactoryV2 won't deploy a V1 key ring if the target address has one`, + DharmaKeyRingFactoryV2, + "newKeyRing", + "send", + [tester.address, KeyRingInstanceFromV2Factory.options.address] + ); + + await tester.runTest( + `DharmaKeyRingFactoryV2 can call getFirstKeyRingAdminActionID`, + DharmaKeyRingFactoryV2, + "getFirstKeyRingAdminActionID", + "call", + [tester.address, tester.address] + ); + + await tester.runTest( + `DharmaKeyRingFactoryV2 reverts when no new key ring supplied`, + DharmaKeyRingFactoryV2, + "getNextKeyRing", + "call", + [constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + `DharmaKeyRingFactoryV2 gets new key ring after a deploy with same input`, + DharmaKeyRingFactoryV2, + "getNextKeyRing", + "call", + [tester.address], + true, + value => { + assert.ok(nextKeyRing !== value); + } + ); + + await tester.runTest( + `DharmaKeyRingFactoryV2 can call newKeyRingAndDaiWithdrawal`, + DharmaKeyRingFactoryV2, + "newKeyRingAndDaiWithdrawal", + "send", + [ + tester.address, + tester.address, + tester.address, + 0, + tester.address, + 0, + "0x", + "0x" + ], + false + ); + + await tester.runTest( + `DharmaKeyRingFactoryV2 can call newKeyRingAndUSDCWithdrawal`, + DharmaKeyRingFactoryV2, + "newKeyRingAndUSDCWithdrawal", + "send", + [ + tester.address, + tester.address, + tester.address, + 0, + tester.address, + 0, + "0x", + "0x" + ], + false + ); + + await tester.runTest( + `AdharmaSmartWalletImplementation cannot be initialized directly post-deployment`, + AdharmaSmartWalletImplementation, + "initialize", + "send", + [tester.address], + false + ); + + await tester.runTest( + `AdharmaSmartWalletImplementation cannot be used to perform calls directly`, + AdharmaSmartWalletImplementation, + "performCall", + "send", + [tester.address, 1, "0x"], + false + ); + + await tester.runTest( + `AdharmaKeyRingImplementation cannot be initialized directly post-deployment`, + AdharmaKeyRingImplementation, + "initialize", + "send", + [1, 1, [tester.address], [3]], + false + ); + + await tester.runTest( + `AdharmaKeyRingImplementation cannot be used to take action directly`, + AdharmaKeyRingImplementation, + "takeAction", + "send", + [tester.address, 1, "0x", "0x"], + false + ); + + await tester.runTest( + `UpgradeBeaconProxyV1 contract deployment fails with no init data`, + tester.UpgradeBeaconProxyV1Deployer, + "", + "deploy", + ["0x"], + false + ); + + await tester.runTest( + `KeyRingUpgradeBeaconProxyV1 contract deployment fails with no init data`, + tester.KeyRingUpgradeBeaconProxyV1Deployer, + "", + "deploy", + ["0x"], + false + ); + + const UpgradeBeaconProxyV1 = await tester.runTest( + `UpgradeBeaconProxyV1 contract deployment (direct)`, + tester.UpgradeBeaconProxyV1Deployer, + "", + "deploy", + [ + web3.eth.abi.encodeFunctionCall( + { + name: "initialize", + type: "function", + inputs: [ + { + type: "address", + name: "userSigningKey" + } + ] + }, + [tester.address] + ) + ] + ); + + const UpgradeBeaconProxyV1Implementation = new web3.eth.Contract( + DharmaSmartWalletImplementationV6Artifact.abi, + UpgradeBeaconProxyV1.options.address + ); + + await tester.runTest( + `UpgradeBeaconProxyV1 can retrieve its user signing key`, + UpgradeBeaconProxyV1Implementation, + "getUserSigningKey", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.address); + } + ); + + const KeyRingUpgradeBeaconProxyV1 = await tester.runTest( + `KeyRingUpgradeBeaconProxyV1 contract deployment (direct)`, + tester.KeyRingUpgradeBeaconProxyV1Deployer, + "", + "deploy", + [ + web3.eth.abi.encodeFunctionCall( + { + name: "initialize", + type: "function", + inputs: [ + { + type: "uint128", + name: "adminThreshold" + }, + { + type: "uint128", + name: "executorThreshold" + }, + { + type: "address[]", + name: "keys" + }, + { + type: "uint8[]", + name: "keyTypes" + } + ] + }, + [1, 1, [tester.address], [3]] + ) + ] + ); + + const KeyRingUpgradeBeaconProxyV1Implementation = new web3.eth.Contract( + DharmaKeyRingImplementationV1Artifact.abi, + KeyRingUpgradeBeaconProxyV1.options.address + ); + + await tester.runTest( + `KeyRingUpgradeBeaconProxyV1 can retrieve its user signing key`, + KeyRingUpgradeBeaconProxyV1Implementation, + "getKeyType", + "call", + [tester.address], + true, + values => { + assert.ok(values.standard); + assert.ok(values.admin); + } + ); + + // NOTE: these two either need to have the runtime requirement stripped out, + // or to use coverage without instrumentation. Skip coverage for now, as they + // are not yet in use. + // (actually, they're not working yet, period... skip them for now) + /* + if (testingContext !== 'coverage') { + const DharmaSmartWalletFactoryV2 = await tester.runTest( + `DharmaSmartWalletFactoryV2 contract deployment`, + DharmaSmartWalletFactoryV2Deployer, + '', + 'deploy', + [] + ) - ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) - ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) - ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) + const DharmaKeyRingFactoryV3 = await tester.runTest( + `DharmaKeyRingFactoryV3 contract deployment`, + DharmaKeyRingFactoryV3Deployer, + '', + 'deploy', + [] + ) + } + */ - /* + await testKeyRegistryV2( + tester, + DharmaKeyRegistryV2Coverage, + tester.DharmaKeyRegistryV2.options.address + ); + + const DharmaAccountRecoveryManagerV2Coverage = await tester.runTest( + `DharmaAccountRecoveryManagerV2 contract deployment`, + tester.DharmaAccountRecoveryManagerV2Deployer, + "", + "deploy" + ); + + await testAccountRecoveryManager( + tester, + DharmaAccountRecoveryManagerV2Coverage, + UserSmartWalletV6.options.address + ); + + await testUpgradeBeaconControllerManagerPartOne( + tester, + DharmaUpgradeBeaconControllerManagerCoverage + ); + + const MockDharmaKeyRingFactory = await tester.runTest( + `MockDharmaKeyRingFactory contract deployment`, + tester.MockDharmaKeyRingFactoryDeployer, + "", + "deploy", + [] + ); + + await tester.runTest( + `MockDharmaKeyRingFactory cannot deploy a DharmaV1 key ring with no keys`, + MockDharmaKeyRingFactory, + "newKeyRing", + "send", + [1, 1, [], []], + false + ); + + await tester.runTest( + `MockDharmaKeyRingFactory cannot deploy a DharmaV1 key ring with null address as key`, + MockDharmaKeyRingFactory, + "newKeyRing", + "send", + [1, 1, [constants.NULL_ADDRESS], [3]], + false + ); + + await tester.runTest( + `MockDharmaKeyRingFactory cannot deploy a DharmaV1 key ring with non-dual key`, + MockDharmaKeyRingFactory, + "newKeyRing", + "send", + [1, 1, [tester.address], [1]], + false + ); + + await tester.runTest( + `MockDharmaKeyRingFactory cannot deploy a DharmaV1 key ring with admin threshold > 1`, + MockDharmaKeyRingFactory, + "newKeyRing", + "send", + [2, 1, [tester.address], [3]], + false + ); + + await tester.runTest( + `MockDharmaKeyRingFactory cannot deploy a DharmaV1 key ring with executor threshold > 1`, + MockDharmaKeyRingFactory, + "newKeyRing", + "send", + [1, 2, [tester.address], [3]], + false + ); + + await tester.runTest( + "Dharma Upgrade Beacon Controller can upgrade to AdharmaSmartWalletImplementation", + tester.DharmaUpgradeBeaconController, + "upgrade", + "send", + [ + tester.DharmaUpgradeBeacon.options.address, + AdharmaSmartWalletImplementation.options.address + ] + ); + + await tester.runTest( + "Dharma Key Ring Upgrade Beacon Controller can upgrade to AdharmaKeyRingImplementation", + tester.DharmaKeyRingUpgradeBeaconController, + "upgrade", + "send", + [ + tester.DharmaKeyRingUpgradeBeacon.options.address, + AdharmaKeyRingImplementation.options.address + ] + ); + + await tester.runTest( + "DharmaSmartWalletFactoryV1 cannot deploy an Adharma smart wallet with no key", + DharmaSmartWalletFactoryV1, + "newSmartWallet", + "send", + [constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + "DharmaSmartWalletFactoryV1 can deploy an Adharma smart wallet", + DharmaSmartWalletFactoryV1, + "newSmartWallet", + "send", + [tester.address] + ); + + await tester.runTest( + `DharmaKeyRingFactoryV1 cannot create a V1 key ring with no key`, + DharmaKeyRingFactoryV1, + "newKeyRing", + "send", + [constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + `DharmaKeyRingFactoryV1 cannot create an Adharma key ring and set a new null key`, + DharmaKeyRingFactoryV1, + "newKeyRingAndAdditionalKey", + "send", + [tester.address, constants.NULL_ADDRESS, "0x"], + false + ); + + await tester.runTest( + `DharmaKeyRingFactoryV1 reverts when no new key ring supplied`, + DharmaKeyRingFactoryV1, + "getNextKeyRing", + "call", + [constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + `DharmaKeyRingFactoryV1 can call newKeyRingAndDaiWithdrawal`, + DharmaKeyRingFactoryV1, + "newKeyRingAndDaiWithdrawal", + "send", + [tester.address, tester.address, 0, tester.address, 0, "0x", "0x"], + false + ); + + await tester.runTest( + `DharmaKeyRingFactoryV1 can call newKeyRingAndUSDCWithdrawal`, + DharmaKeyRingFactoryV1, + "newKeyRingAndUSDCWithdrawal", + "send", + [tester.address, tester.address, 0, tester.address, 0, "0x", "0x"], + false + ); + + await tester.runTest( + `DharmaKeyRingFactoryV1 can create an Adharma key ring`, + DharmaKeyRingFactoryV1, + "newKeyRing", + "send", + [tester.address] + ); + + const UserSmartWalletAdharma = new web3.eth.Contract( + AdharmaSmartWalletImplementationArtifact.abi, + UserSmartWalletV6.options.address + ); + + await tester.runTest( + `Adharma Smart Wallet can be used to perform calls`, + UserSmartWalletAdharma, + "performCall", + "send", + [UserSmartWalletAdharma.options.address, 0, "0x"], + true, + receipt => {}, + tester.originalAddress + ); + + await tester.runTest( + `Adharma Smart Wallet can be used to perform failing calls`, + UserSmartWalletAdharma, + "performCall", + "send", + [BadBeacon.options.address, 0, "0x"], + false, + receipt => {}, + tester.originalAddress + ); + + const KeyRingAdharma = new web3.eth.Contract( + AdharmaKeyRingImplementationArtifact.abi, + KeyRingInstance.options.address + ); + + await tester.runTest( + `Adharma Key Ring can be used to take an action`, + KeyRingAdharma, + "takeAction", + "send", + [tester.address, 0, "0x", "0x"] + ); + + await tester.runTest( + `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with no keys`, + MockDharmaKeyRingFactory, + "newKeyRing", + "send", + [0, 0, [], []], + false + ); + + await tester.runTest( + `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with admin threshold of 0`, + MockDharmaKeyRingFactory, + "newKeyRing", + "send", + [0, 1, [tester.address], [3]], + false + ); + + await tester.runTest( + `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with executor threshold of 0`, + MockDharmaKeyRingFactory, + "newKeyRing", + "send", + [1, 0, [tester.address], [3]], + false + ); + + await tester.runTest( + `MockDharmaKeyRingFactory cannot deploy an Adharma key ring where length of keys and types are not equal`, + MockDharmaKeyRingFactory, + "newKeyRing", + "send", + [1, 1, [tester.address, tester.addressTwo], [3]], + false + ); + + await tester.runTest( + `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with duplicate keys`, + MockDharmaKeyRingFactory, + "newKeyRing", + "send", + [1, 1, [tester.address, tester.address], [3, 3]], + false + ); + + await tester.runTest( + `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with no admin key`, + MockDharmaKeyRingFactory, + "newKeyRing", + "send", + [1, 1, [tester.address], [1]], + false + ); + + await tester.runTest( + `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with less admin keys than threshold`, + MockDharmaKeyRingFactory, + "newKeyRing", + "send", + [2, 1, [tester.address], [3]], + false + ); + + await tester.runTest( + `MockDharmaKeyRingFactory can deploy an Adharma key ring with multiple keys`, + MockDharmaKeyRingFactory, + "newKeyRing", + "send", + [2, 2, [tester.address, tester.addressTwo], [3, 3]] + ); + + await tester.runTest( + `MockDharmaKeyRingFactory cannot deploy an Adharma key ring with no standard key`, + MockDharmaKeyRingFactory, + "newKeyRing", + "send", + [1, 1, [tester.address], [2]], + false + ); + + await tester.runTest( + `TimelockEdgecaseTester contract deployment edge case 1`, + tester.TimelockEdgecaseTesterDeployer, + "", + "deploy", + [0], + false + ); + + await tester.runTest( + `TimelockEdgecaseTester contract deployment edge case 2`, + tester.TimelockEdgecaseTesterDeployer, + "", + "deploy", + [1], + false + ); + + await tester.runTest( + `TimelockEdgecaseTester contract deployment edge case 3`, + tester.TimelockEdgecaseTesterDeployer, + "", + "deploy", + [2], + false + ); + + const DharmaUpgradeMultisig = await tester.runTest( + `DharmaUpgradeMultisig contract deployment`, + tester.DharmaUpgradeMultisigDeployer, + "", + "deploy", + [ + [ + tester.ownerOne, + tester.ownerTwo, + tester.ownerThree, + tester.ownerFour, + tester.ownerFive + ] + ] + ); + + const DharmaAccountRecoveryMultisig = await tester.runTest( + `DharmaAccountRecoveryMultisig contract deployment`, + tester.DharmaAccountRecoveryMultisigDeployer, + "", + "deploy", + [ + [ + tester.ownerOne, + tester.ownerTwo, + tester.ownerThree, + tester.ownerFour + ] + ] + ); + + const DharmaAccountRecoveryOperatorMultisig = await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig contract deployment`, + tester.DharmaAccountRecoveryOperatorMultisigDeployer, + "", + "deploy", + [ + [ + tester.ownerOne, + tester.ownerTwo, + tester.ownerThree, + tester.ownerFour + ] + ] + ); + + const DharmaKeyRegistryMultisig = await tester.runTest( + `DharmaKeyRegistryMultisig contract deployment`, + tester.DharmaKeyRegistryMultisigDeployer, + "", + "deploy", + [ + [ + tester.ownerOne, + tester.ownerTwo, + tester.ownerThree, + tester.ownerFour, + tester.ownerFive + ] + ] + ); + + rawData = "0x"; + executorGasLimit = 100000000000; + + const bizarreSigs = + "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0" + + "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A11b" + + "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0" + + "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A01a"; + + await tester.runTest( + `DharmaUpgradeMultisig can get the initial nonce`, + DharmaUpgradeMultisig, + "getNonce", + "call", + [], + true, + value => { + assert.strictEqual(value, "0"); + } + ); + + await tester.runTest( + `DharmaUpgradeMultisig can get the owners`, + DharmaUpgradeMultisig, + "getOwners", + "call", + [], + true, + value => { + assert.deepEqual(value, [ + tester.ownerOne, + tester.ownerTwo, + tester.ownerThree, + tester.ownerFour, + tester.ownerFive + ]); + } + ); + + await tester.runTest( + `DharmaUpgradeMultisig can get an owner`, + DharmaUpgradeMultisig, + "isOwner", + "call", + [tester.ownerOne], + true, + value => { + assert.ok(value); + } + ); + + await tester.runTest( + `DharmaUpgradeMultisig returns false for a non-owner`, + DharmaUpgradeMultisig, + "isOwner", + "call", + [tester.address], + true, + value => { + assert.ok(!value); + } + ); + + await tester.runTest( + `DharmaUpgradeMultisig can get the threshold`, + DharmaUpgradeMultisig, + "getThreshold", + "call", + [], + true, + value => { + assert.strictEqual(value, "3"); + } + ); + + await tester.runTest( + `DharmaUpgradeMultisig can get the destination`, + DharmaUpgradeMultisig, + "getDestination", + "call", + [], + true, + value => { + assert.strictEqual( + value, + constants.UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS + ); + } + ); + + // Generate the messsage hash based on the supplied parameters. + hashInputs = + DharmaUpgradeMultisig.options.address + + "0".padStart(64, "0") + + tester.address.slice(2) + + executorGasLimit.toString(16).padStart(64, "0") + + rawData.slice(2); + + hash = util.bufferToHex(util.keccak256(hashInputs)); + + await tester.runTest( + `DharmaUpgradeMultisig can get a hash`, + DharmaUpgradeMultisig, + "getNextHash", + "call", + [rawData, tester.address, executorGasLimit], + true, + value => { + assert.strictEqual(value, hash); + } + ); + + await tester.runTest( + `DharmaUpgradeMultisig can get a hash with a specific nonce`, + DharmaUpgradeMultisig, + "getHash", + "call", + [rawData, tester.address, executorGasLimit, 0], + true, + value => { + assert.strictEqual(value, hash); + } + ); + + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne); + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo); + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree); + ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2); + ownerSigsOutOfOrder = + ownerTwoSig + ownerOneSig.slice(2) + ownerThreeSig.slice(2); + unownedSig = tester.signHashedPrefixedHexString(hash, tester.address); + unownedSigs = unownedSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2); + + await tester.runTest( + `DharmaUpgradeMultisig cannot call execute from non-executor`, + DharmaUpgradeMultisig, + "execute", + "send", + [rawData, tester.addressTwo, executorGasLimit, ownerSigs], + false + ); + + await tester.runTest( + `DharmaUpgradeMultisig cannot call execute with oddly-sized signatures`, + DharmaUpgradeMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigs + "1234"], + false + ); + + await tester.runTest( + `DharmaUpgradeMultisig cannot call execute with non-compliant signatures`, + DharmaUpgradeMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, bizarreSigs], + false + ); + + await tester.runTest( + `DharmaUpgradeMultisig cannot call execute without enough signatures`, + DharmaUpgradeMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigs.slice(0, -130)], + false + ); + + await tester.runTest( + `DharmaUpgradeMultisig cannot call execute without owner signatures`, + DharmaUpgradeMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, unownedSigs], + false + ); + + await tester.runTest( + `DharmaUpgradeMultisig cannot call execute with out-of-order signatures`, + DharmaUpgradeMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigsOutOfOrder], + false + ); + + await tester.runTest( + `DharmaUpgradeMultisig can call execute`, + DharmaUpgradeMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigs] + ); + + await tester.runTest( + `DharmaUpgradeMultisig nonce is incremented`, + DharmaUpgradeMultisig, + "getNonce", + "call", + [], + true, + value => { + assert.strictEqual(value, "1"); + } + ); + + await tester.runTest( + `DharmaKeyRegistryMultisig can get the initial nonce`, + DharmaKeyRegistryMultisig, + "getNonce", + "call", + [], + true, + value => { + assert.strictEqual(value, "0"); + } + ); + + await tester.runTest( + `DharmaKeyRegistryMultisig can get the owners`, + DharmaKeyRegistryMultisig, + "getOwners", + "call", + [], + true, + value => { + assert.deepEqual(value, [ + tester.ownerOne, + tester.ownerTwo, + tester.ownerThree, + tester.ownerFour, + tester.ownerFive + ]); + } + ); + + await tester.runTest( + `DharmaKeyRegistryMultisig can get an owner`, + DharmaKeyRegistryMultisig, + "isOwner", + "call", + [tester.ownerOne], + true, + value => { + assert.ok(value); + } + ); + + await tester.runTest( + `DharmaKeyRegistryMultisig returns false for a non-owner`, + DharmaKeyRegistryMultisig, + "isOwner", + "call", + [tester.address], + true, + value => { + assert.ok(!value); + } + ); + + await tester.runTest( + `DharmaKeyRegistryMultisig can get the threshold`, + DharmaKeyRegistryMultisig, + "getThreshold", + "call", + [], + true, + value => { + assert.strictEqual(value, "3"); + } + ); + + await tester.runTest( + `DharmaKeyRegistryMultisig can get the destination`, + DharmaKeyRegistryMultisig, + "getDestination", + "call", + [], + true, + value => { + assert.strictEqual(value, constants.KEY_REGISTRY_V2_ADDRESS); + } + ); + + // Generate the messsage hash based on the supplied parameters. + hashInputs = + DharmaKeyRegistryMultisig.options.address + + "0".padStart(64, "0") + + tester.address.slice(2) + + executorGasLimit.toString(16).padStart(64, "0") + + rawData.slice(2); + + hash = util.bufferToHex(util.keccak256(hashInputs)); + + await tester.runTest( + `DharmaKeyRegistryMultisig can get a hash`, + DharmaKeyRegistryMultisig, + "getNextHash", + "call", + [rawData, tester.address, executorGasLimit], + true, + value => { + assert.strictEqual(value, hash); + } + ); + + await tester.runTest( + `DharmaKeyRegistryMultisig can get a hash with a specific nonce`, + DharmaKeyRegistryMultisig, + "getHash", + "call", + [rawData, tester.address, executorGasLimit, 0], + true, + value => { + assert.strictEqual(value, hash); + } + ); + + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne); + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo); + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree); + ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2); + ownerSigsOutOfOrder = + ownerTwoSig + ownerOneSig.slice(2) + ownerThreeSig.slice(2); + unownedSig = tester.signHashedPrefixedHexString(hash, tester.address); + unownedSigs = unownedSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2); + + await tester.runTest( + `DharmaKeyRegistryMultisig cannot call execute from non-executor`, + DharmaKeyRegistryMultisig, + "execute", + "send", + [rawData, tester.addressTwo, executorGasLimit, ownerSigs], + false + ); + + await tester.runTest( + `DharmaKeyRegistryMultisig cannot call execute with oddly-sized signatures`, + DharmaKeyRegistryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigs + "1234"], + false + ); + + await tester.runTest( + `DharmaKeyRegistryMultisig cannot call execute with non-compliant signatures`, + DharmaKeyRegistryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, bizarreSigs], + false + ); + + await tester.runTest( + `DharmaKeyRegistryMultisig cannot call execute without enough signatures`, + DharmaKeyRegistryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigs.slice(0, -130)], + false + ); + + await tester.runTest( + `DharmaKeyRegistryMultisig cannot call execute without owner signatures`, + DharmaKeyRegistryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, unownedSigs], + false + ); + + await tester.runTest( + `DharmaKeyRegistryMultisig cannot call execute with out-of-order signatures`, + DharmaKeyRegistryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigsOutOfOrder], + false + ); + + await tester.runTest( + `DharmaKeyRegistryMultisig can call execute`, + DharmaKeyRegistryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigs] + ); + + await tester.runTest( + `DharmaKeyRegistryMultisig nonce is incremented`, + DharmaKeyRegistryMultisig, + "getNonce", + "call", + [], + true, + value => { + assert.strictEqual(value, "1"); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryMultisig can get the initial nonce`, + DharmaAccountRecoveryMultisig, + "getNonce", + "call", + [], + true, + value => { + assert.strictEqual(value, "0"); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryMultisig can get the owners`, + DharmaAccountRecoveryMultisig, + "getOwners", + "call", + [], + true, + value => { + assert.deepEqual(value, [ + tester.ownerOne, + tester.ownerTwo, + tester.ownerThree, + tester.ownerFour + ]); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryMultisig can get an owner`, + DharmaAccountRecoveryMultisig, + "isOwner", + "call", + [tester.ownerOne], + true, + value => { + assert.ok(value); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryMultisig returns false for a non-owner`, + DharmaAccountRecoveryMultisig, + "isOwner", + "call", + [tester.address], + true, + value => { + assert.ok(!value); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryMultisig can get the threshold`, + DharmaAccountRecoveryMultisig, + "getThreshold", + "call", + [], + true, + value => { + assert.strictEqual(value, "3"); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryMultisig can get the destination`, + DharmaAccountRecoveryMultisig, + "getDestination", + "call", + [], + true, + value => { + assert.strictEqual( + value, + constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS + ); + } + ); + + // Generate the messsage hash based on the supplied parameters. + hashInputs = + DharmaAccountRecoveryMultisig.options.address + + "0".padStart(64, "0") + + tester.address.slice(2) + + executorGasLimit.toString(16).padStart(64, "0") + + rawData.slice(2); + + hash = util.bufferToHex(util.keccak256(hashInputs)); + + await tester.runTest( + `DharmaAccountRecoveryMultisig can get a hash`, + DharmaAccountRecoveryMultisig, + "getNextHash", + "call", + [rawData, tester.address, executorGasLimit], + true, + value => { + assert.strictEqual(value, hash); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryMultisig can get a hash with a specific nonce`, + DharmaAccountRecoveryMultisig, + "getHash", + "call", + [rawData, tester.address, executorGasLimit, 0], + true, + value => { + assert.strictEqual(value, hash); + } + ); + + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne); + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo); + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree); + + /* ownerSigs = ownerOneSig + ownerTwoSig.slice(2) ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) unownedSig = tester.signHashedPrefixedHexString(hash, address) unownedSigs = unownedSig + ownerTwoSig.slice(2) */ - ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) + ownerThreeSig.slice(2) - unownedSig = tester.signHashedPrefixedHexString(hash, tester.address) - unownedSigs = unownedSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - - await tester.runTest( - `DharmaAccountRecoveryMultisig cannot call execute from non-executor`, - DharmaAccountRecoveryMultisig, - 'execute', - 'send', - [rawData, tester.addressTwo, executorGasLimit, ownerSigs], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig cannot call execute with oddly-sized signatures`, - DharmaAccountRecoveryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigs + '1234'], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig cannot call execute with non-compliant signatures`, - DharmaAccountRecoveryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, bizarreSigs], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig cannot call execute without enough signatures`, - DharmaAccountRecoveryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerOneSig], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig cannot call execute without owner signatures`, - DharmaAccountRecoveryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, unownedSigs], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig cannot call execute with out-of-order signatures`, - DharmaAccountRecoveryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigsOutOfOrder], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig can call execute`, - DharmaAccountRecoveryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigs] - ) - - await tester.runTest( - `DharmaAccountRecoveryMultisig nonce is incremented`, - DharmaAccountRecoveryMultisig, - 'getNonce', - 'call', - [], - true, - value => { - assert.strictEqual(value, '1') - } - ) - - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig can get the owners`, - DharmaAccountRecoveryOperatorMultisig, - 'getOwners', - 'call', - [], - true, - value => { - assert.deepEqual( - value, [tester.ownerOne, tester.ownerTwo, tester.ownerThree, tester.ownerFour] - ) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig can get an owner`, - DharmaAccountRecoveryOperatorMultisig, - 'isOwner', - 'call', - [tester.ownerOne], - true, - value => { - assert.ok(value) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig returns false for a non-owner`, - DharmaAccountRecoveryOperatorMultisig, - 'isOwner', - 'call', - [tester.address], - true, - value => { - assert.ok(!value) - } - ) - - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig can get the threshold`, - DharmaAccountRecoveryOperatorMultisig, - 'getThreshold', - 'call', - [], - true, - value => { - assert.strictEqual(value, '2') - } - ) - - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig can get the destination`, - DharmaAccountRecoveryOperatorMultisig, - 'getDestination', - 'call', - [], - true, - value => { - assert.strictEqual(value, constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS) - } - ) - - // Generate the messsage hash based on the supplied parameters. - hashInputs = ( - DharmaAccountRecoveryOperatorMultisig.options.address + - '0'.padStart(64, '0') + - tester.address.slice(2) + - executorGasLimit.toString(16).padStart(64, '0') + - rawData.slice(2) - ) - - hash = util.bufferToHex(util.keccak256(hashInputs)) - - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig can get a hash`, - DharmaAccountRecoveryOperatorMultisig, - 'getHash', - 'call', - [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32], - true, - values => { - assert.strictEqual(values.hash, hash) - } - ) - - ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) - ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) - - /* + ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2); + ownerSigsOutOfOrder = + ownerTwoSig + ownerOneSig.slice(2) + ownerThreeSig.slice(2); + unownedSig = tester.signHashedPrefixedHexString(hash, tester.address); + unownedSigs = unownedSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2); + + await tester.runTest( + `DharmaAccountRecoveryMultisig cannot call execute from non-executor`, + DharmaAccountRecoveryMultisig, + "execute", + "send", + [rawData, tester.addressTwo, executorGasLimit, ownerSigs], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryMultisig cannot call execute with oddly-sized signatures`, + DharmaAccountRecoveryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigs + "1234"], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryMultisig cannot call execute with non-compliant signatures`, + DharmaAccountRecoveryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, bizarreSigs], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryMultisig cannot call execute without enough signatures`, + DharmaAccountRecoveryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerOneSig], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryMultisig cannot call execute without owner signatures`, + DharmaAccountRecoveryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, unownedSigs], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryMultisig cannot call execute with out-of-order signatures`, + DharmaAccountRecoveryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigsOutOfOrder], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryMultisig can call execute`, + DharmaAccountRecoveryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigs] + ); + + await tester.runTest( + `DharmaAccountRecoveryMultisig nonce is incremented`, + DharmaAccountRecoveryMultisig, + "getNonce", + "call", + [], + true, + value => { + assert.strictEqual(value, "1"); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig can get the owners`, + DharmaAccountRecoveryOperatorMultisig, + "getOwners", + "call", + [], + true, + value => { + assert.deepEqual(value, [ + tester.ownerOne, + tester.ownerTwo, + tester.ownerThree, + tester.ownerFour + ]); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig can get an owner`, + DharmaAccountRecoveryOperatorMultisig, + "isOwner", + "call", + [tester.ownerOne], + true, + value => { + assert.ok(value); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig returns false for a non-owner`, + DharmaAccountRecoveryOperatorMultisig, + "isOwner", + "call", + [tester.address], + true, + value => { + assert.ok(!value); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig can get the threshold`, + DharmaAccountRecoveryOperatorMultisig, + "getThreshold", + "call", + [], + true, + value => { + assert.strictEqual(value, "2"); + } + ); + + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig can get the destination`, + DharmaAccountRecoveryOperatorMultisig, + "getDestination", + "call", + [], + true, + value => { + assert.strictEqual( + value, + constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS + ); + } + ); + + // Generate the messsage hash based on the supplied parameters. + hashInputs = + DharmaAccountRecoveryOperatorMultisig.options.address + + "0".padStart(64, "0") + + tester.address.slice(2) + + executorGasLimit.toString(16).padStart(64, "0") + + rawData.slice(2); + + hash = util.bufferToHex(util.keccak256(hashInputs)); + + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig can get a hash`, + DharmaAccountRecoveryOperatorMultisig, + "getHash", + "call", + [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32], + true, + values => { + assert.strictEqual(values.hash, hash); + } + ); + + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne); + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo); + + /* ownerSigs = ownerOneSig + ownerTwoSig.slice(2) ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) unownedSig = tester.signHashedPrefixedHexString(hash, address) unownedSigs = unownedSig + ownerTwoSig.slice(2) */ - ownerSigs = ownerOneSig + ownerTwoSig.slice(2) - ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2) - unownedSig = tester.signHashedPrefixedHexString(hash, tester.address) - unownedSigs = unownedSig + ownerTwoSig.slice(2) - - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig cannot call execute from non-executor`, - DharmaAccountRecoveryOperatorMultisig, - 'execute', - 'send', - [rawData, tester.addressTwo, executorGasLimit, constants.NULL_BYTES_32, ownerSigs], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig cannot call execute with oddly-sized signatures`, - DharmaAccountRecoveryOperatorMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32, ownerSigs + '1234'], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig cannot call execute with non-compliant signatures`, - DharmaAccountRecoveryOperatorMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32, bizarreSigs], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig cannot call execute without enough signatures`, - DharmaAccountRecoveryOperatorMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32, ownerOneSig], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig cannot call execute without owner signatures`, - DharmaAccountRecoveryOperatorMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32, unownedSigs], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig cannot call execute with out-of-order signatures`, - DharmaAccountRecoveryOperatorMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32, ownerSigsOutOfOrder], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig can call execute`, - DharmaAccountRecoveryOperatorMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32, ownerSigs] - ) - - await tester.runTest( - `DharmaAccountRecoveryOperatorMultisig cannot replay a call to execute`, - DharmaAccountRecoveryOperatorMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, constants.NULL_BYTES_32, ownerSigs], - false - ) - - const DharmaEscapeHatchRegistry = await tester.runTest( - `DharmaEscapeHatchRegistry contract deployment`, - tester.DharmaEscapeHatchRegistryDeployer, - '', - 'deploy' - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry confirms that an escape hatch does not exist until set`, - DharmaEscapeHatchRegistry, - 'getEscapeHatch', - 'call', - [], - true, - value => { - assert.ok(!value.exists) - assert.strictEqual(value.escapeHatch, constants.NULL_ADDRESS) - } - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry can set the null address as an escape hatch account`, - DharmaEscapeHatchRegistry, - 'setEscapeHatch', - 'send', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry can set an escape hatch account`, - DharmaEscapeHatchRegistry, - 'setEscapeHatch', - 'send', - [tester.addressTwo] - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry can get an escape hatch account once set`, - DharmaEscapeHatchRegistry, - 'getEscapeHatch', - 'call', - [], - true, - value => { - assert.ok(value.exists) - assert.strictEqual(value.escapeHatch, tester.addressTwo) - } - ) - - fallbackEscapeHatch = await web3.eth.call({ - to: DharmaEscapeHatchRegistry.options.address, - from: tester.address, - data: "0x" - }) - - console.log( - ' ✓ DharmaEscapeHatchRegistry can get an escape hatch account using the fallback' - ) - assert.strictEqual( - web3.eth.abi.decodeParameter('address', fallbackEscapeHatch), - tester.addressTwo - ) - tester.passed++ - - await tester.runTest( - `DharmaEscapeHatchRegistry can get an escape hatch for a specific smart wallet`, - DharmaEscapeHatchRegistry, - 'getEscapeHatchForSmartWallet', - 'call', - [tester.address], - true, - value => { - assert.ok(value.exists) - assert.strictEqual(value.escapeHatch, tester.addressTwo) - }, - tester.originalAddress - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry cannot get an escape hatch the null address`, - DharmaEscapeHatchRegistry, - 'getEscapeHatchForSmartWallet', - 'call', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry can remove an escape hatch account`, - DharmaEscapeHatchRegistry, - 'removeEscapeHatch' - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry confirms that an escape hatch is successfully removed`, - DharmaEscapeHatchRegistry, - 'getEscapeHatch', - 'call', - [], - true, - value => { - assert.ok(!value.exists) - assert.strictEqual(value.escapeHatch, constants.NULL_ADDRESS) - } - ) - - fallbackEscapeHatch = await web3.eth.call({ - to: DharmaEscapeHatchRegistry.options.address, - from: tester.address, - data: "0x" - }) - - console.log( - ' ✓ DharmaEscapeHatchRegistry can gets null address for removed escape hatch account using the fallback' - ) - assert.strictEqual( - web3.eth.abi.decodeParameter('address', fallbackEscapeHatch), - constants.NULL_ADDRESS - ) - tester.passed++ - - await tester.runTest( - `DharmaEscapeHatchRegistry will not fire an event when removing an unset escape hatch account`, - DharmaEscapeHatchRegistry, - 'removeEscapeHatch' - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry confirms that escape hatch functionality is not initially disabled`, - DharmaEscapeHatchRegistry, - 'hasDisabledEscapeHatchForSmartWallet', - 'call', - [tester.address], - true, - value => { - assert.ok(!value) - }, - tester.originalAddress - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry cannot get disabled status for null address`, - DharmaEscapeHatchRegistry, - 'hasDisabledEscapeHatchForSmartWallet', - 'call', - [constants.NULL_ADDRESS], - false - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry can reset an escape hatch account`, - DharmaEscapeHatchRegistry, - 'setEscapeHatch', - 'send', - [tester.ownerOne] - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry can get an escape hatch account once reset`, - DharmaEscapeHatchRegistry, - 'getEscapeHatch', - 'call', - [], - true, - value => { - assert.ok(value.exists) - assert.strictEqual(value.escapeHatch, tester.ownerOne) - } - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry setting an existing escape hatch account is a no-op`, - DharmaEscapeHatchRegistry, - 'setEscapeHatch', - 'send', - [tester.ownerOne] - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry can disable the escape hatch mechanism`, - DharmaEscapeHatchRegistry, - 'permanentlyDisableEscapeHatch' - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry confirms that escape hatch functionality is disabled`, - DharmaEscapeHatchRegistry, - 'hasDisabledEscapeHatchForSmartWallet', - 'call', - [tester.address], - true, - value => { - assert.ok(value) - }, - tester.originalAddress - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry confirms that an escape hatch is successfully removed when disabling`, - DharmaEscapeHatchRegistry, - 'getEscapeHatch', - 'call', - [], - true, - value => { - assert.ok(!value.exists) - assert.strictEqual(value.escapeHatch, constants.NULL_ADDRESS) - } - ) - - fallbackEscapeHatch = await web3.eth.call({ - to: DharmaEscapeHatchRegistry.options.address, - from: tester.address, - data: "0x" - }) - - console.log( - ' ✓ DharmaEscapeHatchRegistry can gets null address for removed escape hatch account after disabling using the fallback' - ) - assert.strictEqual( - web3.eth.abi.decodeParameter('address', fallbackEscapeHatch), - constants.NULL_ADDRESS - ) - tester.passed++ - - await tester.runTest( - `DharmaEscapeHatchRegistry confirms escape hatch is removed after disabling for for a specific smart wallet`, - DharmaEscapeHatchRegistry, - 'getEscapeHatchForSmartWallet', - 'call', - [tester.address], - true, - value => { - assert.ok(!value.exists) - assert.strictEqual(value.escapeHatch, constants.NULL_ADDRESS) - }, - tester.originalAddress - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry cannot set an escape hatch account once disabled`, - DharmaEscapeHatchRegistry, - 'setEscapeHatch', - 'send', - [tester.ownerTwo], - false - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry cannot remove an escape hatch account once disabled`, - DharmaEscapeHatchRegistry, - 'removeEscapeHatch', - 'send', - [], - false - ) - - await tester.runTest( - `DharmaEscapeHatchRegistry cannot re-disable an escape hatch account once disabled`, - DharmaEscapeHatchRegistry, - 'permanentlyDisableEscapeHatch', - 'send', - [], - false - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 owner can start ownership transfer to multisig`, - tester.DharmaAccountRecoveryManagerV2, - 'transferOwnership', - 'send', - [DharmaAccountRecoveryMultisig.options.address] - ) - - rawData = tester.DharmaAccountRecoveryManagerV2.methods.acceptOwnership().encodeABI() - await tester.runTest( - `DharmaAccountRecoveryMultisig can get a hash`, - DharmaAccountRecoveryMultisig, - 'getNextHash', - 'call', - [rawData, tester.address, executorGasLimit], - true, - value => { - hash = value - } - ) - - // accept ownership - ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) - ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) - ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) - ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - - await tester.runTest( - `DharmaAccountRecoveryMultisig can call execute to accept ownership`, - DharmaAccountRecoveryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigs] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 owner is now set to multisig`, - tester.DharmaAccountRecoveryManagerV2, - 'owner', - 'call', - [], - true, - value => { - assert.strictEqual(value, DharmaAccountRecoveryMultisig.options.address) - } - ) - - // TODO: test account recovery using the multisig? - - // transfer ownership back - rawData = tester.DharmaAccountRecoveryManagerV2.methods.transferOwnership(tester.address).encodeABI() - await tester.runTest( - `DharmaAccountRecoveryMultisig can get a hash`, - DharmaAccountRecoveryMultisig, - 'getNextHash', - 'call', - [rawData, tester.address, executorGasLimit], - true, - value => { - hash = value - } - ) - - ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) - ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) - ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) - ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - - await tester.runTest( - `DharmaAccountRecoveryMultisig can call execute to transfer ownership back`, - DharmaAccountRecoveryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigs] - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 EOA can accept ownership transfer from multisig`, - tester.DharmaAccountRecoveryManagerV2, - 'acceptOwnership' - ) - - await tester.runTest( - `DharmaAccountRecoveryManagerV2 owner is now set to EOA`, - tester.DharmaAccountRecoveryManagerV2, - 'owner', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - `DharmaKeyRegistryV2 owner can start ownership transfer to multisig`, - tester.DharmaKeyRegistryV2, - 'transferOwnership', - 'send', - [DharmaKeyRegistryMultisig.options.address] - ) - - rawData = tester.DharmaKeyRegistryV2.methods.acceptOwnership().encodeABI() - await tester.runTest( - `DharmaKeyRegistryMultisig can get a hash`, - DharmaKeyRegistryMultisig, - 'getNextHash', - 'call', - [rawData, tester.address, executorGasLimit], - true, - value => { - hash = value - } - ) - - // accept ownership - ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) - ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) - ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) - ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - - await tester.runTest( - `DharmaKeyRegistryMultisig can call execute to accept ownership`, - DharmaKeyRegistryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigs] - ) - - await tester.runTest( - `DharmaKeyRegistryV2 owner is now set to multisig`, - tester.DharmaKeyRegistryV2, - 'owner', - 'call', - [], - true, - value => { - assert.strictEqual(value, DharmaKeyRegistryMultisig.options.address) - } - ) - - // TODO: test setting a new key using the multisig? - - // transfer ownership back - rawData = tester.DharmaKeyRegistryV2.methods.transferOwnership(tester.address).encodeABI() - await tester.runTest( - `DharmaKeyRegistryMultisig can get a hash`, - DharmaKeyRegistryMultisig, - 'getNextHash', - 'call', - [rawData, tester.address, executorGasLimit], - true, - value => { - hash = value - } - ) - - ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) - ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) - ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) - ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - - await tester.runTest( - `DharmaKeyRegistryMultisig can call execute to transfer ownership back`, - DharmaKeyRegistryMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigs] - ) - - await tester.runTest( - `DharmaKeyRegistryV2 EOA can accept ownership transfer from multisig`, - tester.DharmaKeyRegistryV2, - 'acceptOwnership' - ) - - await tester.runTest( - `DharmaKeyRegistryV2 owner is now set to EOA`, - tester.DharmaKeyRegistryV2, - 'owner', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner is initially set to an EOA`, - tester.DharmaUpgradeBeaconControllerManager, - 'owner', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) - } - ) - - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner can start ownership transfer to multisig`, - tester.DharmaUpgradeBeaconControllerManager, - 'transferOwnership', - 'send', - [DharmaUpgradeMultisig.options.address] - ) + ownerSigs = ownerOneSig + ownerTwoSig.slice(2); + ownerSigsOutOfOrder = ownerTwoSig + ownerOneSig.slice(2); + unownedSig = tester.signHashedPrefixedHexString(hash, tester.address); + unownedSigs = unownedSig + ownerTwoSig.slice(2); - rawData = tester.DharmaUpgradeBeaconControllerManager.methods.acceptOwnership().encodeABI() - await tester.runTest( - `DharmaUpgradeMultisig can get a hash`, - DharmaUpgradeMultisig, - 'getNextHash', - 'call', - [rawData, tester.address, executorGasLimit], - true, - value => { - hash = value - } - ) + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig cannot call execute from non-executor`, + DharmaAccountRecoveryOperatorMultisig, + "execute", + "send", + [ + rawData, + tester.addressTwo, + executorGasLimit, + constants.NULL_BYTES_32, + ownerSigs + ], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig cannot call execute with oddly-sized signatures`, + DharmaAccountRecoveryOperatorMultisig, + "execute", + "send", + [ + rawData, + tester.address, + executorGasLimit, + constants.NULL_BYTES_32, + ownerSigs + "1234" + ], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig cannot call execute with non-compliant signatures`, + DharmaAccountRecoveryOperatorMultisig, + "execute", + "send", + [ + rawData, + tester.address, + executorGasLimit, + constants.NULL_BYTES_32, + bizarreSigs + ], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig cannot call execute without enough signatures`, + DharmaAccountRecoveryOperatorMultisig, + "execute", + "send", + [ + rawData, + tester.address, + executorGasLimit, + constants.NULL_BYTES_32, + ownerOneSig + ], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig cannot call execute without owner signatures`, + DharmaAccountRecoveryOperatorMultisig, + "execute", + "send", + [ + rawData, + tester.address, + executorGasLimit, + constants.NULL_BYTES_32, + unownedSigs + ], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig cannot call execute with out-of-order signatures`, + DharmaAccountRecoveryOperatorMultisig, + "execute", + "send", + [ + rawData, + tester.address, + executorGasLimit, + constants.NULL_BYTES_32, + ownerSigsOutOfOrder + ], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig can call execute`, + DharmaAccountRecoveryOperatorMultisig, + "execute", + "send", + [ + rawData, + tester.address, + executorGasLimit, + constants.NULL_BYTES_32, + ownerSigs + ] + ); + + await tester.runTest( + `DharmaAccountRecoveryOperatorMultisig cannot replay a call to execute`, + DharmaAccountRecoveryOperatorMultisig, + "execute", + "send", + [ + rawData, + tester.address, + executorGasLimit, + constants.NULL_BYTES_32, + ownerSigs + ], + false + ); + + const DharmaEscapeHatchRegistry = await tester.runTest( + `DharmaEscapeHatchRegistry contract deployment`, + tester.DharmaEscapeHatchRegistryDeployer, + "", + "deploy" + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry confirms that an escape hatch does not exist until set`, + DharmaEscapeHatchRegistry, + "getEscapeHatch", + "call", + [], + true, + value => { + assert.ok(!value.exists); + assert.strictEqual(value.escapeHatch, constants.NULL_ADDRESS); + } + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry can set the null address as an escape hatch account`, + DharmaEscapeHatchRegistry, + "setEscapeHatch", + "send", + [constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry can set an escape hatch account`, + DharmaEscapeHatchRegistry, + "setEscapeHatch", + "send", + [tester.addressTwo] + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry can get an escape hatch account once set`, + DharmaEscapeHatchRegistry, + "getEscapeHatch", + "call", + [], + true, + value => { + assert.ok(value.exists); + assert.strictEqual(value.escapeHatch, tester.addressTwo); + } + ); + + fallbackEscapeHatch = await web3.eth.call({ + to: DharmaEscapeHatchRegistry.options.address, + from: tester.address, + data: "0x" + }); - // accept ownership - ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) - ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) - ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) - ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - - await tester.runTest( - `DharmaUpgradeMultisig can call execute to accept ownership`, - DharmaUpgradeMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigs] - ) + console.log( + " ✓ DharmaEscapeHatchRegistry can get an escape hatch account using the fallback" + ); + assert.strictEqual( + web3.eth.abi.decodeParameter("address", fallbackEscapeHatch), + tester.addressTwo + ); + tester.passed++; + + await tester.runTest( + `DharmaEscapeHatchRegistry can get an escape hatch for a specific smart wallet`, + DharmaEscapeHatchRegistry, + "getEscapeHatchForSmartWallet", + "call", + [tester.address], + true, + value => { + assert.ok(value.exists); + assert.strictEqual(value.escapeHatch, tester.addressTwo); + }, + tester.originalAddress + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry cannot get an escape hatch the null address`, + DharmaEscapeHatchRegistry, + "getEscapeHatchForSmartWallet", + "call", + [constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry can remove an escape hatch account`, + DharmaEscapeHatchRegistry, + "removeEscapeHatch" + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry confirms that an escape hatch is successfully removed`, + DharmaEscapeHatchRegistry, + "getEscapeHatch", + "call", + [], + true, + value => { + assert.ok(!value.exists); + assert.strictEqual(value.escapeHatch, constants.NULL_ADDRESS); + } + ); + + fallbackEscapeHatch = await web3.eth.call({ + to: DharmaEscapeHatchRegistry.options.address, + from: tester.address, + data: "0x" + }); - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner is now set to multisig`, - tester.DharmaUpgradeBeaconControllerManager, - 'owner', - 'call', - [], - true, - value => { - assert.strictEqual(value, DharmaUpgradeMultisig.options.address) - } - ) + console.log( + " ✓ DharmaEscapeHatchRegistry can gets null address for removed escape hatch account using the fallback" + ); + assert.strictEqual( + web3.eth.abi.decodeParameter("address", fallbackEscapeHatch), + constants.NULL_ADDRESS + ); + tester.passed++; + + await tester.runTest( + `DharmaEscapeHatchRegistry will not fire an event when removing an unset escape hatch account`, + DharmaEscapeHatchRegistry, + "removeEscapeHatch" + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry confirms that escape hatch functionality is not initially disabled`, + DharmaEscapeHatchRegistry, + "hasDisabledEscapeHatchForSmartWallet", + "call", + [tester.address], + true, + value => { + assert.ok(!value); + }, + tester.originalAddress + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry cannot get disabled status for null address`, + DharmaEscapeHatchRegistry, + "hasDisabledEscapeHatchForSmartWallet", + "call", + [constants.NULL_ADDRESS], + false + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry can reset an escape hatch account`, + DharmaEscapeHatchRegistry, + "setEscapeHatch", + "send", + [tester.ownerOne] + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry can get an escape hatch account once reset`, + DharmaEscapeHatchRegistry, + "getEscapeHatch", + "call", + [], + true, + value => { + assert.ok(value.exists); + assert.strictEqual(value.escapeHatch, tester.ownerOne); + } + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry setting an existing escape hatch account is a no-op`, + DharmaEscapeHatchRegistry, + "setEscapeHatch", + "send", + [tester.ownerOne] + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry can disable the escape hatch mechanism`, + DharmaEscapeHatchRegistry, + "permanentlyDisableEscapeHatch" + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry confirms that escape hatch functionality is disabled`, + DharmaEscapeHatchRegistry, + "hasDisabledEscapeHatchForSmartWallet", + "call", + [tester.address], + true, + value => { + assert.ok(value); + }, + tester.originalAddress + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry confirms that an escape hatch is successfully removed when disabling`, + DharmaEscapeHatchRegistry, + "getEscapeHatch", + "call", + [], + true, + value => { + assert.ok(!value.exists); + assert.strictEqual(value.escapeHatch, constants.NULL_ADDRESS); + } + ); + + fallbackEscapeHatch = await web3.eth.call({ + to: DharmaEscapeHatchRegistry.options.address, + from: tester.address, + data: "0x" + }); - // TODO: test an upgrade, rollback, etc with the multisig? - - // transfer ownership back - rawData = tester.DharmaUpgradeBeaconControllerManager.methods.transferOwnership(tester.address).encodeABI() - await tester.runTest( - `DharmaUpgradeMultisig can get a hash`, - DharmaUpgradeMultisig, - 'getNextHash', - 'call', - [rawData, tester.address, executorGasLimit], - true, - value => { - hash = value - } - ) + console.log( + " ✓ DharmaEscapeHatchRegistry can gets null address for removed escape hatch account after disabling using the fallback" + ); + assert.strictEqual( + web3.eth.abi.decodeParameter("address", fallbackEscapeHatch), + constants.NULL_ADDRESS + ); + tester.passed++; + + await tester.runTest( + `DharmaEscapeHatchRegistry confirms escape hatch is removed after disabling for for a specific smart wallet`, + DharmaEscapeHatchRegistry, + "getEscapeHatchForSmartWallet", + "call", + [tester.address], + true, + value => { + assert.ok(!value.exists); + assert.strictEqual(value.escapeHatch, constants.NULL_ADDRESS); + }, + tester.originalAddress + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry cannot set an escape hatch account once disabled`, + DharmaEscapeHatchRegistry, + "setEscapeHatch", + "send", + [tester.ownerTwo], + false + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry cannot remove an escape hatch account once disabled`, + DharmaEscapeHatchRegistry, + "removeEscapeHatch", + "send", + [], + false + ); + + await tester.runTest( + `DharmaEscapeHatchRegistry cannot re-disable an escape hatch account once disabled`, + DharmaEscapeHatchRegistry, + "permanentlyDisableEscapeHatch", + "send", + [], + false + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 owner can start ownership transfer to multisig`, + tester.DharmaAccountRecoveryManagerV2, + "transferOwnership", + "send", + [DharmaAccountRecoveryMultisig.options.address] + ); + + rawData = tester.DharmaAccountRecoveryManagerV2.methods + .acceptOwnership() + .encodeABI(); + await tester.runTest( + `DharmaAccountRecoveryMultisig can get a hash`, + DharmaAccountRecoveryMultisig, + "getNextHash", + "call", + [rawData, tester.address, executorGasLimit], + true, + value => { + hash = value; + } + ); + + // accept ownership + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne); + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo); + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree); + ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2); + + await tester.runTest( + `DharmaAccountRecoveryMultisig can call execute to accept ownership`, + DharmaAccountRecoveryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigs] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 owner is now set to multisig`, + tester.DharmaAccountRecoveryManagerV2, + "owner", + "call", + [], + true, + value => { + assert.strictEqual( + value, + DharmaAccountRecoveryMultisig.options.address + ); + } + ); + + // TODO: test account recovery using the multisig? + + // transfer ownership back + rawData = tester.DharmaAccountRecoveryManagerV2.methods + .transferOwnership(tester.address) + .encodeABI(); + await tester.runTest( + `DharmaAccountRecoveryMultisig can get a hash`, + DharmaAccountRecoveryMultisig, + "getNextHash", + "call", + [rawData, tester.address, executorGasLimit], + true, + value => { + hash = value; + } + ); + + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne); + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo); + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree); + ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2); + + await tester.runTest( + `DharmaAccountRecoveryMultisig can call execute to transfer ownership back`, + DharmaAccountRecoveryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigs] + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 EOA can accept ownership transfer from multisig`, + tester.DharmaAccountRecoveryManagerV2, + "acceptOwnership" + ); + + await tester.runTest( + `DharmaAccountRecoveryManagerV2 owner is now set to EOA`, + tester.DharmaAccountRecoveryManagerV2, + "owner", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.address); + } + ); + + await tester.runTest( + `DharmaKeyRegistryV2 owner can start ownership transfer to multisig`, + tester.DharmaKeyRegistryV2, + "transferOwnership", + "send", + [DharmaKeyRegistryMultisig.options.address] + ); + + rawData = tester.DharmaKeyRegistryV2.methods.acceptOwnership().encodeABI(); + await tester.runTest( + `DharmaKeyRegistryMultisig can get a hash`, + DharmaKeyRegistryMultisig, + "getNextHash", + "call", + [rawData, tester.address, executorGasLimit], + true, + value => { + hash = value; + } + ); + + // accept ownership + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne); + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo); + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree); + ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2); + + await tester.runTest( + `DharmaKeyRegistryMultisig can call execute to accept ownership`, + DharmaKeyRegistryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigs] + ); + + await tester.runTest( + `DharmaKeyRegistryV2 owner is now set to multisig`, + tester.DharmaKeyRegistryV2, + "owner", + "call", + [], + true, + value => { + assert.strictEqual( + value, + DharmaKeyRegistryMultisig.options.address + ); + } + ); + + // TODO: test setting a new key using the multisig? + + // transfer ownership back + rawData = tester.DharmaKeyRegistryV2.methods + .transferOwnership(tester.address) + .encodeABI(); + await tester.runTest( + `DharmaKeyRegistryMultisig can get a hash`, + DharmaKeyRegistryMultisig, + "getNextHash", + "call", + [rawData, tester.address, executorGasLimit], + true, + value => { + hash = value; + } + ); + + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne); + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo); + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree); + ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2); + + await tester.runTest( + `DharmaKeyRegistryMultisig can call execute to transfer ownership back`, + DharmaKeyRegistryMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigs] + ); + + await tester.runTest( + `DharmaKeyRegistryV2 EOA can accept ownership transfer from multisig`, + tester.DharmaKeyRegistryV2, + "acceptOwnership" + ); + + await tester.runTest( + `DharmaKeyRegistryV2 owner is now set to EOA`, + tester.DharmaKeyRegistryV2, + "owner", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.address); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner is initially set to an EOA`, + tester.DharmaUpgradeBeaconControllerManager, + "owner", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.address); + } + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner can start ownership transfer to multisig`, + tester.DharmaUpgradeBeaconControllerManager, + "transferOwnership", + "send", + [DharmaUpgradeMultisig.options.address] + ); + + rawData = tester.DharmaUpgradeBeaconControllerManager.methods + .acceptOwnership() + .encodeABI(); + await tester.runTest( + `DharmaUpgradeMultisig can get a hash`, + DharmaUpgradeMultisig, + "getNextHash", + "call", + [rawData, tester.address, executorGasLimit], + true, + value => { + hash = value; + } + ); + + // accept ownership + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne); + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo); + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree); + ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2); + + await tester.runTest( + `DharmaUpgradeMultisig can call execute to accept ownership`, + DharmaUpgradeMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigs] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner is now set to multisig`, + tester.DharmaUpgradeBeaconControllerManager, + "owner", + "call", + [], + true, + value => { + assert.strictEqual(value, DharmaUpgradeMultisig.options.address); + } + ); + + // TODO: test an upgrade, rollback, etc with the multisig? + + // transfer ownership back + rawData = tester.DharmaUpgradeBeaconControllerManager.methods + .transferOwnership(tester.address) + .encodeABI(); + await tester.runTest( + `DharmaUpgradeMultisig can get a hash`, + DharmaUpgradeMultisig, + "getNextHash", + "call", + [rawData, tester.address, executorGasLimit], + true, + value => { + hash = value; + } + ); + + ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne); + ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo); + ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree); + ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2); + + await tester.runTest( + `DharmaUpgradeMultisig can call execute to transfer ownership back`, + DharmaUpgradeMultisig, + "execute", + "send", + [rawData, tester.address, executorGasLimit, ownerSigs] + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager EOA can accept ownership transfer from multisig`, + tester.DharmaUpgradeBeaconControllerManager, + "acceptOwnership" + ); + + await tester.runTest( + `DharmaUpgradeBeaconControllerManager owner is now set to EOA`, + tester.DharmaUpgradeBeaconControllerManager, + "owner", + "call", + [], + true, + value => { + assert.strictEqual(value, tester.address); + } + ); + + await testUpgradeBeaconControllerManagerPartTwo( + tester, + DharmaUpgradeBeaconControllerManagerCoverage, + tester.DharmaUpgradeBeaconController, + tester.DharmaKeyRingUpgradeBeaconController, + tester.DharmaUpgradeBeacon.options.address, + AdharmaSmartWalletImplementation.options.address, + DharmaSmartWalletImplementationV7.options.address, + DharmaKeyRingImplementationV1.options.address + ); - ownerOneSig = tester.signHashedPrefixedHexString(hash, tester.ownerOne) - ownerTwoSig = tester.signHashedPrefixedHexString(hash, tester.ownerTwo) - ownerThreeSig = tester.signHashedPrefixedHexString(hash, tester.ownerThree) - ownerSigs = ownerOneSig + ownerTwoSig.slice(2) + ownerThreeSig.slice(2) - - await tester.runTest( - `DharmaUpgradeMultisig can call execute to transfer ownership back`, - DharmaUpgradeMultisig, - 'execute', - 'send', - [rawData, tester.address, executorGasLimit, ownerSigs] - ) + console.log( + `completed ${tester.passed + tester.failed} test${ + tester.passed + tester.failed === 1 ? "" : "s" + } ` + `with ${tester.failed} failure${tester.failed === 1 ? "" : "s"}.` + ); - await tester.runTest( - `DharmaUpgradeBeaconControllerManager EOA can accept ownership transfer from multisig`, - tester.DharmaUpgradeBeaconControllerManager, - 'acceptOwnership' - ) + await longer(); - await tester.runTest( - `DharmaUpgradeBeaconControllerManager owner is now set to EOA`, - tester.DharmaUpgradeBeaconControllerManager, - 'owner', - 'call', - [], - true, - value => { - assert.strictEqual(value, tester.address) + if (tester.failed > 0) { + process.exit(1); } - ) - - await testUpgradeBeaconControllerManagerPartTwo( - tester, - DharmaUpgradeBeaconControllerManagerCoverage, - tester.DharmaUpgradeBeaconController, - tester.DharmaKeyRingUpgradeBeaconController, - tester.DharmaUpgradeBeacon.options.address, - AdharmaSmartWalletImplementation.options.address, - DharmaSmartWalletImplementationV7.options.address, - DharmaKeyRingImplementationV1.options.address - ) - - console.log( - `completed ${tester.passed + tester.failed} test${tester.passed + tester.failed === 1 ? '' : 's'} ` + - `with ${tester.failed} failure${tester.failed === 1 ? '' : 's'}.` - ) - - await longer(); - - if (tester.failed > 0) { - process.exit(1) - } - - // exit. - return 0 + // exit. + return 0; } module.exports = { - test, + test }; diff --git a/scripts/test/testCoverage.js b/scripts/test/testCoverage.js index c622a8d..feca4cc 100644 --- a/scripts/test/testCoverage.js +++ b/scripts/test/testCoverage.js @@ -1,17 +1,17 @@ // import tests -var deployMockExternal = require('./deployMockExternal.js') -var deploy = require('./deploy.js') -var test = require('./test.js') +var deployMockExternal = require("./deployMockExternal.js"); +var deploy = require("./deploy.js"); +var test = require("./test.js"); // run tests async function runTests() { - const context = process.env.TESTING_CONTEXT; + const context = process.env.TESTING_CONTEXT; - await deployMockExternal.test(context); - await deploy.test(context); - await test.test(context); + await deployMockExternal.test(context); + await deploy.test(context); + await test.test(context); - process.exit(0) + process.exit(0); } -runTests() \ No newline at end of file +runTests(); diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index 4b63d6b..c9b0af5 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -1,49 +1,49 @@ const { web3 } = require("./web3"); const constants = require("./constants"); const assert = require("assert"); -const util = require('ethereumjs-util'); +const util = require("ethereumjs-util"); -const MockCodeCheckArtifact = require('../../build/contracts/MockCodeCheck.json') +const MockCodeCheckArtifact = require("../../build/contracts/MockCodeCheck.json"); -const AdharmaSmartWalletImplementationArtifact = require('../../build/contracts/AdharmaSmartWalletImplementation.json') -const AdharmaKeyRingImplementationArtifact = require('../../build/contracts/AdharmaKeyRingImplementation.json') +const AdharmaSmartWalletImplementationArtifact = require("../../build/contracts/AdharmaSmartWalletImplementation.json"); +const AdharmaKeyRingImplementationArtifact = require("../../build/contracts/AdharmaKeyRingImplementation.json"); -const DharmaUpgradeBeaconControllerManagerArtifact = require('../../build/contracts/DharmaUpgradeBeaconControllerManager.json') -const DharmaUpgradeBeaconControllerArtifact = require('../../build/contracts/DharmaUpgradeBeaconController.json') -const DharmaUpgradeBeaconArtifact = require('../../build/contracts/DharmaUpgradeBeacon.json') -const DharmaKeyRingUpgradeBeaconArtifact = require('../../build/contracts/DharmaKeyRingUpgradeBeacon.json') -const DharmaUpgradeBeaconEnvoyArtifact = require('../../build/contracts/DharmaUpgradeBeaconEnvoy.json') +const DharmaUpgradeBeaconControllerManagerArtifact = require("../../build/contracts/DharmaUpgradeBeaconControllerManager.json"); +const DharmaUpgradeBeaconControllerArtifact = require("../../build/contracts/DharmaUpgradeBeaconController.json"); +const DharmaUpgradeBeaconArtifact = require("../../build/contracts/DharmaUpgradeBeacon.json"); +const DharmaKeyRingUpgradeBeaconArtifact = require("../../build/contracts/DharmaKeyRingUpgradeBeacon.json"); +const DharmaUpgradeBeaconEnvoyArtifact = require("../../build/contracts/DharmaUpgradeBeaconEnvoy.json"); -const DharmaAccountRecoveryManagerV2Artifact = require('../../build/contracts/DharmaAccountRecoveryManagerV2.json') -const DharmaKeyRegistryV2Artifact = require('../../build/contracts/DharmaKeyRegistryV2.json') -const DharmaSmartWalletFactoryV1Artifact = require('../../build/contracts/DharmaSmartWalletFactoryV1.json') -const DharmaSmartWalletFactoryV2Artifact = require('../../build/contracts/DharmaSmartWalletFactoryV2.json') +const DharmaAccountRecoveryManagerV2Artifact = require("../../build/contracts/DharmaAccountRecoveryManagerV2.json"); +const DharmaKeyRegistryV2Artifact = require("../../build/contracts/DharmaKeyRegistryV2.json"); +const DharmaSmartWalletFactoryV1Artifact = require("../../build/contracts/DharmaSmartWalletFactoryV1.json"); +const DharmaSmartWalletFactoryV2Artifact = require("../../build/contracts/DharmaSmartWalletFactoryV2.json"); -const DharmaSmartWalletImplementationV6Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV6.json') -const DharmaSmartWalletImplementationV7Artifact = require('../../build/contracts/DharmaSmartWalletImplementationV7.json') +const DharmaSmartWalletImplementationV6Artifact = require("../../build/contracts/DharmaSmartWalletImplementationV6.json"); +const DharmaSmartWalletImplementationV7Artifact = require("../../build/contracts/DharmaSmartWalletImplementationV7.json"); -const DharmaKeyRingImplementationV1Artifact = require('../../build/contracts/DharmaKeyRingImplementationV1.json') -const DharmaKeyRingFactoryV1Artifact = require('../../build/contracts/DharmaKeyRingFactoryV1.json') -const DharmaKeyRingFactoryV2Artifact = require('../../build/contracts/DharmaKeyRingFactoryV2.json') -const DharmaKeyRingFactoryV3Artifact = require('../../build/contracts/DharmaKeyRingFactoryV3.json') +const DharmaKeyRingImplementationV1Artifact = require("../../build/contracts/DharmaKeyRingImplementationV1.json"); +const DharmaKeyRingFactoryV1Artifact = require("../../build/contracts/DharmaKeyRingFactoryV1.json"); +const DharmaKeyRingFactoryV2Artifact = require("../../build/contracts/DharmaKeyRingFactoryV2.json"); +const DharmaKeyRingFactoryV3Artifact = require("../../build/contracts/DharmaKeyRingFactoryV3.json"); -const UpgradeBeaconProxyV1Artifact = require('../../build/contracts/UpgradeBeaconProxyV1.json') -const KeyRingUpgradeBeaconProxyV1Artifact = require('../../build/contracts/KeyRingUpgradeBeaconProxyV1.json') +const UpgradeBeaconProxyV1Artifact = require("../../build/contracts/UpgradeBeaconProxyV1.json"); +const KeyRingUpgradeBeaconProxyV1Artifact = require("../../build/contracts/KeyRingUpgradeBeaconProxyV1.json"); -const DharmaUpgradeMultisigArtifact = require('../../build/contracts/DharmaUpgradeMultisig.json') -const DharmaAccountRecoveryMultisigArtifact = require('../../build/contracts/DharmaAccountRecoveryMultisig.json') -const DharmaAccountRecoveryOperatorMultisigArtifact = require('../../build/contracts/DharmaAccountRecoveryOperatorMultisig.json') -const DharmaKeyRegistryMultisigArtifact = require('../../build/contracts/DharmaKeyRegistryMultisig.json') +const DharmaUpgradeMultisigArtifact = require("../../build/contracts/DharmaUpgradeMultisig.json"); +const DharmaAccountRecoveryMultisigArtifact = require("../../build/contracts/DharmaAccountRecoveryMultisig.json"); +const DharmaAccountRecoveryOperatorMultisigArtifact = require("../../build/contracts/DharmaAccountRecoveryOperatorMultisig.json"); +const DharmaKeyRegistryMultisigArtifact = require("../../build/contracts/DharmaKeyRegistryMultisig.json"); -const DharmaEscapeHatchRegistryArtifact = require('../../build/contracts/DharmaEscapeHatchRegistry.json') +const DharmaEscapeHatchRegistryArtifact = require("../../build/contracts/DharmaEscapeHatchRegistry.json"); -const UpgradeBeaconImplementationCheckArtifact = require('../../build/contracts/UpgradeBeaconImplementationCheck.json') -const BadBeaconArtifact = require('../../build/contracts/BadBeacon.json') -const BadBeaconTwoArtifact = require('../../build/contracts/BadBeaconTwo.json') -const TimelockEdgecaseTesterArtifact = require('../../build/contracts/TimelockEdgecaseTester.json') +const UpgradeBeaconImplementationCheckArtifact = require("../../build/contracts/UpgradeBeaconImplementationCheck.json"); +const BadBeaconArtifact = require("../../build/contracts/BadBeacon.json"); +const BadBeaconTwoArtifact = require("../../build/contracts/BadBeaconTwo.json"); +const TimelockEdgecaseTesterArtifact = require("../../build/contracts/TimelockEdgecaseTester.json"); -const MockDharmaKeyRingFactoryArtifact = require('../../build/contracts/MockDharmaKeyRingFactory.json') -const IERC20Artifact = require('../../build/contracts/IERC20.json') +const MockDharmaKeyRingFactoryArtifact = require("../../build/contracts/MockDharmaKeyRingFactory.json"); +const IERC20Artifact = require("../../build/contracts/IERC20.json"); class Tester { constructor(testingContext) { @@ -54,32 +54,29 @@ class Tester { const UpgradeBeaconImplementationCheckDeployer = new web3.eth.Contract( UpgradeBeaconImplementationCheckArtifact.abi ); - UpgradeBeaconImplementationCheckDeployer.options.data = ( - UpgradeBeaconImplementationCheckArtifact.bytecode - ); - this.UpgradeBeaconImplementationCheckDeployer = ( - UpgradeBeaconImplementationCheckDeployer - ); + UpgradeBeaconImplementationCheckDeployer.options.data = + UpgradeBeaconImplementationCheckArtifact.bytecode; + this.UpgradeBeaconImplementationCheckDeployer = UpgradeBeaconImplementationCheckDeployer; } async init() { // get available addresses and assign them to various roles const addresses = await web3.eth.getAccounts(); if (addresses.length < 1) { - console.log('cannot find enough addresses to run tests!'); - process.exit(1) + console.log("cannot find enough addresses to run tests!"); + process.exit(1); } - let latestBlock = await web3.eth.getBlock('latest'); + let latestBlock = await web3.eth.getBlock("latest"); this.originalAddress = addresses[0]; this.address = await this.setupNewDefaultAddress( - '0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed' + "0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed" ); this.addressTwo = await this.setupNewDefaultAddress( - '0xf00df00df00df00df00df00df00df00df00df00df00df00df00df00df00df00d' + "0xf00df00df00df00df00df00df00df00df00df00df00df00df00df00df00df00d" ); this.ownerOne = await this.setupNewDefaultAddress( @@ -98,7 +95,7 @@ class Tester { constants.MOCK_OWNER_PRIVATE_KEYS[4] ); - this.gasLimit = latestBlock.gasLimit + this.gasLimit = latestBlock.gasLimit; const MockCodeCheckDeployer = new web3.eth.Contract( MockCodeCheckArtifact.abi @@ -108,39 +105,42 @@ class Tester { this.MockCodeCheck = await this.runTest( `MockCodeCheck contract deployment`, MockCodeCheckDeployer, - '', - 'deploy' - ) + "", + "deploy" + ); await this.runTest( - 'Deployed MockCodeCheck code is correct', + "Deployed MockCodeCheck code is correct", this.MockCodeCheck, - 'code', - 'call', + "code", + "call", [this.MockCodeCheck.options.address], true, value => { - assert.strictEqual(value, MockCodeCheckArtifact.deployedBytecode) + assert.strictEqual( + value, + MockCodeCheckArtifact.deployedBytecode + ); } - ) + ); await this.runTest( - 'Deployed MockCodeCheck has correct extcodehash', + "Deployed MockCodeCheck has correct extcodehash", this.MockCodeCheck, - 'hash', - 'call', + "hash", + "call", [this.MockCodeCheck.options.address], true, value => { - assert.strictEqual( - value, - web3.utils.keccak256( - MockCodeCheckArtifact.deployedBytecode, - {encoding: 'hex'} - ) - ) + assert.strictEqual( + value, + web3.utils.keccak256( + MockCodeCheckArtifact.deployedBytecode, + { encoding: "hex" } + ) + ); } - ) + ); await this.setupDeployedContracst(); } @@ -201,7 +201,7 @@ class Tester { if ( error.message === "Returned error: gas required exceeds allowance or always failing " + - "transaction" + "transaction" ) { await this.raiseGasLimit(); await this.getDeployGas(dataPayload); @@ -384,7 +384,7 @@ class Tester { web3.utils.keccak256( // prefix => "\x19Ethereum Signed Message:\n32" "0x19457468657265756d205369676e6564204d6573736167653a0a3332" + - hashedHexString.slice(2), + hashedHexString.slice(2), { encoding: "hex" } ) ), @@ -404,9 +404,9 @@ class Tester { web3.utils.keccak256( // prefix => "\x19Ethereum Signed Message:\n32" "0x19457468657265756d205369676e6564204d6573736167653a0a3332" + - web3.utils - .keccak256(hexString, { encoding: "hex" }) - .slice(2), + web3.utils + .keccak256(hexString, { encoding: "hex" }) + .slice(2), { encoding: "hex" } ) ), @@ -748,18 +748,18 @@ class Tester { console.log( ` ✓ ${ callOrSendOrDeploy === "deploy" ? "successful " : "" - }${title}${ + }${title}${ callOrSendOrDeploy === "deploy" ? ` (${deployGas} gas)` : "" - }` + }` ); this.passed++; } else { console.log( ` ✘ ${ callOrSendOrDeploy === "deploy" ? "failed " : "" - }${title}${ + }${title}${ callOrSendOrDeploy === "deploy" ? ` (${deployGas} gas)` : "" - }` + }` ); this.failed++; } @@ -822,7 +822,6 @@ class Tester { .filter(value => value !== null); } - async checkAndDeploy( name, address, @@ -836,8 +835,8 @@ class Tester { await this.runTest( `Checking ${name} runtime code`, mockCodeCheck, - 'code', - 'call', + "code", + "call", [address], true, value => { @@ -845,29 +844,24 @@ class Tester { } ); - if ( - currentCode !== runtimeCode - ) { + if (currentCode !== runtimeCode) { await this.runTest( `${name} contract address check through immutable create2 factory`, create2Factory, - 'findCreate2Address', - 'call', - [ - salt, - creationCode - ], + "findCreate2Address", + "call", + [salt, creationCode], true, value => { - assert.strictEqual(value, address) + assert.strictEqual(value, address); } ); await this.runTest( `${name} contract deployment through immutable create2 factory`, create2Factory, - 'safeCreate2', - 'send', + "safeCreate2", + "send", [salt, creationCode] ); } @@ -875,12 +869,12 @@ class Tester { await this.runTest( `Deployed ${name} code is correct`, mockCodeCheck, - 'code', - 'call', + "code", + "call", [address], true, value => { - assert.strictEqual(value, runtimeCode) + assert.strictEqual(value, runtimeCode); } ); } @@ -889,25 +883,25 @@ class Tester { this.DharmaUpgradeBeaconController = new web3.eth.Contract( DharmaUpgradeBeaconControllerArtifact.abi, constants.UPGRADE_BEACON_CONTROLLER_ADDRESS - ) + ); this.DharmaUpgradeBeacon = new web3.eth.Contract( DharmaUpgradeBeaconArtifact.abi, constants.UPGRADE_BEACON_ADDRESS - ) + ); this.DharmaKeyRingUpgradeBeaconController = new web3.eth.Contract( DharmaUpgradeBeaconControllerArtifact.abi, constants.KEY_RING_UPGRADE_BEACON_CONTROLLER_ADDRESS - ) + ); this.DharmaKeyRingUpgradeBeacon = new web3.eth.Contract( DharmaKeyRingUpgradeBeaconArtifact.abi, constants.KEY_RING_UPGRADE_BEACON_ADDRESS - ) + ); this.DharmaAccountRecoveryManagerV2 = new web3.eth.Contract( DharmaAccountRecoveryManagerV2Artifact.abi, constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS - ) + ); /* const DharmaKeyRegistryV1 = new web3.eth.Contract( @@ -919,292 +913,306 @@ class Tester { this.DharmaKeyRegistryV2 = new web3.eth.Contract( DharmaKeyRegistryV2Artifact.abi, constants.KEY_REGISTRY_V2_ADDRESS - ) + ); this.DharmaUpgradeBeaconControllerManager = new web3.eth.Contract( DharmaUpgradeBeaconControllerManagerArtifact.abi, constants.UPGRADE_BEACON_CONTROLLER_MANAGER_ADDRESS - ) + ); this.DharmaSmartWalletFactoryV1OnChain = new web3.eth.Contract( DharmaSmartWalletFactoryV1Artifact.abi, constants.FACTORY_ADDRESS - ) + ); this.Comptroller = new web3.eth.Contract( constants.COMPTROLLER_ABI, constants.COMPTROLLER_MAINNET_ADDRESS - ) + ); this.CSAI_BORROW = new web3.eth.Contract( - [{ - "constant": false, - "inputs": [{"name": "borrowAmount", "type": "uint256"}], - "name": "borrow", - "outputs": [{"name": "", "type": "uint256"}], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }], + [ + { + constant: false, + inputs: [{ name: "borrowAmount", type: "uint256" }], + name: "borrow", + outputs: [{ name: "", type: "uint256" }], + payable: false, + stateMutability: "nonpayable", + type: "function" + } + ], constants.CSAI_MAINNET_ADDRESS - ) + ); this.FIAT_TOKEN = new web3.eth.Contract( [ { - "constant": true, "inputs": [], "name": "blacklister", - "outputs": [{"name": "", "type": "address"}], "payable": false, - "stateMutability": "view", "type": "function" - }, { - "constant": false, "inputs": [{"name": "_account", "type": "address"}], - "name": "unBlacklist", "outputs": [], "payable": false, - "stateMutability": "nonpayable", "type": "function" - }, { - "constant": false, "inputs": [{"name": "_account", "type": "address"}], - "name": "blacklist", "outputs": [], "payable": false, - "stateMutability": "nonpayable", "type": "function" - }, { - "constant": true, "inputs": [{"name": "_account", "type": "address"}], - "name": "isBlacklisted", "outputs": [{"name": "", "type": "bool"}], - "payable": false, "stateMutability": "view", "type": "function" - }, { - "constant": false, "inputs": [], - "name": "pause", "outputs": [], "payable": false, - "stateMutability": "nonpayable", "type": "function" - }, { - "constant": false, "inputs": [], - "name": "unpause", "outputs": [], "payable": false, - "stateMutability": "nonpayable", "type": "function" - }, { - "constant": true, "inputs": [], "name": "pauser", - "outputs": [{"name": "", "type": "address"}], "payable": false, - "stateMutability": "view", "type": "function" - } + constant: true, + inputs: [], + name: "blacklister", + outputs: [{ name: "", type: "address" }], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [{ name: "_account", type: "address" }], + name: "unBlacklist", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [{ name: "_account", type: "address" }], + name: "blacklist", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [{ name: "_account", type: "address" }], + name: "isBlacklisted", + outputs: [{ name: "", type: "bool" }], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [], + name: "pause", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [], + name: "unpause", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "pauser", + outputs: [{ name: "", type: "address" }], + payable: false, + stateMutability: "view", + type: "function" + } ], constants.USDC_MAINNET_ADDRESS - ) + ); this.SAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.SAI_MAINNET_ADDRESS - ) + IERC20Artifact.abi, + constants.SAI_MAINNET_ADDRESS + ); this.DAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.DAI_MAINNET_ADDRESS - ) + IERC20Artifact.abi, + constants.DAI_MAINNET_ADDRESS + ); this.USDC = new web3.eth.Contract( - IERC20Artifact.abi, constants.USDC_MAINNET_ADDRESS - ) + IERC20Artifact.abi, + constants.USDC_MAINNET_ADDRESS + ); this.CSAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.CSAI_MAINNET_ADDRESS - ) + IERC20Artifact.abi, + constants.CSAI_MAINNET_ADDRESS + ); this.CDAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.CDAI_MAINNET_ADDRESS - ) + IERC20Artifact.abi, + constants.CDAI_MAINNET_ADDRESS + ); this.CUSDC = new web3.eth.Contract( - IERC20Artifact.abi, constants.CUSDC_MAINNET_ADDRESS - ) - - this.BadBeaconDeployer = new web3.eth.Contract(BadBeaconArtifact.abi) - this.BadBeaconDeployer.options.data = BadBeaconArtifact.bytecode + IERC20Artifact.abi, + constants.CUSDC_MAINNET_ADDRESS + ); - this.BadBeaconTwoDeployer = new web3.eth.Contract(BadBeaconTwoArtifact.abi) - this.BadBeaconTwoDeployer.options.data = BadBeaconTwoArtifact.bytecode + this.BadBeaconDeployer = new web3.eth.Contract(BadBeaconArtifact.abi); + this.BadBeaconDeployer.options.data = BadBeaconArtifact.bytecode; + this.BadBeaconTwoDeployer = new web3.eth.Contract( + BadBeaconTwoArtifact.abi + ); + this.BadBeaconTwoDeployer.options.data = BadBeaconTwoArtifact.bytecode; this.AdharmaSmartWalletImplementationDeployer = new web3.eth.Contract( AdharmaSmartWalletImplementationArtifact.abi - ) - this.AdharmaSmartWalletImplementationDeployer.options.data = ( - AdharmaSmartWalletImplementationArtifact.bytecode - ) + ); + this.AdharmaSmartWalletImplementationDeployer.options.data = + AdharmaSmartWalletImplementationArtifact.bytecode; this.DharmaSmartWalletImplementationV6Deployer = new web3.eth.Contract( DharmaSmartWalletImplementationV6Artifact.abi - ) - this.DharmaSmartWalletImplementationV6Deployer.options.data = ( - DharmaSmartWalletImplementationV6Artifact.bytecode - ) + ); + this.DharmaSmartWalletImplementationV6Deployer.options.data = + DharmaSmartWalletImplementationV6Artifact.bytecode; this.DharmaSmartWalletImplementationV7Deployer = new web3.eth.Contract( DharmaSmartWalletImplementationV7Artifact.abi - ) - this.DharmaSmartWalletImplementationV7Deployer.options.data = ( - DharmaSmartWalletImplementationV7Artifact.bytecode - ) + ); + this.DharmaSmartWalletImplementationV7Deployer.options.data = + DharmaSmartWalletImplementationV7Artifact.bytecode; this.AdharmaKeyRingImplementationDeployer = new web3.eth.Contract( AdharmaKeyRingImplementationArtifact.abi - ) - this.AdharmaKeyRingImplementationDeployer.options.data = ( - AdharmaKeyRingImplementationArtifact.bytecode - ) + ); + this.AdharmaKeyRingImplementationDeployer.options.data = + AdharmaKeyRingImplementationArtifact.bytecode; this.DharmaKeyRingImplementationV1Deployer = new web3.eth.Contract( DharmaKeyRingImplementationV1Artifact.abi - ) - this.DharmaKeyRingImplementationV1Deployer.options.data = ( - DharmaKeyRingImplementationV1Artifact.bytecode - ) + ); + this.DharmaKeyRingImplementationV1Deployer.options.data = + DharmaKeyRingImplementationV1Artifact.bytecode; this.UpgradeBeaconImplementationCheckDeployer = new web3.eth.Contract( UpgradeBeaconImplementationCheckArtifact.abi - ) - this.UpgradeBeaconImplementationCheckDeployer.options.data = ( - UpgradeBeaconImplementationCheckArtifact.bytecode - ) + ); + this.UpgradeBeaconImplementationCheckDeployer.options.data = + UpgradeBeaconImplementationCheckArtifact.bytecode; this.TimelockEdgecaseTesterDeployer = new web3.eth.Contract( TimelockEdgecaseTesterArtifact.abi - ) - this.TimelockEdgecaseTesterDeployer.options.data = ( - TimelockEdgecaseTesterArtifact.bytecode - ) + ); + this.TimelockEdgecaseTesterDeployer.options.data = + TimelockEdgecaseTesterArtifact.bytecode; this.DharmaUpgradeBeaconControllerDeployer = new web3.eth.Contract( DharmaUpgradeBeaconControllerArtifact.abi - ) - this.DharmaUpgradeBeaconControllerDeployer.options.data = ( - DharmaUpgradeBeaconControllerArtifact.bytecode - ) + ); + this.DharmaUpgradeBeaconControllerDeployer.options.data = + DharmaUpgradeBeaconControllerArtifact.bytecode; this.DharmaUpgradeBeaconDeployer = new web3.eth.Contract( DharmaUpgradeBeaconArtifact.abi - ) - this.DharmaUpgradeBeaconDeployer.options.data = ( - DharmaUpgradeBeaconArtifact.bytecode - ) + ); + this.DharmaUpgradeBeaconDeployer.options.data = + DharmaUpgradeBeaconArtifact.bytecode; this.DharmaKeyRingUpgradeBeaconDeployer = new web3.eth.Contract( DharmaKeyRingUpgradeBeaconArtifact.abi - ) - this.DharmaKeyRingUpgradeBeaconDeployer.options.data = ( - DharmaKeyRingUpgradeBeaconArtifact.bytecode - ) + ); + this.DharmaKeyRingUpgradeBeaconDeployer.options.data = + DharmaKeyRingUpgradeBeaconArtifact.bytecode; this.DharmaUpgradeBeaconEnvoyDeployer = new web3.eth.Contract( DharmaUpgradeBeaconEnvoyArtifact.abi - ) - this.DharmaUpgradeBeaconEnvoyDeployer.options.data = ( - DharmaUpgradeBeaconEnvoyArtifact.bytecode - ) + ); + this.DharmaUpgradeBeaconEnvoyDeployer.options.data = + DharmaUpgradeBeaconEnvoyArtifact.bytecode; this.DharmaUpgradeBeaconControllerManagerDeployer = new web3.eth.Contract( DharmaUpgradeBeaconControllerManagerArtifact.abi - ) - this.DharmaUpgradeBeaconControllerManagerDeployer.options.data = ( - DharmaUpgradeBeaconControllerManagerArtifact.bytecode - ) + ); + this.DharmaUpgradeBeaconControllerManagerDeployer.options.data = + DharmaUpgradeBeaconControllerManagerArtifact.bytecode; this.UpgradeBeaconProxyV1Deployer = new web3.eth.Contract( UpgradeBeaconProxyV1Artifact.abi - ) - this.UpgradeBeaconProxyV1Deployer.options.data = ( - UpgradeBeaconProxyV1Artifact.bytecode - ) + ); + this.UpgradeBeaconProxyV1Deployer.options.data = + UpgradeBeaconProxyV1Artifact.bytecode; this.KeyRingUpgradeBeaconProxyV1Deployer = new web3.eth.Contract( KeyRingUpgradeBeaconProxyV1Artifact.abi - ) - this.KeyRingUpgradeBeaconProxyV1Deployer.options.data = ( - KeyRingUpgradeBeaconProxyV1Artifact.bytecode - ) + ); + this.KeyRingUpgradeBeaconProxyV1Deployer.options.data = + KeyRingUpgradeBeaconProxyV1Artifact.bytecode; this.DharmaKeyRegistryV2Deployer = new web3.eth.Contract( DharmaKeyRegistryV2Artifact.abi - ) - this.DharmaKeyRegistryV2Deployer.options.data = ( - DharmaKeyRegistryV2Artifact.bytecode - ) + ); + this.DharmaKeyRegistryV2Deployer.options.data = + DharmaKeyRegistryV2Artifact.bytecode; this.DharmaSmartWalletFactoryV1Deployer = new web3.eth.Contract( DharmaSmartWalletFactoryV1Artifact.abi - ) - this.DharmaSmartWalletFactoryV1Deployer.options.data = ( - DharmaSmartWalletFactoryV1Artifact.bytecode - ) + ); + this.DharmaSmartWalletFactoryV1Deployer.options.data = + DharmaSmartWalletFactoryV1Artifact.bytecode; this.DharmaSmartWalletFactoryV2Deployer = new web3.eth.Contract( DharmaSmartWalletFactoryV2Artifact.abi - ) - this.DharmaSmartWalletFactoryV2Deployer.options.data = ( - DharmaSmartWalletFactoryV2Artifact.bytecode - ) + ); + this.DharmaSmartWalletFactoryV2Deployer.options.data = + DharmaSmartWalletFactoryV2Artifact.bytecode; this.DharmaKeyRingFactoryV1Deployer = new web3.eth.Contract( DharmaKeyRingFactoryV1Artifact.abi - ) - this.DharmaKeyRingFactoryV1Deployer.options.data = ( - DharmaKeyRingFactoryV1Artifact.bytecode - ) + ); + this.DharmaKeyRingFactoryV1Deployer.options.data = + DharmaKeyRingFactoryV1Artifact.bytecode; this.DharmaKeyRingFactoryV2Deployer = new web3.eth.Contract( DharmaKeyRingFactoryV2Artifact.abi - ) - this.DharmaKeyRingFactoryV2Deployer.options.data = ( - DharmaKeyRingFactoryV2Artifact.bytecode - ) + ); + this.DharmaKeyRingFactoryV2Deployer.options.data = + DharmaKeyRingFactoryV2Artifact.bytecode; this.DharmaKeyRingFactoryV3Deployer = new web3.eth.Contract( DharmaKeyRingFactoryV3Artifact.abi - ) - this.DharmaKeyRingFactoryV3Deployer.options.data = ( - DharmaKeyRingFactoryV3Artifact.bytecode - ) + ); + this.DharmaKeyRingFactoryV3Deployer.options.data = + DharmaKeyRingFactoryV3Artifact.bytecode; this.MockDharmaKeyRingFactoryDeployer = new web3.eth.Contract( MockDharmaKeyRingFactoryArtifact.abi - ) - this.MockDharmaKeyRingFactoryDeployer.options.data = ( - MockDharmaKeyRingFactoryArtifact.bytecode - ) + ); + this.MockDharmaKeyRingFactoryDeployer.options.data = + MockDharmaKeyRingFactoryArtifact.bytecode; this.DharmaAccountRecoveryManagerV2Deployer = new web3.eth.Contract( DharmaAccountRecoveryManagerV2Artifact.abi - ) - this.DharmaAccountRecoveryManagerV2Deployer.options.data = ( - DharmaAccountRecoveryManagerV2Artifact.bytecode - ) + ); + this.DharmaAccountRecoveryManagerV2Deployer.options.data = + DharmaAccountRecoveryManagerV2Artifact.bytecode; this.DharmaUpgradeMultisigDeployer = new web3.eth.Contract( DharmaUpgradeMultisigArtifact.abi - ) - this.DharmaUpgradeMultisigDeployer.options.data = ( - DharmaUpgradeMultisigArtifact.bytecode - ) + ); + this.DharmaUpgradeMultisigDeployer.options.data = + DharmaUpgradeMultisigArtifact.bytecode; this.DharmaAccountRecoveryMultisigDeployer = new web3.eth.Contract( DharmaAccountRecoveryMultisigArtifact.abi - ) - this.DharmaAccountRecoveryMultisigDeployer.options.data = ( - DharmaAccountRecoveryMultisigArtifact.bytecode - ) + ); + this.DharmaAccountRecoveryMultisigDeployer.options.data = + DharmaAccountRecoveryMultisigArtifact.bytecode; this.DharmaAccountRecoveryOperatorMultisigDeployer = new web3.eth.Contract( DharmaAccountRecoveryOperatorMultisigArtifact.abi - ) - this.DharmaAccountRecoveryOperatorMultisigDeployer.options.data = ( - DharmaAccountRecoveryOperatorMultisigArtifact.bytecode - ) + ); + this.DharmaAccountRecoveryOperatorMultisigDeployer.options.data = + DharmaAccountRecoveryOperatorMultisigArtifact.bytecode; this.DharmaKeyRegistryMultisigDeployer = new web3.eth.Contract( DharmaKeyRegistryMultisigArtifact.abi - ) - this.DharmaKeyRegistryMultisigDeployer.options.data = ( - DharmaKeyRegistryMultisigArtifact.bytecode - ) + ); + this.DharmaKeyRegistryMultisigDeployer.options.data = + DharmaKeyRegistryMultisigArtifact.bytecode; this.DharmaEscapeHatchRegistryDeployer = new web3.eth.Contract( DharmaEscapeHatchRegistryArtifact.abi - ) - this.DharmaEscapeHatchRegistryDeployer.options.data = ( - DharmaEscapeHatchRegistryArtifact.bytecode - ) - - + ); + this.DharmaEscapeHatchRegistryDeployer.options.data = + DharmaEscapeHatchRegistryArtifact.bytecode; } } @@ -1212,49 +1220,49 @@ function swapMetadataHash(bytecode, newMetadataHashes) { const totalBzzrs = bytecode.split(constants.METADATA_IDENTIFIER).length - 1; if (totalBzzrs !== newMetadataHashes.length) { - throw("number of metadata hashes to replace must match provided number."); + throw "number of metadata hashes to replace must match provided number."; } let startingPoint = bytecode.length - 1; for (let i = 0; i < totalBzzrs; i++) { - let replacement = constants.METADATA_IDENTIFIER + newMetadataHashes.slice(i)[0]; + let replacement = + constants.METADATA_IDENTIFIER + newMetadataHashes.slice(i)[0]; let lastIndex = bytecode.lastIndexOf( - constants.METADATA_IDENTIFIER, startingPoint - ); - bytecode = ( - bytecode.slice(0, lastIndex) + replacement + bytecode.slice( - lastIndex + replacement.length, bytecode.length - ) + constants.METADATA_IDENTIFIER, + startingPoint ); + bytecode = + bytecode.slice(0, lastIndex) + + replacement + + bytecode.slice(lastIndex + replacement.length, bytecode.length); startingPoint = lastIndex - 1; } return bytecode; } function newContractAndSwapMetadataHash(artifact) { - const contract = new web3.eth.Contract( - artifact.abi - ); - - contract.options.data = ( - swapMetadataHash( - artifact.bytecode, - ['0000000000000000000000000000000000000000000000000000000000000000'] - ) - ); + const contract = new web3.eth.Contract(artifact.abi); + + contract.options.data = swapMetadataHash(artifact.bytecode, [ + "0000000000000000000000000000000000000000000000000000000000000000" + ]); return contract; } // used to wait for more confirmations function longer() { - return new Promise(resolve => {setTimeout(() => {resolve()}, 500)}) + return new Promise(resolve => { + setTimeout(() => { + resolve(); + }, 500); + }); } module.exports = { Tester, swapMetadataHash, newContractAndSwapMetadataHash, - longer, + longer }; diff --git a/scripts/test/web3.js b/scripts/test/web3.js index 0522704..30ad0c2 100644 --- a/scripts/test/web3.js +++ b/scripts/test/web3.js @@ -1,11 +1,11 @@ const context = process.env.TESTING_CONTEXT; -const connectionConfig = require('../../truffle-config.js'); +const connectionConfig = require("../../truffle-config.js"); const connection = connectionConfig.networks[context]; const web3 = connection.provider; module.exports = { - web3, -}; \ No newline at end of file + web3 +}; From 0479e7ba96f82f6b80779aa5a0df230a2a992230 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Fri, 7 Feb 2020 22:53:57 -0500 Subject: [PATCH 30/47] expand coverage on DSWv7 --- scripts/test/test.js | 179 +++++++++++++++++++++++++++++++++---------- 1 file changed, 137 insertions(+), 42 deletions(-) diff --git a/scripts/test/test.js b/scripts/test/test.js index 579ec57..d584771 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -841,19 +841,6 @@ async function test(testingContext) { [UserSmartWalletV6.options.address, web3.utils.toWei("0.5", "mwei")] ); - await tester.runTest( - "V6 UserSmartWallet relay can trigger cSai to cDai migration before cDai approval", - UserSmartWalletV6, - "migrateCSaiToCDai", - "send", - [], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ); - await tester.runTest( "V6 UserSmartWallet can get next custom action ID", UserSmartWalletV6, @@ -3617,27 +3604,6 @@ async function test(testingContext) { } ); - await tester.runTest( - "cSai can be sent to V7 UserSmartWallet", - tester.CSAI, - "transfer", - "send", - [UserSmartWalletV7.options.address, web3.utils.toWei("0.5", "mwei")] - ); - - await tester.runTest( - "V7 UserSmartWallet relay can trigger cSai to dDai migration before dDai approval", - UserSmartWalletV7, - "migrateCSaiToDDai", - "send", - [], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress - ); - await tester.runTest( "V7 UserSmartWallet can get next custom action ID", UserSmartWalletV7, @@ -6390,9 +6356,17 @@ async function test(testingContext) { ); await tester.runTest( - "V7 UserSmartWallet relay can trigger sai to dai migration as a no-op", + "cSai can be sent to V7 UserSmartWallet", + tester.CSAI, + "transfer", + "send", + [UserSmartWalletV7.options.address, web3.utils.toWei("1", "mwei")] + ); + + await tester.runTest( + "V7 UserSmartWallet relay can trigger cSai to dDai migration", UserSmartWalletV7, - "migrateSaiToDai", + "migrateCSaiToDDai", "send", [], true, @@ -6403,7 +6377,7 @@ async function test(testingContext) { ); await tester.runTest( - "V7 UserSmartWallet relay can trigger cSai to dDai migration as a no-op", + "V7 UserSmartWallet relay can trigger cSai to dDai migration again (no-op)", UserSmartWalletV7, "migrateCSaiToDDai", "send", @@ -6416,11 +6390,79 @@ async function test(testingContext) { ); await tester.runTest( - "cSai can be sent to V7 UserSmartWallet", - tester.CSAI, + "cDai can be sent to V7 UserSmartWallet", + tester.CDAI, + "transfer", + "send", + [UserSmartWalletV7.options.address, web3.utils.toWei("1", "mwei")] + ); + + await tester.runTest( + "V7 UserSmartWallet relay can trigger cDai to dDai migration", + UserSmartWalletV7, + "migrateCDaiToDDai", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "cDai can be sent to V7 UserSmartWallet again", + tester.CDAI, + "transfer", + "send", + [UserSmartWalletV7.options.address, web3.utils.toWei("1", "mwei")] + ); + + await tester.runTest( + "V7 UserSmartWallet relay can trigger cDai to dDai migration again", + UserSmartWalletV7, + "migrateCDaiToDDai", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "cUSDC can be sent to V7 UserSmartWallet", + tester.CUSDC, "transfer", "send", - [UserSmartWalletV7.options.address, web3.utils.toWei("0.5", "mwei")] + [UserSmartWalletV7.options.address, web3.utils.toWei("1", "lovelace")] + ); + + await tester.runTest( + "V7 UserSmartWallet relay can trigger cUSDC to dUSDC migration", + UserSmartWalletV7, + "migrateCUSDCToDUSDC", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + + await tester.runTest( + "V7 UserSmartWallet relay can trigger cUSDC to dUSDC migration again (no-op)", + UserSmartWalletV7, + "migrateCUSDCToDUSDC", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress ); await tester.runTest( @@ -6449,6 +6491,58 @@ async function test(testingContext) { constants.SAI_WHALE_ADDRESS ); + await tester.runTest( + "Dai Whale can deposit dai into the V7 user smart wallet", + tester.DAI, + "transfer", + "send", + [UserSmartWalletV7.options.address, web3.utils.toWei("1", "ether")], + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.DAI_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + UserSmartWalletV7.options.address + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("1", "ether") + ); + } + }, + constants.DAI_WHALE_ADDRESS + ); + + await tester.runTest( + "USDC Whale can deposit usdc into the V7 user smart wallet", + tester.USDC, + "transfer", + "send", + [UserSmartWalletV7.options.address, web3.utils.toWei("1", "lovelace")], + true, + receipt => { + if (testingContext !== "coverage") { + assert.strictEqual( + receipt.events.Transfer.returnValues.from, + constants.USDC_WHALE_ADDRESS + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.to, + UserSmartWalletV7.options.address + ); + assert.strictEqual( + receipt.events.Transfer.returnValues.value, + web3.utils.toWei("1", "lovelace") + ); + } + }, + constants.USDC_WHALE_ADDRESS + ); + await tester.runTest( "V7 UserSmartWallet relay can trigger sai to dai migration", UserSmartWalletV7, @@ -6463,9 +6557,9 @@ async function test(testingContext) { ); await tester.runTest( - "V7 UserSmartWallet relay can trigger cSai to dDai migration", + "V7 UserSmartWallet relay can trigger sai to dai migration again (no-op)", UserSmartWalletV7, - "migrateCSaiToDDai", + "migrateSaiToDai", "send", [], true, @@ -6475,6 +6569,7 @@ async function test(testingContext) { tester.originalAddress ); + // Initiate account recovery await tester.runTest( "smart wallet account recovery can be initiated", From afb926ae573382b16812e023d405a02c049fb7cd Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Sun, 9 Feb 2020 02:20:55 -0500 Subject: [PATCH 31/47] add BalanceChecker and expand coverage --- .solcover.js | 9 +---- contracts/test/BalanceChecker.sol | 63 +++++++++++++++++++++++++++++++ scripts/test/test.js | 25 +++++++++++- scripts/test/testHelpers.js | 50 ++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 contracts/test/BalanceChecker.sol diff --git a/.solcover.js b/.solcover.js index 082f5cd..dbe79aa 100644 --- a/.solcover.js +++ b/.solcover.js @@ -5,7 +5,6 @@ module.exports = { copyPackages: ['web3'], skipFiles: [ 'account-recovery/DharmaAccountRecoveryManager.sol', - //'account-recovery/DharmaAccountRecoveryManagerV2.sol', 'factories/key-ring/DharmaKeyRingFactoryV3.sol', 'factories/smart-wallet/DharmaSmartWalletFactoryV2.sol', 'helpers/CodeHashCache.sol', @@ -15,12 +14,8 @@ module.exports = { 'helpers/IndestructibleRegistry.sol', 'helpers/SmartWalletRevertReasonHelperV1.sol', 'helpers/SmartWalletFactoryV1UserSigningKeyUpdater.sol', - //'helpers/Timelocker.sol', - //'helpers/TimelockerV2.sol', - //'implementations/key-ring/AdharmaKeyRingImplementation.sol', 'implementations/key-ring/DharmaKeyRingImplementationV0.sol', 'implementations/key-ring/DharmaKeyRingImplementationV2.sol', - //'implementations/smart-wallet/AdharmaSmartWalletImplementation.sol', 'implementations/smart-wallet/DharmaSmartWalletImplementationV0.sol', 'implementations/smart-wallet/DharmaSmartWalletImplementationV1.sol', 'implementations/smart-wallet/DharmaSmartWalletImplementationV2.sol', @@ -41,9 +36,6 @@ module.exports = { 'mock/MockCodeCheck.sol', 'mock/RelayContract.sol', 'mock/RelayContractV2.sol', - //'multisigs/DharmaUpgradeMultisig.sol', - //'multisigs/DharmaKeyRegistryMultisig.sol', - //'multisigs/DharmaAccountRecoveryOperatorMultisig.sol', 'openzeppelin-upgradeability/cryptography/ECDSA.sol', 'openzeppelin-upgradeability/ownership/Ownable.sol', 'openzeppelin-upgradeability/upgradeability/AdminUpgradeabilityProxy.sol', @@ -58,6 +50,7 @@ module.exports = { 'registries/DharmaKeyRegistryV1.sol', 'test/BadBeacon.sol', 'test/BadBeaconTwo.sol', + 'test/BalanceChecker.sol', 'test/MockDharmaKeyRingFactory.sol', 'test/DharmaTestingMultisig.sol', 'test/MockAdharmaKeyRingFactory.sol', diff --git a/contracts/test/BalanceChecker.sol b/contracts/test/BalanceChecker.sol new file mode 100644 index 0000000..6bc4c35 --- /dev/null +++ b/contracts/test/BalanceChecker.sol @@ -0,0 +1,63 @@ +pragma solidity 0.5.11; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + + +/** + * @title BalanceChecker + */ +contract BalanceChecker { + IERC20 internal constant _DDAI = IERC20( + 0x00000000001876eB1444c986fD502e618c587430 // mainnet + ); + + IERC20 internal constant _DUSDC = IERC20( + 0x00000000008943c65cAf789FFFCF953bE156f6f8 // mainnet + ); + + IERC20 internal constant _DAI = IERC20( + 0x6B175474E89094C44Da98b954EedeAC495271d0F // mainnet + ); + + IERC20 internal constant _USDC = IERC20( + 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 // mainnet + ); + + IERC20 internal constant _SAI = IERC20( + 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359 // mainnet + ); + + IERC20 internal constant _CSAI = IERC20( + 0xF5DCe57282A584D2746FaF1593d3121Fcac444dC // mainnet + ); + + IERC20 internal constant _CDAI = IERC20( + 0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643 // mainnet + ); + + IERC20 internal constant _CUSDC = IERC20( + 0x39AA39c021dfbaE8faC545936693aC917d5E7563 // mainnet + ); + + function getBalances(address wallet) external view returns ( + uint256 dDaiBalance, + uint256 dUSDCBalance, + uint256 daiBalance, + uint256 usdcBalance, + uint256 saiBalance, + uint256 cSaiBalance, + uint256 cDaiBalance, + uint256 cUSDCBalance, + uint256 etherBalance + ) { + dDaiBalance = _DDAI.balanceOf(wallet); + dUSDCBalance = _DUSDC.balanceOf(wallet); + daiBalance = _DAI.balanceOf(wallet); + usdcBalance = _USDC.balanceOf(wallet); + saiBalance = _SAI.balanceOf(wallet); + cSaiBalance = _CSAI.balanceOf(wallet); + cDaiBalance = _CDAI.balanceOf(wallet); + cUSDCBalance = _CUSDC.balanceOf(wallet); + etherBalance = wallet.balance; + } +} \ No newline at end of file diff --git a/scripts/test/test.js b/scripts/test/test.js index d584771..49b1e95 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -6210,6 +6210,8 @@ async function test(testingContext) { tester.address ); + + await tester.runTest( "V7 UserSmartWallet escape hatch account can call escape again", UserSmartWalletV7, @@ -6355,14 +6357,33 @@ async function test(testingContext) { tester.originalAddress ); + await tester.runTest( + "grant allowance in order to mint cSai", + tester.SAI, + "approve", + "send", + [tester.CSAI.options.address, web3.utils.toWei('100', 'ether')] + ); + + await tester.runTest( + "mint cSai", + tester.CSAI_MINT, + "mint", + "send", + [web3.utils.toWei('100', 'ether')] + ); + await tester.runTest( "cSai can be sent to V7 UserSmartWallet", tester.CSAI, "transfer", "send", - [UserSmartWalletV7.options.address, web3.utils.toWei("1", "mwei")] + [UserSmartWalletV7.options.address, web3.utils.toWei("1", "gwei")] ); + const walletBalance = await tester.getBalances(UserSmartWalletV7.options.address); + assert.strictEqual(walletBalance.cSai, 10.0); + await tester.runTest( "V7 UserSmartWallet relay can trigger cSai to dDai migration", UserSmartWalletV7, @@ -6810,7 +6831,7 @@ async function test(testingContext) { ); await tester.runTest( - `KeyRingInstance can does not verify a bad signature`, + `KeyRingInstance does not verify a bad signature`, KeyRingInstance, "isValidSignature", "call", diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index c9b0af5..38e48a8 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -44,6 +44,8 @@ const TimelockEdgecaseTesterArtifact = require("../../build/contracts/TimelockEd const MockDharmaKeyRingFactoryArtifact = require("../../build/contracts/MockDharmaKeyRingFactory.json"); const IERC20Artifact = require("../../build/contracts/IERC20.json"); +const CTokenInterfaceArtifact = require("../../build/contracts/CTokenInterface.json"); +const BalanceCheckerArtifact = require("../../build/contracts/BalanceChecker.json"); class Tester { constructor(testingContext) { @@ -97,6 +99,18 @@ class Tester { this.gasLimit = latestBlock.gasLimit; + const BalanceCheckerDeployer = new web3.eth.Contract( + BalanceCheckerArtifact.abi + ); + BalanceCheckerDeployer.options.data = BalanceCheckerArtifact.bytecode; + + this.BalanceChecker = await this.runTest( + `BalanceChecker contract deployment`, + BalanceCheckerDeployer, + "", + "deploy" + ); + const MockCodeCheckDeployer = new web3.eth.Contract( MockCodeCheckArtifact.abi ); @@ -769,6 +783,37 @@ class Tester { } } + async getBalances(account) { + const balances = await this.BalanceChecker.methods.getBalances(account) + .call() + .catch(error => { + console.error(error); + process.exit(1); + }); + + return { + account, + dDai: parseFloat(web3.utils.fromWei(balances.dDaiBalance, 'gwei')) * 10, + dUSDC: parseFloat(web3.utils.fromWei(balances.dUSDCBalance, 'gwei')) * 10, + dai: parseFloat(web3.utils.fromWei(balances.daiBalance, 'ether')), + usdc: parseFloat(web3.utils.fromWei(balances.usdcBalance, 'mwei')), + sai: parseFloat(web3.utils.fromWei(balances.saiBalance, 'ether')), + cSai: parseFloat(web3.utils.fromWei(balances.cSaiBalance, 'gwei')) * 10, + cDai: parseFloat(web3.utils.fromWei(balances.cDaiBalance, 'gwei')) * 10, + cUSDC: parseFloat(web3.utils.fromWei(balances.cUSDCBalance, 'gwei')) * 10, + ether: parseFloat(web3.utils.fromWei(balances.etherBalance, 'ether')), + dDaiRaw: balances.dDaiBalance, + dUSDCRaw: balances.dUSDCBalance, + daiRaw: balances.daiBalance, + usdcRaw: balances.usdcBalance, + saiRaw: balances.saiBalance, + cSaiRaw: balances.cSaiBalance, + cDaiRaw: balances.cDaiBalance, + cUSDCRaw: balances.cUSDCBalance, + etherRaw: balances.etherBalance + }; + } + getEvents(receipt, contractNames) { const { events } = receipt; @@ -1034,6 +1079,11 @@ class Tester { constants.CSAI_MAINNET_ADDRESS ); + this.CSAI_MINT = new web3.eth.Contract( + CTokenInterfaceArtifact.abi, + constants.CSAI_MAINNET_ADDRESS + ); + this.CDAI = new web3.eth.Contract( IERC20Artifact.abi, constants.CDAI_MAINNET_ADDRESS From 2647fca9f0ba1efde6f6620df5a18d7befb90b9e Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Sun, 9 Feb 2020 23:33:58 -0500 Subject: [PATCH 32/47] refactor deployer setup --- scripts/test/testHelpers.js | 208 ++++++++++++------------------------ 1 file changed, 71 insertions(+), 137 deletions(-) diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index 38e48a8..1fd25f0 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -156,7 +156,7 @@ class Tester { } ); - await this.setupDeployedContracst(); + await this.setupDeployedContracts(); } async setupNewDefaultAddress(newPrivateKey) { @@ -924,7 +924,13 @@ class Tester { ); } - async setupDeployedContracst() { + newDeployer(artifact) { + let deployer = new web3.eth.Contract(artifact.abi); + deployer.options.data = artifact.bytecode; + return deployer; + } + + async setupDeployedContracts() { this.DharmaUpgradeBeaconController = new web3.eth.Contract( DharmaUpgradeBeaconControllerArtifact.abi, constants.UPGRADE_BEACON_CONTROLLER_ADDRESS @@ -948,13 +954,6 @@ class Tester { constants.ACCOUNT_RECOVERY_MANAGER_V2_ADDRESS ); - /* - const DharmaKeyRegistryV1 = new web3.eth.Contract( - DharmaKeyRegistryV1Artifact.abi, - constants.KEY_REGISTRY_ADDRESS - ) - */ - this.DharmaKeyRegistryV2 = new web3.eth.Contract( DharmaKeyRegistryV2Artifact.abi, constants.KEY_REGISTRY_V2_ADDRESS @@ -1060,209 +1059,144 @@ class Tester { ); this.SAI = new web3.eth.Contract( - IERC20Artifact.abi, - constants.SAI_MAINNET_ADDRESS + IERC20Artifact.abi, constants.SAI_MAINNET_ADDRESS ); this.DAI = new web3.eth.Contract( - IERC20Artifact.abi, - constants.DAI_MAINNET_ADDRESS + IERC20Artifact.abi, constants.DAI_MAINNET_ADDRESS ); this.USDC = new web3.eth.Contract( - IERC20Artifact.abi, - constants.USDC_MAINNET_ADDRESS + IERC20Artifact.abi, constants.USDC_MAINNET_ADDRESS ); this.CSAI = new web3.eth.Contract( - IERC20Artifact.abi, - constants.CSAI_MAINNET_ADDRESS + IERC20Artifact.abi, constants.CSAI_MAINNET_ADDRESS ); this.CSAI_MINT = new web3.eth.Contract( - CTokenInterfaceArtifact.abi, - constants.CSAI_MAINNET_ADDRESS + CTokenInterfaceArtifact.abi, constants.CSAI_MAINNET_ADDRESS ); this.CDAI = new web3.eth.Contract( - IERC20Artifact.abi, - constants.CDAI_MAINNET_ADDRESS + IERC20Artifact.abi, constants.CDAI_MAINNET_ADDRESS ); this.CUSDC = new web3.eth.Contract( - IERC20Artifact.abi, - constants.CUSDC_MAINNET_ADDRESS + IERC20Artifact.abi, constants.CUSDC_MAINNET_ADDRESS ); - this.BadBeaconDeployer = new web3.eth.Contract(BadBeaconArtifact.abi); - this.BadBeaconDeployer.options.data = BadBeaconArtifact.bytecode; + this.BadBeaconDeployer = this.newDeployer(BadBeaconArtifact); - this.BadBeaconTwoDeployer = new web3.eth.Contract( - BadBeaconTwoArtifact.abi - ); - this.BadBeaconTwoDeployer.options.data = BadBeaconTwoArtifact.bytecode; + this.BadBeaconTwoDeployer = this.newDeployer(BadBeaconTwoArtifact); - this.AdharmaSmartWalletImplementationDeployer = new web3.eth.Contract( - AdharmaSmartWalletImplementationArtifact.abi + this.AdharmaSmartWalletImplementationDeployer = this.newDeployer( + AdharmaSmartWalletImplementationArtifact ); - this.AdharmaSmartWalletImplementationDeployer.options.data = - AdharmaSmartWalletImplementationArtifact.bytecode; - this.DharmaSmartWalletImplementationV6Deployer = new web3.eth.Contract( - DharmaSmartWalletImplementationV6Artifact.abi + this.DharmaSmartWalletImplementationV6Deployer = this.newDeployer( + DharmaSmartWalletImplementationV6Artifact ); - this.DharmaSmartWalletImplementationV6Deployer.options.data = - DharmaSmartWalletImplementationV6Artifact.bytecode; - this.DharmaSmartWalletImplementationV7Deployer = new web3.eth.Contract( - DharmaSmartWalletImplementationV7Artifact.abi + this.DharmaSmartWalletImplementationV7Deployer = this.newDeployer( + DharmaSmartWalletImplementationV7Artifact ); - this.DharmaSmartWalletImplementationV7Deployer.options.data = - DharmaSmartWalletImplementationV7Artifact.bytecode; - this.AdharmaKeyRingImplementationDeployer = new web3.eth.Contract( - AdharmaKeyRingImplementationArtifact.abi + this.AdharmaKeyRingImplementationDeployer = this.newDeployer( + AdharmaKeyRingImplementationArtifact ); - this.AdharmaKeyRingImplementationDeployer.options.data = - AdharmaKeyRingImplementationArtifact.bytecode; - this.DharmaKeyRingImplementationV1Deployer = new web3.eth.Contract( - DharmaKeyRingImplementationV1Artifact.abi + this.DharmaKeyRingImplementationV1Deployer = this.newDeployer( + DharmaKeyRingImplementationV1Artifact ); - this.DharmaKeyRingImplementationV1Deployer.options.data = - DharmaKeyRingImplementationV1Artifact.bytecode; - this.UpgradeBeaconImplementationCheckDeployer = new web3.eth.Contract( - UpgradeBeaconImplementationCheckArtifact.abi + this.UpgradeBeaconImplementationCheckDeployer = this.newDeployer( + UpgradeBeaconImplementationCheckArtifact ); - this.UpgradeBeaconImplementationCheckDeployer.options.data = - UpgradeBeaconImplementationCheckArtifact.bytecode; - this.TimelockEdgecaseTesterDeployer = new web3.eth.Contract( - TimelockEdgecaseTesterArtifact.abi + this.TimelockEdgecaseTesterDeployer = this.newDeployer( + TimelockEdgecaseTesterArtifact ); - this.TimelockEdgecaseTesterDeployer.options.data = - TimelockEdgecaseTesterArtifact.bytecode; - this.DharmaUpgradeBeaconControllerDeployer = new web3.eth.Contract( - DharmaUpgradeBeaconControllerArtifact.abi + this.DharmaUpgradeBeaconControllerDeployer = this.newDeployer( + DharmaUpgradeBeaconControllerArtifact ); - this.DharmaUpgradeBeaconControllerDeployer.options.data = - DharmaUpgradeBeaconControllerArtifact.bytecode; - this.DharmaUpgradeBeaconDeployer = new web3.eth.Contract( - DharmaUpgradeBeaconArtifact.abi + this.DharmaUpgradeBeaconDeployer = this.newDeployer( + DharmaUpgradeBeaconArtifact ); - this.DharmaUpgradeBeaconDeployer.options.data = - DharmaUpgradeBeaconArtifact.bytecode; - this.DharmaKeyRingUpgradeBeaconDeployer = new web3.eth.Contract( - DharmaKeyRingUpgradeBeaconArtifact.abi + this.DharmaKeyRingUpgradeBeaconDeployer = this.newDeployer( + DharmaKeyRingUpgradeBeaconArtifact ); - this.DharmaKeyRingUpgradeBeaconDeployer.options.data = - DharmaKeyRingUpgradeBeaconArtifact.bytecode; - this.DharmaUpgradeBeaconEnvoyDeployer = new web3.eth.Contract( - DharmaUpgradeBeaconEnvoyArtifact.abi + this.DharmaUpgradeBeaconEnvoyDeployer = this.newDeployer( + DharmaUpgradeBeaconEnvoyArtifact ); - this.DharmaUpgradeBeaconEnvoyDeployer.options.data = - DharmaUpgradeBeaconEnvoyArtifact.bytecode; - this.DharmaUpgradeBeaconControllerManagerDeployer = new web3.eth.Contract( - DharmaUpgradeBeaconControllerManagerArtifact.abi + this.DharmaUpgradeBeaconControllerManagerDeployer = this.newDeployer( + DharmaUpgradeBeaconControllerManagerArtifact ); - this.DharmaUpgradeBeaconControllerManagerDeployer.options.data = - DharmaUpgradeBeaconControllerManagerArtifact.bytecode; - this.UpgradeBeaconProxyV1Deployer = new web3.eth.Contract( - UpgradeBeaconProxyV1Artifact.abi + this.UpgradeBeaconProxyV1Deployer = this.newDeployer( + UpgradeBeaconProxyV1Artifact ); - this.UpgradeBeaconProxyV1Deployer.options.data = - UpgradeBeaconProxyV1Artifact.bytecode; - this.KeyRingUpgradeBeaconProxyV1Deployer = new web3.eth.Contract( - KeyRingUpgradeBeaconProxyV1Artifact.abi + this.KeyRingUpgradeBeaconProxyV1Deployer = this.newDeployer( + KeyRingUpgradeBeaconProxyV1Artifact ); - this.KeyRingUpgradeBeaconProxyV1Deployer.options.data = - KeyRingUpgradeBeaconProxyV1Artifact.bytecode; - this.DharmaKeyRegistryV2Deployer = new web3.eth.Contract( - DharmaKeyRegistryV2Artifact.abi + this.DharmaKeyRegistryV2Deployer = this.newDeployer( + DharmaKeyRegistryV2Artifact ); - this.DharmaKeyRegistryV2Deployer.options.data = - DharmaKeyRegistryV2Artifact.bytecode; - this.DharmaSmartWalletFactoryV1Deployer = new web3.eth.Contract( - DharmaSmartWalletFactoryV1Artifact.abi + this.DharmaSmartWalletFactoryV1Deployer = this.newDeployer( + DharmaSmartWalletFactoryV1Artifact ); - this.DharmaSmartWalletFactoryV1Deployer.options.data = - DharmaSmartWalletFactoryV1Artifact.bytecode; - this.DharmaSmartWalletFactoryV2Deployer = new web3.eth.Contract( - DharmaSmartWalletFactoryV2Artifact.abi + this.DharmaSmartWalletFactoryV2Deployer = this.newDeployer( + DharmaSmartWalletFactoryV2Artifact ); - this.DharmaSmartWalletFactoryV2Deployer.options.data = - DharmaSmartWalletFactoryV2Artifact.bytecode; - this.DharmaKeyRingFactoryV1Deployer = new web3.eth.Contract( - DharmaKeyRingFactoryV1Artifact.abi + this.DharmaKeyRingFactoryV1Deployer = this.newDeployer( + DharmaKeyRingFactoryV1Artifact ); - this.DharmaKeyRingFactoryV1Deployer.options.data = - DharmaKeyRingFactoryV1Artifact.bytecode; - this.DharmaKeyRingFactoryV2Deployer = new web3.eth.Contract( - DharmaKeyRingFactoryV2Artifact.abi + this.DharmaKeyRingFactoryV2Deployer = this.newDeployer( + DharmaKeyRingFactoryV2Artifact ); - this.DharmaKeyRingFactoryV2Deployer.options.data = - DharmaKeyRingFactoryV2Artifact.bytecode; - this.DharmaKeyRingFactoryV3Deployer = new web3.eth.Contract( - DharmaKeyRingFactoryV3Artifact.abi + this.DharmaKeyRingFactoryV3Deployer = this.newDeployer( + DharmaKeyRingFactoryV3Artifact ); - this.DharmaKeyRingFactoryV3Deployer.options.data = - DharmaKeyRingFactoryV3Artifact.bytecode; - this.MockDharmaKeyRingFactoryDeployer = new web3.eth.Contract( - MockDharmaKeyRingFactoryArtifact.abi + this.MockDharmaKeyRingFactoryDeployer = this.newDeployer( + MockDharmaKeyRingFactoryArtifact ); - this.MockDharmaKeyRingFactoryDeployer.options.data = - MockDharmaKeyRingFactoryArtifact.bytecode; - this.DharmaAccountRecoveryManagerV2Deployer = new web3.eth.Contract( - DharmaAccountRecoveryManagerV2Artifact.abi + this.DharmaAccountRecoveryManagerV2Deployer = this.newDeployer( + DharmaAccountRecoveryManagerV2Artifact ); - this.DharmaAccountRecoveryManagerV2Deployer.options.data = - DharmaAccountRecoveryManagerV2Artifact.bytecode; - this.DharmaUpgradeMultisigDeployer = new web3.eth.Contract( - DharmaUpgradeMultisigArtifact.abi + this.DharmaUpgradeMultisigDeployer = this.newDeployer( + DharmaUpgradeMultisigArtifact ); - this.DharmaUpgradeMultisigDeployer.options.data = - DharmaUpgradeMultisigArtifact.bytecode; - this.DharmaAccountRecoveryMultisigDeployer = new web3.eth.Contract( - DharmaAccountRecoveryMultisigArtifact.abi + this.DharmaAccountRecoveryMultisigDeployer = this.newDeployer( + DharmaAccountRecoveryMultisigArtifact ); - this.DharmaAccountRecoveryMultisigDeployer.options.data = - DharmaAccountRecoveryMultisigArtifact.bytecode; - this.DharmaAccountRecoveryOperatorMultisigDeployer = new web3.eth.Contract( - DharmaAccountRecoveryOperatorMultisigArtifact.abi + this.DharmaAccountRecoveryOperatorMultisigDeployer = this.newDeployer( + DharmaAccountRecoveryOperatorMultisigArtifact ); - this.DharmaAccountRecoveryOperatorMultisigDeployer.options.data = - DharmaAccountRecoveryOperatorMultisigArtifact.bytecode; - this.DharmaKeyRegistryMultisigDeployer = new web3.eth.Contract( - DharmaKeyRegistryMultisigArtifact.abi + this.DharmaKeyRegistryMultisigDeployer = this.newDeployer( + DharmaKeyRegistryMultisigArtifact ); - this.DharmaKeyRegistryMultisigDeployer.options.data = - DharmaKeyRegistryMultisigArtifact.bytecode; - this.DharmaEscapeHatchRegistryDeployer = new web3.eth.Contract( - DharmaEscapeHatchRegistryArtifact.abi + this.DharmaEscapeHatchRegistryDeployer = this.newDeployer( + DharmaEscapeHatchRegistryArtifact ); - this.DharmaEscapeHatchRegistryDeployer.options.data = - DharmaEscapeHatchRegistryArtifact.bytecode; } } From f945a1695d5c84cb835e2f55d9287bdf5bfe8e5c Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Mon, 10 Feb 2020 11:58:02 -0500 Subject: [PATCH 33/47] implement withBalanceCheck wrapper --- .../DharmaSmartWalletImplementationV7.sol | 19 +- contracts/test/BalanceChecker.sol | 44 +++- ...maSmartWalletImplementationV0Interface.sol | 1 - ...maSmartWalletImplementationV7Interface.sol | 97 +++++++++ scripts/test/test.js | 203 +++++++++++------- scripts/test/testHelpers.js | 100 +++++++-- 6 files changed, 345 insertions(+), 119 deletions(-) diff --git a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol index 4ad7a83..2e4b312 100644 --- a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol +++ b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol @@ -6,7 +6,6 @@ pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/cryptography/ECDSA.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "../../../interfaces/DharmaSmartWalletImplementationV0Interface.sol"; import "../../../interfaces/DharmaSmartWalletImplementationV1Interface.sol"; import "../../../interfaces/DharmaSmartWalletImplementationV3Interface.sol"; import "../../../interfaces/DharmaSmartWalletImplementationV4Interface.sol"; @@ -39,7 +38,6 @@ import "../../helpers/SmartWalletRevertReasonHelperV1.sol"; * of the new smart wallet instance. */ contract DharmaSmartWalletImplementationV7 is - DharmaSmartWalletImplementationV0Interface, DharmaSmartWalletImplementationV1Interface, DharmaSmartWalletImplementationV3Interface, DharmaSmartWalletImplementationV4Interface, @@ -907,21 +905,26 @@ contract DharmaSmartWalletImplementationV7 is } /** - * @notice Retrieve the Dai and USDC balances held by the smart wallet, both - * directly and held in Dharma Dai and Dharma USD Coin. - * @return The Dai balance, the USDC balance, the underlying Dai balance of - * the dDai balance, and the underlying USDC balance of the dUSDC balance. + * @notice View function to retrieve the Dai and USDC balances held by the + * smart wallet, both directly and held in Dharma Dai and Dharma USD Coin, as + * well as the Ether balance (the underlying dEther balance will always return + * zero in this implementation, as there is no dEther yet). + * @return The Dai balance, the USDC balance, the Ether balance, the + * underlying Dai balance of the dDai balance, and the underlying USDC balance + * of the dUSDC balance (zero will always be returned as the underlying Ether + * balance of the dEther balance in this implementation). */ - function getBalances() external returns ( + function getBalances() external view returns ( uint256 daiBalance, uint256 usdcBalance, - uint256 etherBalance, // always returns 0 + uint256 etherBalance, uint256 dDaiUnderlyingDaiBalance, uint256 dUsdcUnderlyingUsdcBalance, uint256 dEtherUnderlyingEtherBalance // always returns 0 ) { daiBalance = _DAI.balanceOf(address(this)); usdcBalance = _USDC.balanceOf(address(this)); + etherBalance = address(this).balance; dDaiUnderlyingDaiBalance = _DDAI.balanceOfUnderlying(address(this)); dUsdcUnderlyingUsdcBalance = _DUSDC.balanceOfUnderlying(address(this)); } diff --git a/contracts/test/BalanceChecker.sol b/contracts/test/BalanceChecker.sol index 6bc4c35..0efc63d 100644 --- a/contracts/test/BalanceChecker.sol +++ b/contracts/test/BalanceChecker.sol @@ -1,6 +1,8 @@ pragma solidity 0.5.11; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "../../interfaces/CTokenInterface.sol"; +import "../../interfaces/DTokenInterface.sol"; /** @@ -40,15 +42,15 @@ contract BalanceChecker { ); function getBalances(address wallet) external view returns ( - uint256 dDaiBalance, - uint256 dUSDCBalance, - uint256 daiBalance, - uint256 usdcBalance, - uint256 saiBalance, - uint256 cSaiBalance, - uint256 cDaiBalance, - uint256 cUSDCBalance, - uint256 etherBalance + uint256 dDaiBalance, + uint256 dUSDCBalance, + uint256 daiBalance, + uint256 usdcBalance, + uint256 saiBalance, + uint256 cSaiBalance, + uint256 cDaiBalance, + uint256 cUSDCBalance, + uint256 etherBalance ) { dDaiBalance = _DDAI.balanceOf(wallet); dUSDCBalance = _DUSDC.balanceOf(wallet); @@ -60,4 +62,28 @@ contract BalanceChecker { cUSDCBalance = _CUSDC.balanceOf(wallet); etherBalance = wallet.balance; } + + function getUnderlyingBalances(address wallet) external returns ( + uint256 dDaiExchangeRate, + uint256 dUSDCExchangeRate, + uint256 cSaiExchangeRate, + uint256 cDaiExchangeRate, + uint256 cUSDCExchangeRate, + uint256 dDaiBalanceUnderlying, + uint256 dUSDCBalanceUnderlying, + uint256 cSaiBalanceUnderlying, + uint256 cDaiBalanceUnderlying, + uint256 cUSDCBalanceUnderlying + ) { + dDaiExchangeRate = DTokenInterface(address(_DDAI)).exchangeRateCurrent(); + dUSDCExchangeRate = DTokenInterface(address(_DUSDC)).exchangeRateCurrent(); + cSaiExchangeRate = CTokenInterface(address(_CSAI)).exchangeRateCurrent(); + cDaiExchangeRate = CTokenInterface(address(_CDAI)).exchangeRateCurrent(); + cUSDCExchangeRate = CTokenInterface(address(_CUSDC)).exchangeRateCurrent(); + dDaiBalanceUnderlying = DTokenInterface(address(_DDAI)).balanceOfUnderlying(wallet); + dUSDCBalanceUnderlying = DTokenInterface(address(_DUSDC)).balanceOfUnderlying(wallet); + cSaiBalanceUnderlying = CTokenInterface(address(_CSAI)).balanceOfUnderlying(wallet); + cDaiBalanceUnderlying = CTokenInterface(address(_CDAI)).balanceOfUnderlying(wallet); + cUSDCBalanceUnderlying = CTokenInterface(address(_CUSDC)).balanceOfUnderlying(wallet); + } } \ No newline at end of file diff --git a/interfaces/DharmaSmartWalletImplementationV0Interface.sol b/interfaces/DharmaSmartWalletImplementationV0Interface.sol index f1814f6..d8c24ee 100644 --- a/interfaces/DharmaSmartWalletImplementationV0Interface.sol +++ b/interfaces/DharmaSmartWalletImplementationV0Interface.sol @@ -29,7 +29,6 @@ interface DharmaSmartWalletImplementationV0Interface { RemoveEscapeHatch, DisableEscapeHatch, DAIWithdrawal, - SignatureVerification, DAIBorrow, USDCBorrow } diff --git a/interfaces/DharmaSmartWalletImplementationV7Interface.sol b/interfaces/DharmaSmartWalletImplementationV7Interface.sol index d3206ae..3e6b790 100644 --- a/interfaces/DharmaSmartWalletImplementationV7Interface.sol +++ b/interfaces/DharmaSmartWalletImplementationV7Interface.sol @@ -2,8 +2,105 @@ pragma solidity 0.5.11; interface DharmaSmartWalletImplementationV7Interface { + // Fires when a new user signing key is set on the smart wallet. + event NewUserSigningKey(address userSigningKey); + + // Fires when an error occurs as part of an attempted action. + event ExternalError(address indexed source, string revertReason); + + // The smart wallet recognizes DAI, USDC, ETH, and SAI as supported assets. + enum AssetType { + DAI, + USDC, + ETH, + SAI + } + + // Actions, or protected methods (i.e. not deposits) each have an action type. + enum ActionType { + Cancel, + SetUserSigningKey, + Generic, + GenericAtomicBatch, + SAIWithdrawal, + USDCWithdrawal, + ETHWithdrawal, + SetEscapeHatch, + RemoveEscapeHatch, + DisableEscapeHatch, + DAIWithdrawal, + SignatureVerification, + DAIBorrow, + USDCBorrow + } + + function initialize(address userSigningKey) external; + + function repayAndDeposit() external; + + function withdrawDai( + uint256 amount, + address recipient, + uint256 minimumActionGas, + bytes calldata userSignature, + bytes calldata dharmaSignature + ) external returns (bool ok); + + function withdrawUSDC( + uint256 amount, + address recipient, + uint256 minimumActionGas, + bytes calldata userSignature, + bytes calldata dharmaSignature + ) external returns (bool ok); + + function cancel( + uint256 minimumActionGas, + bytes calldata signature + ) external; + + function setUserSigningKey( + address userSigningKey, + uint256 minimumActionGas, + bytes calldata userSignature, + bytes calldata dharmaSignature + ) external; + function migrateSaiToDai() external; + function migrateCSaiToDDai() external; + function migrateCDaiToDDai() external; + function migrateCUSDCToDUSDC() external; + + function getBalances() external view returns ( + uint256 daiBalance, + uint256 usdcBalance, + uint256 etherBalance, + uint256 dDaiUnderlyingDaiBalance, + uint256 dUsdcUnderlyingUsdcBalance, + uint256 dEtherUnderlyingEtherBalance // always returns zero + ); + + function getUserSigningKey() external view returns (address userSigningKey); + + function getNonce() external view returns (uint256 nonce); + + function getNextCustomActionID( + ActionType action, + uint256 amount, + address recipient, + uint256 minimumActionGas + ) external view returns (bytes32 actionID); + + function getCustomActionID( + ActionType action, + uint256 amount, + address recipient, + uint256 nonce, + uint256 minimumActionGas + ) external view returns (bytes32 actionID); + + function getVersion() external pure returns (uint256 version); } \ No newline at end of file diff --git a/scripts/test/test.js b/scripts/test/test.js index 49b1e95..e4de39e 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -3527,16 +3527,49 @@ async function test(testingContext) { 7 ); - await tester.runTest( - "V7 UserSmartWallet can get balances", - UserSmartWalletV7, - "getBalances", - "call", - [], - true, - value => { - //console.log(value) - } + const startingBalance = { + dDai: 0, + dUSDC: 0, + dai: 0, + usdc: 0, + dDaiUnderlying: 0, + dUSDCUnderlying: 0, + etherRaw: '99999999999999998' + } + + await tester.withBalanceCheck( + UserSmartWalletV7.options.address, + startingBalance, + startingBalance, + tester.runTest, + [ + "V7 UserSmartWallet can get balances", + UserSmartWalletV7, + "getBalances", + "call", + [], + true, + values => { + assert.strictEqual( + values.daiBalance, startingBalance.dai.toString() + ); + assert.strictEqual( + values.usdcBalance, startingBalance.usdc.toString() + ); + assert.strictEqual( + values.etherBalance, startingBalance.etherRaw + ); + assert.strictEqual( + values.dDaiUnderlyingDaiBalance, + startingBalance.dDaiUnderlying.toString() + ); + assert.strictEqual( + values.dUsdcUnderlyingUsdcBalance, + startingBalance.dUSDCUnderlying.toString() + ); + assert.strictEqual(values.dEtherUnderlyingEtherBalance, '0'); + } + ] ); await tester.runTest( @@ -3733,64 +3766,40 @@ async function test(testingContext) { constants.USDC_WHALE_ADDRESS ); - await tester.runTest( - "V7 UserSmartWallet can get a generic action ID", - UserSmartWalletV7, - "getNextGenericActionID", - "call", - [ - tester.DAI.options.address, - tester.DAI.methods - .approve(tester.CDAI.options.address, 0) - .encodeABI(), - 0 - ], - true, - value => { - customActionId = value; - } - ); - - executeActionSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.address - ); + const preDepositBalance = { + dai: 100, + usdc: 100, + dDaiUnderlying: 0, + dUSDCUnderlying: 0 + } - executeActionUserSignature = tester.signHashedPrefixedHexString( - customActionId, - tester.addressTwo - ); + const postDepositBalance = { + dai: 0, + usdc: 0, + dDaiUnderlying: 100, + dUSDCUnderlying: 100 + } - await tester.runTest( - "V7 UserSmartWallet can call executeAction", - UserSmartWalletV7, - "executeAction", - "send", - [ - tester.DAI.options.address, - tester.DAI.methods - .approve(tester.CDAI.options.address, 0) - .encodeABI(), - 0, - executeActionUserSignature, - executeActionSignature + await tester.withBalanceCheck( + UserSmartWalletV7.options.address, + preDepositBalance, + postDepositBalance, + tester.runTest, + [ + "V7 user smart wallet can trigger repayAndDeposit to deposit all new funds", + UserSmartWalletV7, + "repayAndDeposit", + "send", + [], + true, + receipt => { + // TODO: validate + } ] - ); - - await tester.runTest( - "V7 user smart wallet can trigger repayAndDeposit to deposit all new funds", - UserSmartWalletV7, - "repayAndDeposit", - "send", - [], - true, - receipt => { - // TODO: validate - } - ); + ) await tester.runTest( - "Dai Whale can deposit dai into the V7 smart wallet", + "Dai Whale can deposit dai into the V7 smart wallet again", tester.DAI, "transfer", "send", @@ -4295,7 +4304,7 @@ async function test(testingContext) { "call", [ 5, // USDCWithdrawal, - "100000", + "1000000", tester.address, 0 ], @@ -4315,24 +4324,54 @@ async function test(testingContext) { tester.addressTwo ); - await tester.runTest( - "V7 UserSmartWallet relay can call with two signatures to withdraw USDC", - UserSmartWalletV7, - "withdrawUSDC", - "send", + const preUSDCWithdrawalBalance = { + dUSDCUnderlying: 100 + } + + const postUSDCWithdrawalBalance = { + dUSDCUnderlying: 99 + } + + const recipientUSDCBalance = (await tester.getBalances(tester.address)).usdc; + + const preUSDCWithdrawalRecipientBalance = { + usdc: recipientUSDCBalance + } + + const postUSDCWithdrawalRecipientBalance = { + usdc: recipientUSDCBalance + 1 + } + + await tester.withBalanceCheck( + UserSmartWalletV7.options.address, + preUSDCWithdrawalBalance, + postUSDCWithdrawalBalance, + tester.withBalanceCheck, [ - "100000", tester.address, - 0, - usdcUserWithdrawalSignature, - usdcWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress + preUSDCWithdrawalRecipientBalance, + postUSDCWithdrawalRecipientBalance, + tester.runTest, + [ + "V7 UserSmartWallet relay can call with two signatures to withdraw USDC", + UserSmartWalletV7, + "withdrawUSDC", + "send", + [ + "1000000", + tester.address, + 0, + usdcUserWithdrawalSignature, + usdcWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ] + ] ); await tester.runTest( @@ -6210,8 +6249,6 @@ async function test(testingContext) { tester.address ); - - await tester.runTest( "V7 UserSmartWallet escape hatch account can call escape again", UserSmartWalletV7, @@ -6373,6 +6410,8 @@ async function test(testingContext) { [web3.utils.toWei('100', 'ether')] ); + // console.log(await tester.getBalances(tester.address)); + await tester.runTest( "cSai can be sent to V7 UserSmartWallet", tester.CSAI, diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index 1fd25f0..98cc17c 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -783,6 +783,51 @@ class Tester { } } + async withBalanceCheck(account, initial, final, test, testArgs) { + // Get the initial balances. + const initialBalances = await this.getBalances(account); + const initialBalancesSet = new Set(Object.keys(initialBalances)); + + //console.log(initialBalances) + + const initialSet = new Set(Object.keys(initial)); + const finalSet = new Set(Object.keys(final)); + + // Initial and final sets must both have the same balance checks. + assert.strictEqual(initialSet.size, finalSet.size); + assert.strictEqual( + initialSet.size, (new Set([...initialSet, ...finalSet])).size + ); + + // Ensure that all the specified balance checks are actually returned. + assert.strictEqual( + (new Set([...initialSet].filter( + x => !initialBalancesSet.has(x)) + )).size, + 0 + ); + + // Get specified keys from balance check and compare to expected values. + const balanceChecks = [...(new Set([...initialSet].filter( + x => initialBalancesSet.has(x) + )))]; + + for (const balance of balanceChecks) { + assert.strictEqual(initial[balance], initialBalances[balance]); + } + + // Run the test. + await test.bind(this)(...testArgs); + + // Get the final balances. + const finalBalances = await this.getBalances(account); + const fiinalBalancesSet = new Set(Object.keys(finalBalances)); + + for (const balance of balanceChecks) { + assert.strictEqual(final[balance], finalBalances[balance]); + } + } + async getBalances(account) { const balances = await this.BalanceChecker.methods.getBalances(account) .call() @@ -791,26 +836,43 @@ class Tester { process.exit(1); }); + const underlyingBalances = await this.BalanceChecker.methods.getUnderlyingBalances(account) + .call() + .catch(error => { + console.error(error); + process.exit(1); + }); + return { - account, - dDai: parseFloat(web3.utils.fromWei(balances.dDaiBalance, 'gwei')) * 10, - dUSDC: parseFloat(web3.utils.fromWei(balances.dUSDCBalance, 'gwei')) * 10, - dai: parseFloat(web3.utils.fromWei(balances.daiBalance, 'ether')), - usdc: parseFloat(web3.utils.fromWei(balances.usdcBalance, 'mwei')), - sai: parseFloat(web3.utils.fromWei(balances.saiBalance, 'ether')), - cSai: parseFloat(web3.utils.fromWei(balances.cSaiBalance, 'gwei')) * 10, - cDai: parseFloat(web3.utils.fromWei(balances.cDaiBalance, 'gwei')) * 10, - cUSDC: parseFloat(web3.utils.fromWei(balances.cUSDCBalance, 'gwei')) * 10, - ether: parseFloat(web3.utils.fromWei(balances.etherBalance, 'ether')), - dDaiRaw: balances.dDaiBalance, - dUSDCRaw: balances.dUSDCBalance, - daiRaw: balances.daiBalance, - usdcRaw: balances.usdcBalance, - saiRaw: balances.saiBalance, - cSaiRaw: balances.cSaiBalance, - cDaiRaw: balances.cDaiBalance, - cUSDCRaw: balances.cUSDCBalance, - etherRaw: balances.etherBalance + account, + dDai: parseFloat(web3.utils.fromWei(balances.dDaiBalance, 'gwei')) * 10, + dUSDC: parseFloat(web3.utils.fromWei(balances.dUSDCBalance, 'gwei')) * 10, + dai: parseFloat(web3.utils.fromWei(balances.daiBalance, 'ether')), + usdc: parseFloat(web3.utils.fromWei(balances.usdcBalance, 'mwei')), + sai: parseFloat(web3.utils.fromWei(balances.saiBalance, 'ether')), + cSai: parseFloat(web3.utils.fromWei(balances.cSaiBalance, 'gwei')) * 10, + cDai: parseFloat(web3.utils.fromWei(balances.cDaiBalance, 'gwei')) * 10, + cUSDC: parseFloat(web3.utils.fromWei(balances.cUSDCBalance, 'gwei')) * 10, + ether: parseFloat(web3.utils.fromWei(balances.etherBalance, 'ether')), + dDaiUnderlying: parseFloat(web3.utils.fromWei(underlyingBalances.dDaiBalanceUnderlying, 'ether')), + dUSDCUnderlying: parseFloat(web3.utils.fromWei(underlyingBalances.dUSDCBalanceUnderlying, 'mwei')), + cSaiUnderlying: parseFloat(web3.utils.fromWei(underlyingBalances.cSaiBalanceUnderlying, 'ether')), + cDaiUnderlying: parseFloat(web3.utils.fromWei(underlyingBalances.cDaiBalanceUnderlying, 'ether')), + cUSDCUnderlying: parseFloat(web3.utils.fromWei(underlyingBalances.cUSDCBalanceUnderlying, 'mwei')), + dDaiRaw: balances.dDaiBalance, + dUSDCRaw: balances.dUSDCBalance, + daiRaw: balances.daiBalance, + usdcRaw: balances.usdcBalance, + saiRaw: balances.saiBalance, + cSaiRaw: balances.cSaiBalance, + cDaiRaw: balances.cDaiBalance, + cUSDCRaw: balances.cUSDCBalance, + etherRaw: balances.etherBalance, + dDaiUnderlyingRaw: underlyingBalances.dDaiBalanceUnderlying, + dUSDCUnderlyingRaw: underlyingBalances.dUSDCBalanceUnderlying, + cSaiUnderlyingRaw: underlyingBalances.cSaiBalanceUnderlying, + cDaiUnderlyingRaw: underlyingBalances.cDaiBalanceUnderlying, + cUSDCUnderlyingRaw: underlyingBalances.cUSDCBalanceUnderlying }; } From 9343296b71ffd3ff48d364cfcac1f99f793eeca3 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Mon, 10 Feb 2020 13:35:59 -0500 Subject: [PATCH 34/47] polish DSWv7 and add initial ERC1271 coverage --- .../SmartWalletRevertReasonHelperV1.sol | 1 + .../DharmaSmartWalletImplementationV7.sol | 17 ++-- scripts/test/constants.js | 6 +- scripts/test/deploy.js | 24 ++--- scripts/test/test.js | 94 +++++++++++++++---- scripts/test/testHelpers.js | 21 +++++ 6 files changed, 124 insertions(+), 39 deletions(-) diff --git a/contracts/helpers/SmartWalletRevertReasonHelperV1.sol b/contracts/helpers/SmartWalletRevertReasonHelperV1.sol index bce98ed..0006707 100644 --- a/contracts/helpers/SmartWalletRevertReasonHelperV1.sol +++ b/contracts/helpers/SmartWalletRevertReasonHelperV1.sol @@ -44,6 +44,7 @@ contract SmartWalletRevertReasonHelperV1 { if (code == 27) return "Invalid `to` parameter - cannot supply the address of this contract."; if (code == 28) return "Invalid `to` parameter - cannot supply the Dharma Escape Hatch Registry."; if (code == 29) return "Invalid custom action type."; + if (code == 30) return "Insufficient data supplied."; return "(no revert reason)"; } } \ No newline at end of file diff --git a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol index 2e4b312..94d508a 100644 --- a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol +++ b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol @@ -127,7 +127,7 @@ contract DharmaSmartWalletImplementationV7 is ); SmartWalletRevertReasonHelperV1 internal constant _REVERT_REASON_HELPER = ( - SmartWalletRevertReasonHelperV1(0x13821c0129FB9e2CC16dE2660783Ff4E4861e92d) + SmartWalletRevertReasonHelperV1(0xE24257338d0c15f3Dd00Ed59fcA9e50CfB167bA8) ); // Compound returns a value of 0 to indicate success, or lack of an error. @@ -1107,7 +1107,10 @@ contract DharmaSmartWalletImplementationV7 is * supplied data. The data must be ABI encoded as (bytes32, bytes), where the * first bytes32 parameter represents the hash digest for validating the * supplied signatures and the second bytes parameter contains context for the - * requested validation. + * requested validation. The two signatures are packed together, with the one + * from Dharma coming first and that from the user coming second - this is so + * that, in future versions, multiple user signatures may be supplied if the + * associated key ring requires them. * @param data bytes The data used to validate the signature. * @param signatures bytes The two signatures, each 65 bytes - one from the * owner (using ERC-1271 as well if the user signing key is a contract) and @@ -1121,13 +1124,15 @@ contract DharmaSmartWalletImplementationV7 is // Get message hash digest and any additional context from data argument. bytes32 digest; bytes memory context; + if (data.length == 32) { digest = abi.decode(data, (bytes32)); } else { + require(data.length >= 64, _revertReason(30)); (digest, context) = abi.decode(data, (bytes32, bytes)); } - // Get user signature & Dharma signature from combined signatures argument. + // Get Dharma signature & user signature from combined signatures argument. require(signatures.length == 130, _revertReason(11)); bytes memory signaturesInMemory = signatures; bytes32 r; @@ -1138,14 +1143,14 @@ contract DharmaSmartWalletImplementationV7 is s := mload(add(signaturesInMemory, 0x40)) v := byte(0, mload(add(signaturesInMemory, 0x60))) } - bytes memory userSignature = abi.encodePacked(r, s, v); + bytes memory dharmaSignature = abi.encodePacked(r, s, v); assembly { r := mload(add(signaturesInMemory, 0x61)) s := mload(add(signaturesInMemory, 0x81)) v := byte(0, mload(add(signaturesInMemory, 0xa1))) } - bytes memory dharmaSignature = abi.encodePacked(r, s, v); + bytes memory userSignature = abi.encodePacked(r, s, v); // Validate user signature with `SignatureVerification` as the action type. require( @@ -2199,7 +2204,7 @@ contract DharmaSmartWalletImplementationV7 is revertReason = abi.decode(revertReasonBytes, (string)); } else { // Simply return the default, with no revert reason. - revertReason = _revertReason(30); + revertReason = _revertReason(uint256(-1)); } } diff --git a/scripts/test/constants.js b/scripts/test/constants.js index 187882c..a91f9a2 100644 --- a/scripts/test/constants.js +++ b/scripts/test/constants.js @@ -94,6 +94,8 @@ module.exports = Object.freeze({ CDAI_MAINNET_ADDRESS: "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643", CUSDC_MAINNET_ADDRESS: "0x39AA39c021dfbaE8faC545936693aC917d5E7563", CETH_MAINNET_ADDRESS: "0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5", + DDAI_MAINNET_ADDRESS: "0x00000000001876eB1444c986fD502e618c587430", + DUSDC_MAINNET_ADDRESS: "0x00000000008943c65cAf789FFFCF953bE156f6f8", DAI_MIGRATOR_MAINNET_ADDRESS: "0xc73e0383F3Aff3215E6f04B0331D58CeCf0Ab849", MOCK_USDC_BLACKLISTED_ADDRESS: "0x6000000000000000000000000000000000000006", COMPTROLLER_MAINNET_ADDRESS: "0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B", @@ -262,7 +264,7 @@ module.exports = Object.freeze({ "20204b657952696e6755706772616465426561636f6e50726f78795631202020" ], REVERT_REASON_HELPER_METADATA: [ - "373389197482e319656922b5cf379766d403a45bdb1776717726e0d125834166" + "cc6f0e10e5acac6b087faf256f191349c398a4fc1e1ca52f2372ad1ecffc2704" ], KEY_RING_FACTORY_V2_ADDRESS: "0x2484000059004afB720000dc738434fA6200F49D", KEY_RING_FACTORY_V2_SALT: @@ -317,7 +319,7 @@ module.exports = Object.freeze({ "0x0000000000f55ff05D0080fE17A63b16596Fd59f", INDESTRUCTIBLE_REGISTRY_RUNTIME_HASH: "0xadca137a47625f8ad1da20be107380101474374dc6c31ad0b8c1807558ea3c29", - REVERT_REASON_HELPER_ADDRESS: "0x13821c0129FB9e2CC16dE2660783Ff4E4861e92d", + REVERT_REASON_HELPER_ADDRESS: "0xE24257338d0c15f3Dd00Ed59fcA9e50CfB167bA8", INDESTRUCTIBLE_REGISTRY_CREATION_TX: "0x64e030870000000000000000000000000000000000000000a4ab82b860e6cb06780400" + "000000000000000000000000000000000000000000000000000000000000000040000000" + diff --git a/scripts/test/deploy.js b/scripts/test/deploy.js index c11c706..818ee35 100644 --- a/scripts/test/deploy.js +++ b/scripts/test/deploy.js @@ -133,18 +133,18 @@ async function test(testingContext) { } /* - console.log( - swapMetadataHash( - DharmaSmartWalletImplementationV7Artifact.bytecode, - constants.DHARMA_SMART_WALLET_IMPLEMENTATION_V7_METADATA - ), - web3.utils.keccak256(swapMetadataHash( - DharmaSmartWalletImplementationV7Artifact.bytecode, - constants.DHARMA_SMART_WALLET_IMPLEMENTATION_V7_METADATA - ), {encoding: 'hex'}) - ) - process.exit(0) - */ + console.log( + swapMetadataHash( + DharmaSmartWalletImplementationV7Artifact.bytecode, + constants.DHARMA_SMART_WALLET_IMPLEMENTATION_V7_METADATA + ), + web3.utils.keccak256(swapMetadataHash( + DharmaSmartWalletImplementationV7Artifact.bytecode, + constants.DHARMA_SMART_WALLET_IMPLEMENTATION_V7_METADATA + ), {encoding: 'hex'}) + ) + process.exit(0) + */ const DharmaUpgradeBeaconController = new web3.eth.Contract( DharmaUpgradeBeaconControllerArtifact.abi, diff --git a/scripts/test/test.js b/scripts/test/test.js index e4de39e..a2cdc2d 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -4461,25 +4461,6 @@ async function test(testingContext) { tester.originalAddress ); - /* TODO: get this working manually - const withdrawalMessage = ( - UserSmartWallet.options.address + // smart wallet address - constants.NULL_BYTES_32.slice(2) + // smart wallet version - address.slice(2) + // user dharma key - address.slice(2) + // dharma key registry key - '5'.padStart(64, '0') + // nonce - constants.NULL_BYTES_32.slice(2) + // minimum gas - '04' + // action type - 'f'.padStart(64, 'f') + // amount - address.slice(2) // recipient - ) - - const saiWithdrawalSignature = tester.signHashedPrefixedHashedHexString( - withdrawalMessage, - address - ) - */ - await tester.runTest( "V7 UserSmartWallet can get a Dai withdrawal custom action ID", UserSmartWalletV7, @@ -6629,6 +6610,81 @@ async function test(testingContext) { tester.originalAddress ); + await tester.runTest( + `Check allowance is not set before meta-tx`, + tester.DUSDC, + "allowance", + "call", + [UserSmartWalletV7.options.address, tester.addressTwo], + true, + value => { + assert.strictEqual(value, '0'); + } + ); + + let messageHash; + await tester.runTest( + `Get message hash for meta-transaction approval`, + tester.DUSDC_META, + "getMetaTransactionMessageHash", + "call", + [ + "0x2d657fa5", // `modifyAllowanceViaMetaTransaction` + web3.eth.abi.encodeParameters( + ["address", "address", "uint256", "bool"], + [UserSmartWalletV7.options.address, tester.addressTwo, '1', true] + ), + 0, // No expiration + constants.NULL_BYTES_32 // no salt + ], + true, + values => { + assert.ok(values.valid); + messageHash = values.messageHash; + } + ); + + const messageHashSignature = tester.signHashedPrefixedHexString( + messageHash, + tester.address + ); + + const messageHashUserSignature = tester.signHashedPrefixedHexString( + messageHash, + tester.addressTwo + ); + + await tester.runTest( + `dUSDC allowance is modifiable via meta-transaction`, + tester.DUSDC_META, + "modifyAllowanceViaMetaTransaction", + "send", + [ + UserSmartWalletV7.options.address, + tester.addressTwo, + '1', + true, + 0, + constants.NULL_BYTES_32, + messageHashSignature + messageHashUserSignature.slice(2) + ], + true, + receipt => { + // TODO: validate + } + ); + + await tester.runTest( + `Check allowance is set after meta-tx`, + tester.DUSDC, + "allowance", + "call", + [UserSmartWalletV7.options.address, tester.addressTwo], + true, + value => { + assert.strictEqual(value, '1'); + } + ); // Initiate account recovery await tester.runTest( diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index 98cc17c..1430c1f 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -1148,6 +1148,27 @@ class Tester { IERC20Artifact.abi, constants.CUSDC_MAINNET_ADDRESS ); + this.DDAI = new web3.eth.Contract( + IERC20Artifact.abi, constants.DDAI_MAINNET_ADDRESS + ); + + this.DUSDC = new web3.eth.Contract( + IERC20Artifact.abi, constants.DUSDC_MAINNET_ADDRESS + ); + + const MetaABI = [ + {"constant":false,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bool","name":"increase","type":"bool"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes","name":"signatures","type":"bytes"}],"name":"modifyAllowanceViaMetaTransaction","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}, + {"constant":true,"inputs":[{"internalType":"bytes4","name":"functionSelector","type":"bytes4"},{"internalType":"bytes","name":"arguments","type":"bytes"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"getMetaTransactionMessageHash","outputs":[{"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"internalType":"bool","name":"valid","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"} + ] + + this.DDAI_META = new web3.eth.Contract( + MetaABI, constants.DDAI_MAINNET_ADDRESS + ); + + this.DUSDC_META = new web3.eth.Contract( + MetaABI, constants.DUSDC_MAINNET_ADDRESS + ); + this.BadBeaconDeployer = this.newDeployer(BadBeaconArtifact); this.BadBeaconTwoDeployer = this.newDeployer(BadBeaconTwoArtifact); From 79d20d8b9a9993855f070c9a8522c4d1185a61f5 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Mon, 10 Feb 2020 14:30:35 -0500 Subject: [PATCH 35/47] eexpand ERC-1271 test coverage --- scripts/test/test.js | 75 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/scripts/test/test.js b/scripts/test/test.js index a2cdc2d..8aaf1e4 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -6610,6 +6610,27 @@ async function test(testingContext) { tester.originalAddress ); + await tester.runTest( + `Call to isValidSignature with insufficient data fails`, + UserSmartWalletV7, + "isValidSignature", + "call", + ["0x", "0x"], + false + ); + + await tester.runTest( + `Call to isValidSignature with 32-bytes of data has no context`, + UserSmartWalletV7, + "isValidSignature", + "call", + [ + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x" + ], + false + ); + await tester.runTest( `Check allowance is not set before meta-tx`, tester.DUSDC, @@ -6654,6 +6675,60 @@ async function test(testingContext) { tester.addressTwo ); + const messageHashBadSignature = '0xaaaaaaaa' + messageHashSignature.slice(10) + const messageHashBadUserSignature = '0xaaaaaaaa' + messageHashUserSignature.slice(10) + + await tester.runTest( + `dUSDC allowance is not modifiable via meta-transaction with bad signature length`, + tester.DUSDC_META, + "modifyAllowanceViaMetaTransaction", + "send", + [ + UserSmartWalletV7.options.address, + tester.addressTwo, + '1', + true, + 0, + constants.NULL_BYTES_32, + messageHashSignature + messageHashUserSignature.slice(2) + 'aa' + ], + false + ); + + await tester.runTest( + `dUSDC allowance is not modifiable via meta-transaction with bad Dharma signature`, + tester.DUSDC_META, + "modifyAllowanceViaMetaTransaction", + "send", + [ + UserSmartWalletV7.options.address, + tester.addressTwo, + '1', + true, + 0, + constants.NULL_BYTES_32, + messageHashBadSignature + messageHashUserSignature.slice(2) + ], + false + ); + + await tester.runTest( + `dUSDC allowance is not modifiable via meta-transaction with bad user signature`, + tester.DUSDC_META, + "modifyAllowanceViaMetaTransaction", + "send", + [ + UserSmartWalletV7.options.address, + tester.addressTwo, + '1', + true, + 0, + constants.NULL_BYTES_32, + messageHashSignature + messageHashBadUserSignature.slice(2) + ], + false + ); + await tester.runTest( `dUSDC allowance is modifiable via meta-transaction`, tester.DUSDC_META, From 811431e47021afabb48bd7e1eb6857f2b832831a Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Mon, 10 Feb 2020 15:06:04 -0500 Subject: [PATCH 36/47] clean up DSWv7 comments --- .../DharmaSmartWalletImplementationV7.sol | 71 ++++++++++--------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol index 94d508a..7f752cc 100644 --- a/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol +++ b/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV7.sol @@ -25,17 +25,18 @@ import "../../helpers/SmartWalletRevertReasonHelperV1.sol"; * @author 0age * @notice The V7 implementation for the Dharma smart wallet is a non-custodial, * meta-transaction-enabled wallet with helper functions to facilitate lending - * funds through Dharma Dai and Dharma USDC (which in turn use CompoundV2), and - * with a security backstop provided by Dharma Labs prior to making withdrawals. - * It adds support for Dharma Dai and Dharma USDC, which wrap the respective - * cTokens and mint and redeem them internally as interest-bearing collateral. - * It contains methods to support account recovery, escape hatch functionality, - * and generic actions, including in an atomic batch. The smart wallet instances - * utilizing this implementation are deployed through the Dharma Smart Wallet - * Factory via `CREATE2`, which allows for their address to be known ahead of - * time, and any Dai or USDC that has already been sent into that address will - * automatically be deposited into the respective Dharma Token upon deployment - * of the new smart wallet instance. + * funds through Dharma Dai and Dharma USD Coin (which in turn use CompoundV2), + * and with an added security backstop provided by Dharma Labs prior to making + * withdrawals. It adds support for Dharma Dai and Dharma USD Coin - they employ + * the respective cTokens as backing tokens and mint and redeem them internally + * as interest-bearing collateral. This implementation also contains methods to + * support account recovery, escape hatch functionality, and generic actions, + * including in an atomic batch. The smart wallet instances utilizing this + * implementation are deployed through the Dharma Smart Wallet Factory via + * `CREATE2`, which allows for their address to be known ahead of time, and any + * Dai or USDC that has already been sent into that address will automatically + * be deposited into the respective Dharma Token upon deployment of the new + * smart wallet instance. */ contract DharmaSmartWalletImplementationV7 is DharmaSmartWalletImplementationV1Interface, @@ -126,6 +127,7 @@ contract DharmaSmartWalletImplementationV7 is 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 // mainnet ); + // The "revert reason helper" contains a collection of revert reason strings. SmartWalletRevertReasonHelperV1 internal constant _REVERT_REASON_HELPER = ( SmartWalletRevertReasonHelperV1(0xE24257338d0c15f3Dd00Ed59fcA9e50CfB167bA8) ); @@ -145,10 +147,10 @@ contract DharmaSmartWalletImplementationV7 is /** * @notice In the initializer, set up the initial user signing key, set - * approval on the Dharma Dai and Dharma USDC contracts, and deposit any Dai - * or USDC already at this address to receive dDai or dUSDC. Note that this - * initializer is only callable while the smart wallet instance is still in - * the contract creation phase. + * approval on the Dharma Dai and Dharma USD Coin contracts, and deposit any + * Dai or USDC already at this address to receive dDai or dUSDC. Note that + * this initializer is only callable while the smart wallet instance is still + * in the contract creation phase. * @param userSigningKey address The initial user signing key for the smart * wallet. */ @@ -180,7 +182,7 @@ contract DharmaSmartWalletImplementationV7 is /** * @notice Deposit all Dai and USDC currently residing at this address and - * receive Dharma Dai or Dharma USDC in return. Note that "repay" is not + * receive Dharma Dai or Dharma USD Coin in return. Note that "repay" is not * currently implemented, though it may be in a future implementation. If some * step of this function fails, the function itself will still succeed, but an * `ExternalError` with information on what went wrong will be emitted. @@ -344,8 +346,8 @@ contract DharmaSmartWalletImplementationV7 is /** * @notice Withdraw USDC to a provided recipient address by redeeming the * underlying USDC from the dUSDC contract and transferring it to recipient. - * All USDC in Dharma USDC and in the smart wallet itself can be withdrawn by - * providing an amount of uint256(-1) or 0xfff...fff. This function can be + * All USDC in Dharma USD Coin and in the smart wallet itself can be withdrawn + * by providing an amount of uint256(-1) or 0xfff...fff. This function can be * called directly by the account set as the global key on the Dharma Key * Registry, or by any relayer that provides a signed message from the same * keyholder. The nonce used for the signature must match the current nonce on @@ -505,7 +507,7 @@ contract DharmaSmartWalletImplementationV7 is /** * @notice Allow a signatory to increment the nonce at any point. The current - * nonce needs to be provided as an argument to the a signature so as not to + * nonce needs to be provided as an argument to the signature so as not to * enable griefing attacks. All arguments can be omitted if called directly. * No value is returned from this function - it will either succeed or revert. * @param minimumActionGas uint256 The minimum amount of gas that must be @@ -540,11 +542,12 @@ contract DharmaSmartWalletImplementationV7 is /** * @notice Perform a generic call to another contract. Note that accounts with - * no code may not be specified, nor may the smart wallet itself. In order to - * increment the nonce and invalidate the signatures, a call to this function - * with a valid target, signatutes, and gas will always succeed. To determine - * whether the call made as part of the action was successful or not, either - * the return values or the `CallSuccess` or `CallFailure` event can be used. + * no code may not be specified, nor may the smart wallet itself or the escape + * hatch registry. In order to increment the nonce and invalidate the + * signatures, a call to this function with a valid target, signatutes, and + * gas will always succeed. To determine whether the call made as part of the + * action was successful or not, either the return values or the `CallSuccess` + * or `CallFailure` event can be used. * @param to address The contract to call. * @param data bytes The calldata to provide when making the call. * @param minimumActionGas uint256 The minimum amount of gas that must be @@ -604,7 +607,7 @@ contract DharmaSmartWalletImplementationV7 is /** * @notice Allow signatory to set a new user signing key. The current nonce - * needs to be provided as an argument to the a signature so as not to enable + * needs to be provided as an argument to the signature so as not to enable * griefing attacks. No value is returned from this function - it will either * succeed or revert. * @param userSigningKey address The new user signing key to set on this smart @@ -998,7 +1001,7 @@ contract DharmaSmartWalletImplementationV7 is * will be used, which means that it will only be valid for the next action * taken. * @param action uint8 The type of action, designated by it's index. Valid - * custom actions in V6 include Cancel (0), SetUserSigningKey (1), + * custom actions in V7 include Cancel (0), SetUserSigningKey (1), * DAIWithdrawal (10), USDCWithdrawal (5), ETHWithdrawal (6), * SetEscapeHatch (7), RemoveEscapeHatch (8), and DisableEscapeHatch (9). * @param amount uint256 The amount to withdraw for Withdrawal actions. This @@ -1270,7 +1273,7 @@ contract DharmaSmartWalletImplementationV7 is // Note: while the call succeeded, the action may still have "failed". emit CallSuccess( actionID, - !externalOk, // if another call failed this will have been rolled back + !externalOk, // If another call failed this will have been rolled back nonce, currentCall.to, currentCall.data, @@ -1504,9 +1507,9 @@ contract DharmaSmartWalletImplementationV7 is * to be conditionally performed after the deposit. * @param asset uint256 The ID of the asset, either Dai (0) or USDC (1). * @param balance uint256 The amount of the asset to deposit. Note that an - * attempt to deposit "dust" (i.e. very small amounts) may result in 0 dTokens - * being minted, or in fewer dTokens being minted than is implied by the - * current exchange rate (due to lack of sufficient precision on the tokens). + * attempt to deposit "dust" (i.e. very small amounts) may result in fewer + * dTokens being minted than is implied by the current exchange rate due to a + * lack of sufficient precision on the tokens in question. */ function _depositDharmaToken(AssetType asset, uint256 balance) internal { // Only perform a deposit if the balance is at least .001 Dai or USDC. @@ -1686,7 +1689,7 @@ contract DharmaSmartWalletImplementationV7 is * errors, which can be guarded against by supplying a minimum action gas * requirement). * @param action uint8 The type of action, designated by it's index. Valid - * actions in V6 include Cancel (0), SetUserSigningKey (1), Generic (2), + * actions in V7 include Cancel (0), SetUserSigningKey (1), Generic (2), * GenericAtomicBatch (3), DAIWithdrawal (10), USDCWithdrawal (5), * ETHWithdrawal (6), SetEscapeHatch (7), RemoveEscapeHatch (8), and * DisableEscapeHatch (9). @@ -1979,7 +1982,7 @@ contract DharmaSmartWalletImplementationV7 is * is derived by prefixing (according to EIP-191 0x45) and hashing an actionID * returned from `getCustomActionID`. * @param action uint8 The type of action, designated by it's index. Valid - * actions in V6 include Cancel (0), SetUserSigningKey (1), Generic (2), + * actions in V7 include Cancel (0), SetUserSigningKey (1), Generic (2), * GenericAtomicBatch (3), DAIWithdrawal (10), USDCWithdrawal (5), * ETHWithdrawal (6), SetEscapeHatch (7), RemoveEscapeHatch (8), and * DisableEscapeHatch (9). @@ -2031,7 +2034,7 @@ contract DharmaSmartWalletImplementationV7 is * when reconstructing an action ID during protected function execution based * on the supplied parameters. * @param action uint8 The type of action, designated by it's index. Valid - * actions in V6 include Cancel (0), SetUserSigningKey (1), Generic (2), + * actions in V7 include Cancel (0), SetUserSigningKey (1), Generic (2), * GenericAtomicBatch (3), DAIWithdrawal (10), USDCWithdrawal (5), * ETHWithdrawal (6), SetEscapeHatch (7), RemoveEscapeHatch (8), and * DisableEscapeHatch (9). @@ -2130,7 +2133,7 @@ contract DharmaSmartWalletImplementationV7 is * "custom" action type (i.e. is not a generic action type) and to construct * the "arguments" input to an actionID based on that action type. * @param action uint8 The type of action, designated by it's index. Valid - * custom actions in V6 include Cancel (0), SetUserSigningKey (1), + * custom actions in V7 include Cancel (0), SetUserSigningKey (1), * DAIWithdrawal (10), USDCWithdrawal (5), ETHWithdrawal (6), * SetEscapeHatch (7), RemoveEscapeHatch (8), and DisableEscapeHatch (9). * @param amount uint256 The amount to withdraw for Withdrawal actions. This From 462e89727f2ed1a4821951e374a1953d59045da7 Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Mon, 10 Feb 2020 12:02:21 -0800 Subject: [PATCH 37/47] add withdrawDai check --- scripts/test/test.js | 112 +++++++++++++++++++++++------------- scripts/test/testHelpers.js | 110 ++++++++++++++++++++++++----------- 2 files changed, 149 insertions(+), 73 deletions(-) diff --git a/scripts/test/test.js b/scripts/test/test.js index 8aaf1e4..a33d1f0 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -3534,8 +3534,8 @@ async function test(testingContext) { usdc: 0, dDaiUnderlying: 0, dUSDCUnderlying: 0, - etherRaw: '99999999999999998' - } + etherRaw: "99999999999999998" + }; await tester.withBalanceCheck( UserSmartWalletV7.options.address, @@ -3551,13 +3551,16 @@ async function test(testingContext) { true, values => { assert.strictEqual( - values.daiBalance, startingBalance.dai.toString() + values.daiBalance, + startingBalance.dai.toString() ); assert.strictEqual( - values.usdcBalance, startingBalance.usdc.toString() + values.usdcBalance, + startingBalance.usdc.toString() ); assert.strictEqual( - values.etherBalance, startingBalance.etherRaw + values.etherBalance, + startingBalance.etherRaw ); assert.strictEqual( values.dDaiUnderlyingDaiBalance, @@ -3567,7 +3570,7 @@ async function test(testingContext) { values.dUsdcUnderlyingUsdcBalance, startingBalance.dUSDCUnderlying.toString() ); - assert.strictEqual(values.dEtherUnderlyingEtherBalance, '0'); + assert.strictEqual(values.dEtherUnderlyingEtherBalance, "0"); } ] ); @@ -3771,14 +3774,14 @@ async function test(testingContext) { usdc: 100, dDaiUnderlying: 0, dUSDCUnderlying: 0 - } + }; const postDepositBalance = { dai: 0, usdc: 0, dDaiUnderlying: 100, dUSDCUnderlying: 100 - } + }; await tester.withBalanceCheck( UserSmartWalletV7.options.address, @@ -3796,7 +3799,7 @@ async function test(testingContext) { // TODO: validate } ] - ) + ); await tester.runTest( "Dai Whale can deposit dai into the V7 smart wallet again", @@ -4326,21 +4329,22 @@ async function test(testingContext) { const preUSDCWithdrawalBalance = { dUSDCUnderlying: 100 - } + }; const postUSDCWithdrawalBalance = { dUSDCUnderlying: 99 - } + }; - const recipientUSDCBalance = (await tester.getBalances(tester.address)).usdc; + const recipientUSDCBalance = (await tester.getBalances(tester.address)) + .usdc; const preUSDCWithdrawalRecipientBalance = { usdc: recipientUSDCBalance - } + }; const postUSDCWithdrawalRecipientBalance = { usdc: recipientUSDCBalance + 1 - } + }; await tester.withBalanceCheck( UserSmartWalletV7.options.address, @@ -4556,7 +4560,7 @@ async function test(testingContext) { "call", [ 10, // DaiWithdrawal - "1000000000000000", + "1000000000000000000", tester.address, 0 ], @@ -4576,24 +4580,54 @@ async function test(testingContext) { tester.addressTwo ); - await tester.runTest( - "V7 UserSmartWallet relay can call with signature to withdraw dai", - UserSmartWalletV7, - "withdrawDai", - "send", + const preDAIWithdrawalBalance = { + dDaiUnderlying: 200 + }; + + const postDAIWithdrawalBalance = { + dDaiUnderlying: 199 + }; + + const recipientDAIBalance = (await tester.getBalances(tester.address)).dai; + + const preDAIWithdrawalRecipientBalance = { + dai: recipientDAIBalance + }; + + const postDAIWithdrawalRecipientBalance = { + dai: recipientDAIBalance + 1 + }; + + await tester.withBalanceCheck( + UserSmartWalletV7.options.address, + preDAIWithdrawalBalance, + postDAIWithdrawalBalance, + tester.withBalanceCheck, [ - "1000000000000000", tester.address, - 0, - daiUserWithdrawalSignature, - daiWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt.events) - }, - tester.originalAddress + preDAIWithdrawalRecipientBalance, + postDAIWithdrawalRecipientBalance, + tester.runTest, + [ + "V7 UserSmartWallet relay can call with two signatures to withdraw DAI", + UserSmartWalletV7, + "withdrawDai", + "send", + [ + "1000000000000000000", + tester.address, + 0, + daiUserWithdrawalSignature, + daiWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ] + ] ); await tester.runTest( @@ -6380,16 +6414,12 @@ async function test(testingContext) { tester.SAI, "approve", "send", - [tester.CSAI.options.address, web3.utils.toWei('100', 'ether')] + [tester.CSAI.options.address, web3.utils.toWei("100", "ether")] ); - await tester.runTest( - "mint cSai", - tester.CSAI_MINT, - "mint", - "send", - [web3.utils.toWei('100', 'ether')] - ); + await tester.runTest("mint cSai", tester.CSAI_MINT, "mint", "send", [ + web3.utils.toWei("100", "ether") + ]); // console.log(await tester.getBalances(tester.address)); @@ -6401,7 +6431,9 @@ async function test(testingContext) { [UserSmartWalletV7.options.address, web3.utils.toWei("1", "gwei")] ); - const walletBalance = await tester.getBalances(UserSmartWalletV7.options.address); + const walletBalance = await tester.getBalances( + UserSmartWalletV7.options.address + ); assert.strictEqual(walletBalance.cSai, 10.0); await tester.runTest( diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index 1430c1f..6ec16e6 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -788,29 +788,27 @@ class Tester { const initialBalances = await this.getBalances(account); const initialBalancesSet = new Set(Object.keys(initialBalances)); - //console.log(initialBalances) - const initialSet = new Set(Object.keys(initial)); const finalSet = new Set(Object.keys(final)); // Initial and final sets must both have the same balance checks. assert.strictEqual(initialSet.size, finalSet.size); assert.strictEqual( - initialSet.size, (new Set([...initialSet, ...finalSet])).size + initialSet.size, + new Set([...initialSet, ...finalSet]).size ); // Ensure that all the specified balance checks are actually returned. assert.strictEqual( - (new Set([...initialSet].filter( - x => !initialBalancesSet.has(x)) - )).size, + new Set([...initialSet].filter(x => !initialBalancesSet.has(x))) + .size, 0 ); // Get specified keys from balance check and compare to expected values. - const balanceChecks = [...(new Set([...initialSet].filter( - x => initialBalancesSet.has(x) - )))]; + const balanceChecks = [ + ...new Set([...initialSet].filter(x => initialBalancesSet.has(x))) + ]; for (const balance of balanceChecks) { assert.strictEqual(initial[balance], initialBalances[balance]); @@ -825,18 +823,20 @@ class Tester { for (const balance of balanceChecks) { assert.strictEqual(final[balance], finalBalances[balance]); - } + } } async getBalances(account) { - const balances = await this.BalanceChecker.methods.getBalances(account) + const balances = await this.BalanceChecker.methods + .getBalances(account) .call() .catch(error => { console.error(error); process.exit(1); }); - const underlyingBalances = await this.BalanceChecker.methods.getUnderlyingBalances(account) + const underlyingBalances = await this.BalanceChecker.methods + .getUnderlyingBalances(account) .call() .catch(error => { console.error(error); @@ -845,20 +845,57 @@ class Tester { return { account, - dDai: parseFloat(web3.utils.fromWei(balances.dDaiBalance, 'gwei')) * 10, - dUSDC: parseFloat(web3.utils.fromWei(balances.dUSDCBalance, 'gwei')) * 10, - dai: parseFloat(web3.utils.fromWei(balances.daiBalance, 'ether')), - usdc: parseFloat(web3.utils.fromWei(balances.usdcBalance, 'mwei')), - sai: parseFloat(web3.utils.fromWei(balances.saiBalance, 'ether')), - cSai: parseFloat(web3.utils.fromWei(balances.cSaiBalance, 'gwei')) * 10, - cDai: parseFloat(web3.utils.fromWei(balances.cDaiBalance, 'gwei')) * 10, - cUSDC: parseFloat(web3.utils.fromWei(balances.cUSDCBalance, 'gwei')) * 10, - ether: parseFloat(web3.utils.fromWei(balances.etherBalance, 'ether')), - dDaiUnderlying: parseFloat(web3.utils.fromWei(underlyingBalances.dDaiBalanceUnderlying, 'ether')), - dUSDCUnderlying: parseFloat(web3.utils.fromWei(underlyingBalances.dUSDCBalanceUnderlying, 'mwei')), - cSaiUnderlying: parseFloat(web3.utils.fromWei(underlyingBalances.cSaiBalanceUnderlying, 'ether')), - cDaiUnderlying: parseFloat(web3.utils.fromWei(underlyingBalances.cDaiBalanceUnderlying, 'ether')), - cUSDCUnderlying: parseFloat(web3.utils.fromWei(underlyingBalances.cUSDCBalanceUnderlying, 'mwei')), + dDai: + parseFloat(web3.utils.fromWei(balances.dDaiBalance, "gwei")) * + 10, + dUSDC: + parseFloat(web3.utils.fromWei(balances.dUSDCBalance, "gwei")) * + 10, + dai: parseFloat(web3.utils.fromWei(balances.daiBalance, "ether")), + usdc: parseFloat(web3.utils.fromWei(balances.usdcBalance, "mwei")), + sai: parseFloat(web3.utils.fromWei(balances.saiBalance, "ether")), + cSai: + parseFloat(web3.utils.fromWei(balances.cSaiBalance, "gwei")) * + 10, + cDai: + parseFloat(web3.utils.fromWei(balances.cDaiBalance, "gwei")) * + 10, + cUSDC: + parseFloat(web3.utils.fromWei(balances.cUSDCBalance, "gwei")) * + 10, + ether: parseFloat( + web3.utils.fromWei(balances.etherBalance, "ether") + ), + dDaiUnderlying: parseFloat( + web3.utils.fromWei( + underlyingBalances.dDaiBalanceUnderlying, + "ether" + ) + ), + dUSDCUnderlying: parseFloat( + web3.utils.fromWei( + underlyingBalances.dUSDCBalanceUnderlying, + "mwei" + ) + ), + cSaiUnderlying: parseFloat( + web3.utils.fromWei( + underlyingBalances.cSaiBalanceUnderlying, + "ether" + ) + ), + cDaiUnderlying: parseFloat( + web3.utils.fromWei( + underlyingBalances.cDaiBalanceUnderlying, + "ether" + ) + ), + cUSDCUnderlying: parseFloat( + web3.utils.fromWei( + underlyingBalances.cUSDCBalanceUnderlying, + "mwei" + ) + ), dDaiRaw: balances.dDaiBalance, dUSDCRaw: balances.dUSDCBalance, daiRaw: balances.daiBalance, @@ -1121,31 +1158,38 @@ class Tester { ); this.SAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.SAI_MAINNET_ADDRESS + IERC20Artifact.abi, + constants.SAI_MAINNET_ADDRESS ); this.DAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.DAI_MAINNET_ADDRESS + IERC20Artifact.abi, + constants.DAI_MAINNET_ADDRESS ); this.USDC = new web3.eth.Contract( - IERC20Artifact.abi, constants.USDC_MAINNET_ADDRESS + IERC20Artifact.abi, + constants.USDC_MAINNET_ADDRESS ); this.CSAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.CSAI_MAINNET_ADDRESS + IERC20Artifact.abi, + constants.CSAI_MAINNET_ADDRESS ); this.CSAI_MINT = new web3.eth.Contract( - CTokenInterfaceArtifact.abi, constants.CSAI_MAINNET_ADDRESS + CTokenInterfaceArtifact.abi, + constants.CSAI_MAINNET_ADDRESS ); this.CDAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.CDAI_MAINNET_ADDRESS + IERC20Artifact.abi, + constants.CDAI_MAINNET_ADDRESS ); this.CUSDC = new web3.eth.Contract( - IERC20Artifact.abi, constants.CUSDC_MAINNET_ADDRESS + IERC20Artifact.abi, + constants.CUSDC_MAINNET_ADDRESS ); this.DDAI = new web3.eth.Contract( From 8a6f82b4223fdc82d9c1b96f43e9701fd49bde31 Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Mon, 10 Feb 2020 15:22:10 -0800 Subject: [PATCH 38/47] add withdrawEther test --- scripts/test/test.js | 98 ++++++++++++++++++++++++++----------- scripts/test/testHelpers.js | 74 +++++++++++++++++++++++++--- 2 files changed, 136 insertions(+), 36 deletions(-) diff --git a/scripts/test/test.js b/scripts/test/test.js index a33d1f0..8e3d8e1 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -31,6 +31,8 @@ const DharmaKeyRingImplementationV1Artifact = require("../../build/contracts/Dha const contractNames = Object.assign({}, constants.CONTRACT_NAMES); +const ONE = web3.utils.toBN("1"); + async function test(testingContext) { const tester = new Tester(testingContext); await tester.init(); @@ -5693,7 +5695,7 @@ async function test(testingContext) { [ 6, // ETHWithdrawal, "1", - targetWalletAddress, + tester.address, 0 ], true, @@ -5712,24 +5714,57 @@ async function test(testingContext) { tester.addressTwo ); - await tester.runTest( - "V7 UserSmartWallet relay cannot withdraw eth to a non-payable account", - UserSmartWalletV7, - "withdrawEther", - "send", + const preETHwithdrawalBalance = { + etherRaw: "99999999999999996" + }; + + const postETHWithdrawalBalance = { + etherRaw: "99999999999999995" + }; + + const recipientETHBalance = (await tester.getBalances(tester.address)) + .etherRaw; + + const preETHWithdrawalRecipientBalance = { + etherRaw: recipientETHBalance + }; + + const recipientBalance = web3.utils.toBN(recipientETHBalance).add(ONE); + + const postETHWithdrawalRecipientBalance = { + etherRaw: recipientBalance.toString() + }; + + await tester.withBalanceCheck( + UserSmartWalletV7.options.address, + preETHwithdrawalBalance, + postETHWithdrawalBalance, + tester.withBalanceCheck, [ - "1", - targetWalletAddress, - 0, - ethUserWithdrawalSignature, - ethWithdrawalSignature - ], - true, - receipt => { - // TODO: verify logs - //console.log(receipt) - }, - tester.originalAddress + tester.address, + preETHWithdrawalRecipientBalance, + postETHWithdrawalRecipientBalance, + tester.runTest, + [ + "V7 UserSmartWallet relay can call with two signatures to withdraw ETH", + UserSmartWalletV7, + "withdrawEther", + "send", + [ + "1", + tester.address, + 0, + ethUserWithdrawalSignature, + ethWithdrawalSignature + ], + true, + receipt => { + // TODO: verify logs + //console.log(receipt) + }, + tester.originalAddress + ] + ] ); await tester.runTest( @@ -6671,7 +6706,7 @@ async function test(testingContext) { [UserSmartWalletV7.options.address, tester.addressTwo], true, value => { - assert.strictEqual(value, '0'); + assert.strictEqual(value, "0"); } ); @@ -6685,7 +6720,12 @@ async function test(testingContext) { "0x2d657fa5", // `modifyAllowanceViaMetaTransaction` web3.eth.abi.encodeParameters( ["address", "address", "uint256", "bool"], - [UserSmartWalletV7.options.address, tester.addressTwo, '1', true] + [ + UserSmartWalletV7.options.address, + tester.addressTwo, + "1", + true + ] ), 0, // No expiration constants.NULL_BYTES_32 // no salt @@ -6707,8 +6747,10 @@ async function test(testingContext) { tester.addressTwo ); - const messageHashBadSignature = '0xaaaaaaaa' + messageHashSignature.slice(10) - const messageHashBadUserSignature = '0xaaaaaaaa' + messageHashUserSignature.slice(10) + const messageHashBadSignature = + "0xaaaaaaaa" + messageHashSignature.slice(10); + const messageHashBadUserSignature = + "0xaaaaaaaa" + messageHashUserSignature.slice(10); await tester.runTest( `dUSDC allowance is not modifiable via meta-transaction with bad signature length`, @@ -6718,11 +6760,11 @@ async function test(testingContext) { [ UserSmartWalletV7.options.address, tester.addressTwo, - '1', + "1", true, 0, constants.NULL_BYTES_32, - messageHashSignature + messageHashUserSignature.slice(2) + 'aa' + messageHashSignature + messageHashUserSignature.slice(2) + "aa" ], false ); @@ -6735,7 +6777,7 @@ async function test(testingContext) { [ UserSmartWalletV7.options.address, tester.addressTwo, - '1', + "1", true, 0, constants.NULL_BYTES_32, @@ -6752,7 +6794,7 @@ async function test(testingContext) { [ UserSmartWalletV7.options.address, tester.addressTwo, - '1', + "1", true, 0, constants.NULL_BYTES_32, @@ -6769,7 +6811,7 @@ async function test(testingContext) { [ UserSmartWalletV7.options.address, tester.addressTwo, - '1', + "1", true, 0, constants.NULL_BYTES_32, @@ -6789,7 +6831,7 @@ async function test(testingContext) { [UserSmartWalletV7.options.address, tester.addressTwo], true, value => { - assert.strictEqual(value, '1'); + assert.strictEqual(value, "1"); } ); diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index 6ec16e6..a349644 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -811,7 +811,7 @@ class Tester { ]; for (const balance of balanceChecks) { - assert.strictEqual(initial[balance], initialBalances[balance]); + assert.strictEqual(initialBalances[balance], initial[balance]); } // Run the test. @@ -1193,24 +1193,82 @@ class Tester { ); this.DDAI = new web3.eth.Contract( - IERC20Artifact.abi, constants.DDAI_MAINNET_ADDRESS + IERC20Artifact.abi, + constants.DDAI_MAINNET_ADDRESS ); this.DUSDC = new web3.eth.Contract( - IERC20Artifact.abi, constants.DUSDC_MAINNET_ADDRESS + IERC20Artifact.abi, + constants.DUSDC_MAINNET_ADDRESS ); const MetaABI = [ - {"constant":false,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bool","name":"increase","type":"bool"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes","name":"signatures","type":"bytes"}],"name":"modifyAllowanceViaMetaTransaction","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}, - {"constant":true,"inputs":[{"internalType":"bytes4","name":"functionSelector","type":"bytes4"},{"internalType":"bytes","name":"arguments","type":"bytes"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"getMetaTransactionMessageHash","outputs":[{"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"internalType":"bool","name":"valid","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"} - ] + { + constant: false, + inputs: [ + { internalType: "address", name: "owner", type: "address" }, + { + internalType: "address", + name: "spender", + type: "address" + }, + { internalType: "uint256", name: "value", type: "uint256" }, + { internalType: "bool", name: "increase", type: "bool" }, + { + internalType: "uint256", + name: "expiration", + type: "uint256" + }, + { internalType: "bytes32", name: "salt", type: "bytes32" }, + { internalType: "bytes", name: "signatures", type: "bytes" } + ], + name: "modifyAllowanceViaMetaTransaction", + outputs: [ + { internalType: "bool", name: "success", type: "bool" } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "bytes4", + name: "functionSelector", + type: "bytes4" + }, + { internalType: "bytes", name: "arguments", type: "bytes" }, + { + internalType: "uint256", + name: "expiration", + type: "uint256" + }, + { internalType: "bytes32", name: "salt", type: "bytes32" } + ], + name: "getMetaTransactionMessageHash", + outputs: [ + { + internalType: "bytes32", + name: "messageHash", + type: "bytes32" + }, + { internalType: "bool", name: "valid", type: "bool" } + ], + payable: false, + stateMutability: "view", + type: "function" + } + ]; this.DDAI_META = new web3.eth.Contract( - MetaABI, constants.DDAI_MAINNET_ADDRESS + MetaABI, + constants.DDAI_MAINNET_ADDRESS ); this.DUSDC_META = new web3.eth.Contract( - MetaABI, constants.DUSDC_MAINNET_ADDRESS + MetaABI, + constants.DUSDC_MAINNET_ADDRESS ); this.BadBeaconDeployer = this.newDeployer(BadBeaconArtifact); From dcb6871112043bcf9ec3ab952b8fec87036a070b Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Mon, 10 Feb 2020 17:21:20 -0800 Subject: [PATCH 39/47] add escape hatch --- scripts/test/test.js | 88 ++++++++++++++++++++++++++++++++----- scripts/test/testHelpers.js | 2 +- 2 files changed, 79 insertions(+), 11 deletions(-) diff --git a/scripts/test/test.js b/scripts/test/test.js index 8e3d8e1..f075435 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -6286,18 +6286,86 @@ async function test(testingContext) { tester.originalAddress ); - await tester.runTest( - "V7 UserSmartWallet escape hatch account can call escape", - UserSmartWalletV7, - "escape", - "send", - [], - true, - receipt => { - // TODO: verify logs - }, + const allPreEscapeBalances = await tester.getBalances( + UserSmartWalletV7.options.address + ); + const preEscapeBalances = { + dDai: allPreEscapeBalances.dDai, + dUSDC: allPreEscapeBalances.dUSDC, + dai: allPreEscapeBalances.dai, + usdc: allPreEscapeBalances.usdc, + sai: allPreEscapeBalances.sai, + cDai: allPreEscapeBalances.cDai, + cUSDC: allPreEscapeBalances.cUSDC, + cSai: allPreEscapeBalances.cSai + // TODO: test raw balances + }; + + const postEscapeBalances = { + dDai: 0, + dUSDC: 0, + dai: 0, + usdc: 0, + sai: 0, + cDai: 0, + cUSDC: 0, + cSai: 0 + }; + + const allRecipientPreEscapeBalances = await tester.getBalances( tester.address ); + const recipientPreEscapeBalances = { + dDai: allRecipientPreEscapeBalances.dDai, + dUSDC: allRecipientPreEscapeBalances.dUSDC, + dai: allRecipientPreEscapeBalances.dai, + usdc: allRecipientPreEscapeBalances.usdc, + sai: allRecipientPreEscapeBalances.sai, + cDai: allRecipientPreEscapeBalances.cDai, + cUSDC: allRecipientPreEscapeBalances.cUSDC, + cSai: allRecipientPreEscapeBalances.cSai + // TODO: test raw balances + }; + let recipientPostEscapeBalances = {}; + + // Add all pre-escape balances, to recipient current balances + for (let token of Object.keys(preEscapeBalances)) { + recipientPostEscapeBalances[token] = + preEscapeBalances[token] + recipientPreEscapeBalances[token]; + } + + // Correct dToken and underlying values since dTokens get converted to underlying. + recipientPostEscapeBalances["dai"] = + recipientPostEscapeBalances["dai"] + preEscapeBalances["dDai"]; + recipientPostEscapeBalances["usdc"] = + recipientPostEscapeBalances["usdc"] + preEscapeBalances["dUSDC"]; + recipientPostEscapeBalances["dDai"] = 0; + recipientPostEscapeBalances["dUSDC"] = 0; + + await tester.withBalanceCheck( + UserSmartWalletV7.options.address, + preEscapeBalances, + postEscapeBalances, + tester.withBalanceCheck, + [ + tester.address, + recipientPreEscapeBalances, + recipientPostEscapeBalances, + tester.runTest, + [ + "V7 UserSmartWallet escape hatch account can call escape", + UserSmartWalletV7, + "escape", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.address + ] + ] + ); await tester.runTest( "V7 UserSmartWallet escape hatch account can call escape again", diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index a349644..e1ea545 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -822,7 +822,7 @@ class Tester { const fiinalBalancesSet = new Set(Object.keys(finalBalances)); for (const balance of balanceChecks) { - assert.strictEqual(final[balance], finalBalances[balance]); + assert.strictEqual(finalBalances[balance], final[balance]); } } From 06048dd3c902215790729a58c680d3bc5474057a Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Mon, 10 Feb 2020 18:17:24 -0800 Subject: [PATCH 40/47] add migrateCDaiToDDai and migrateCUSDCToDUSDC --- scripts/test/test.js | 99 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 77 insertions(+), 22 deletions(-) diff --git a/scripts/test/test.js b/scripts/test/test.js index f075435..15bc2a3 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -32,6 +32,7 @@ const DharmaKeyRingImplementationV1Artifact = require("../../build/contracts/Dha const contractNames = Object.assign({}, constants.CONTRACT_NAMES); const ONE = web3.utils.toBN("1"); +const ZERO = web3.utils.toBN("0"); async function test(testingContext) { const tester = new Tester(testingContext); @@ -6573,17 +6574,44 @@ async function test(testingContext) { [UserSmartWalletV7.options.address, web3.utils.toWei("1", "mwei")] ); - await tester.runTest( - "V7 UserSmartWallet relay can trigger cDai to dDai migration", - UserSmartWalletV7, - "migrateCDaiToDDai", - "send", - [], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress + let allPreMigrationBalances = await tester.getBalances( + UserSmartWalletV7.options.address + ); + + const dDaiUnderlyingRaw = web3.utils.toBN( + allPreMigrationBalances.dDaiUnderlyingRaw + ); + const cDaiUnderlyingRaw = web3.utils.toBN( + allPreMigrationBalances.cDaiUnderlyingRaw + ); + let preMigrationBalances = { + dDaiUnderlyingRaw: dDaiUnderlyingRaw.toString(), + cDaiUnderlyingRaw: cDaiUnderlyingRaw.toString() + }; + + const postDDaiUnderlyingRaw = dDaiUnderlyingRaw.add(cDaiUnderlyingRaw); + let postMigrationBalances = { + dDaiUnderlyingRaw: postDDaiUnderlyingRaw.toString(), + cDaiUnderlyingRaw: ZERO.toString() + }; + + await tester.withBalanceCheck( + UserSmartWalletV7.options.address, + preMigrationBalances, + postMigrationBalances, + tester.runTest, + [ + "V7 UserSmartWallet relay can trigger cDai to dDai migration", + UserSmartWalletV7, + "migrateCDaiToDDai", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ] ); await tester.runTest( @@ -6615,17 +6643,44 @@ async function test(testingContext) { [UserSmartWalletV7.options.address, web3.utils.toWei("1", "lovelace")] ); - await tester.runTest( - "V7 UserSmartWallet relay can trigger cUSDC to dUSDC migration", - UserSmartWalletV7, - "migrateCUSDCToDUSDC", - "send", - [], - true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress + allPreMigrationBalances = await tester.getBalances( + UserSmartWalletV7.options.address + ); + + const dUSDCUnderlyingRaw = web3.utils.toBN( + allPreMigrationBalances.dUSDCUnderlyingRaw + ); + const cUSDCUnderlyingRaw = web3.utils.toBN( + allPreMigrationBalances.cUSDCUnderlyingRaw + ); + preMigrationBalances = { + dUSDCUnderlyingRaw: dUSDCUnderlyingRaw.toString(), + cUSDCUnderlyingRaw: cUSDCUnderlyingRaw.toString() + }; + + const postDUSDCUnderlyingRaw = dUSDCUnderlyingRaw.add(cUSDCUnderlyingRaw); + postMigrationBalances = { + dUSDCUnderlyingRaw: postDUSDCUnderlyingRaw.toString(), + cUSDCUnderlyingRaw: ZERO.toString() + }; + + await tester.withBalanceCheck( + UserSmartWalletV7.options.address, + preMigrationBalances, + postMigrationBalances, + tester.runTest, + [ + "V7 UserSmartWallet relay can trigger cDai to dDai migration", + UserSmartWalletV7, + "migrateCUSDCToDUSDC", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ] ); await tester.runTest( From 7fbedcab0536168bab1723cb508ffdf73c4a83b2 Mon Sep 17 00:00:00 2001 From: 0age <0age@protonmail.com> Date: Tue, 11 Feb 2020 13:53:06 -0500 Subject: [PATCH 41/47] update README with v6 & v7 information --- README.md | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 10f50a7..6860331 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ > An upgradeable, meta-transaction-enabled smart wallet for earning interest on stablecoins while retaining custody of funds, with an added security backstop provided by Dharma Labs. -[![Smart Wallet Version](https://img.shields.io/endpoint?url=https%3A%2F%2Fdharma-version-api.netlify.com%2F.netlify%2Ffunctions%2Fserver%3Ftarget%3Dsmartwallet)](https://etherscan.io/address/0x00000000001f2bec34d4a98c839cf711afc842c6#code) +[![Smart Wallet Version](https://img.shields.io/endpoint?url=https%3A%2F%2Fdharma-version-api.netlify.com%2F.netlify%2Ffunctions%2Fserver%3Ftarget%3Dsmartwallet)](https://etherscan.io/address/0x0000000000ab32e9e7bd6bd3c37a7e99fb8c2d43#code) [![Key Ring Version](https://img.shields.io/endpoint?url=https%3A%2F%2Fdharma-version-api.netlify.com%2F.netlify%2Ffunctions%2Fserver%3Ftarget%3Dkeyring)](https://etherscan.io/address/0x00000000ea0007cdab60e07437e59e9cc41c2e49#code) [![License](https://img.shields.io/github/license/dharma-eng/dharma-smart-wallet.svg)](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/LICENSE.md) [![Build Status](https://img.shields.io/travis/dharma-eng/dharma-smart-wallet)](https://travis-ci.org/dharma-eng/dharma-smart-wallet) @@ -15,7 +15,7 @@ ## Summary The **Dharma Smart Wallet** is a 2/2 "multisig" smart contract, controlled by the user's Dharma Key Ring and by Dharma Labs, that: -- allows users to **make deposits and mint cDai or cUSDC from Compound** by simply sending Dai or USDC to their smart wallet address, even **before a contract has been deployed** to that address +- allows users to **make deposits and mint [Dharma Dai or Dharma USD Coin](https://github.com/dharma-eng/dharma-token)** by simply sending Dai or USDC to their smart wallet address, even **before a contract has been deployed** to that address - allows users to **make Dai or USDC withdrawals without paying for gas**, by providing signed messages that are validated against both the user's **Dharma Key Ring contract** and against the **Dharma Key Registry** and relayed by Dharma - allows users to **recover their account if access is lost or compromised** after a three-day timelock, or to opt out of account recovery entirely, via the **Account Recovery Manager** - allows for **upgrades to all user smart wallets at once**, without requiring any action on behalf of the user, and with a seven-day timelock prior to each upgrade, using the **Upgrade Beacon Controller Manager** @@ -28,6 +28,7 @@ The **Dharma Key Ring** is an N/M "multisig" smart contract, controlled and conf These contracts have been audited by Trail of Bits - see their security assessment for more information. + ## Table of Contents - [Contract Deployment Addresses and Verified Source Code](#contract-deployment-addresses-and-verified-source-code) - [Overview](#overview) @@ -36,34 +37,35 @@ These contracts have been audited by Trail of Bits - DharmaUpgradeBeaconControllerManager | Dharma Smart Wallet | Dharma Smart Wallet | -| DharmaUpgradeBeaconController | AdharmaSmartWalletImplementation | DharmaSmartWalletFactoryV1 | -| DharmaUpgradeBeacon | DharmaSmartWalletImplementationV1 | [DharmaSmartWalletFactoryV2](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/factories/smart-wallet/DharmaSmartWalletFactoryV2.sol) | -| DharmaKeyRingUpgradeBeaconController | DharmaSmartWalletImplementationV2 | | -| DharmaKeyRingUpgradeBeacon | DharmaSmartWalletImplementationV3 | Dharma Key Ring | -| DharmaUpgradeBeaconEnvoy | DharmaSmartWalletImplementationV4 | DharmaKeyRingFactoryV1 | -| DharmaKeyRegistryV1 | DharmaSmartWalletImplementationV5 | DharmaKeyRingFactoryV2 | -| DharmaKeyRegistryV2 | Dharma Key Ring | [DharmaKeyRingFactoryV3](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/factories/key-ring/DharmaKeyRingFactoryV3.sol) | +| DharmaUpgradeBeaconControllerManager | AdharmaSmartWalletImplementation | DharmaSmartWalletFactoryV1 | +| DharmaUpgradeBeaconController |DharmaSmartWalletImplementationV1 | [DharmaSmartWalletFactoryV2](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/factories/smart-wallet/DharmaSmartWalletFactoryV2.sol) | +| DharmaUpgradeBeacon | DharmaSmartWalletImplementationV2 | | +| DharmaKeyRingUpgradeBeaconController | DharmaSmartWalletImplementationV3 | | +| DharmaKeyRingUpgradeBeacon | DharmaSmartWalletImplementationV4 | | +| DharmaUpgradeBeaconEnvoy | DharmaSmartWalletImplementationV5 | DharmaKeyRingFactoryV1 | +| DharmaKeyRegistryV1 | DharmaSmartWalletImplementationV6 | DharmaKeyRingFactoryV2 | +| DharmaKeyRegistryV2 | DharmaSmartWalletImplementationV7 | [DharmaKeyRingFactoryV3](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/factories/key-ring/DharmaKeyRingFactoryV3.sol) | | DharmaAccountRecoveryManagerV2 | AdharmaKeyRingImplementation | | | DharmaEscapeHatchRegistry | DharmaKeyRingImplementationV1 | | + ## Overview The Dharma Smart Wallet and Dharma Key Ring are designed with the following assumptions in mind: - Dharma users will **share custody** of their smart wallet, with Dharma Labs serving as a **security backstop**, in order to better protect their funds from loss and from external adversaries and to simplify the process of earning interest on their stablecoins. The security backstop gives users the liberty to store keys in contexts that would be insufficient taken in isolation, such as in their web browser, while still maintaining non-custodial assurances that, were Dharma's key to ever become compromised, their funds would stay securely in their possession. If users decide they would rather use a fully self-custodial wallet and handle the details themselves, they will migrate away from the smart wallet by transferring their funds to a new address, or wait for upgrades to the smart wallet that unlock options for greater degrees of self-custody. - Users are content to **let Dharma make upgrades to their smart wallets**, and do not require opt-in upgrades. However, a seven-day timelock on upgrades will let users "opt-out" of unwanted upgrades by giving them a window of time to withdraw their funds from the smart wallet. - The initial wallet implementation uses a **subsidized meta-transaction mechanism**, where Dharma pays for the gas - in other words, there is no need to implement strict gas metering or extra fees in order to pay the transaction relayer back (as a matter of fact, **the user won't have to deal with gas or transaction submissions at all**). - The wallet validates protected actions using **standard ethereum message signatures** (ECDSA + ecrecover + EIP-191) with **replay protection** baked in. Additionally, the Dharma Smart Wallet supports EIP-1271, which allows for the Dharma Key Ring to hold multiple signing keys and to eventually support per-key and per-action-type permissions and thresholds. -- The smart wallet is **not set up to do anything too fancy**, like deploy contracts or run arbitrary code - it only needs to be able to make transfers and calls into other contract accounts. In particular, interactions with Compound V2 are mediated via custom, streamlined functions. +- The smart wallet is **not set up to do anything too fancy**, like deploy contracts or run arbitrary code - it only needs to be able to make transfers and calls into other contract accounts. In particular, interactions with Dharma Tokens and Compound V2 contracts are mediated via custom, streamlined functions. ### Dharma Smart Wallet -The current implementation of the [Dharma Smart Wallet](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV3.sol) works as follows: -- Smart wallet deployments and stablecoin deposits can be initiated by anyone who is willing to pay the gas. Smart wallet addresses are counterfactual based on the initial user signing key, and can be safely deployed by anyone using a [Dharma Smart Wallet Factory](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/factories/smart-wallet/DharmaSmartWalletFactoryV2.sol), as withdrawals will atomically redeem and transfer the relevant stablecoin. Therefore, expect any Dai or USDC sent to the smart wallet address to quickly be converted to cDAI or cUSDC. +The current implementation of the [Dharma Smart Wallet](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV6.sol) works as follows: +- Smart wallet deployments and stablecoin deposits can be initiated by anyone who is willing to pay the gas. Smart wallet addresses are counterfactual based on the initial user signing key, and can be safely deployed by anyone using a [Dharma Smart Wallet Factory](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/factories/smart-wallet/DharmaSmartWalletFactoryV1.sol), as withdrawals will atomically redeem and transfer the relevant stablecoin. Therefore, expect any Dai or USDC sent to the smart wallet address to quickly be converted to dDAI or dUSDC. - Every withdrawal requires signatures from both the user **and** from Dharma Labs in order to be accepted. The signature component from the user is validated against their Dharma Key Ring, and the signature component from Dharma Labs is validated against the [Dharma Key Registry](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/registries/DharmaKeyRegistryV2.sol). Either party may cancel a given signature at any time prior to execution. -- The [Dharma Account Recovery Manager](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/account-recovery/DharmaAccountRecoveryManager.sol) will only be used in the event that a user has lost access to their Dharma Key Ring or it has been compromised - it will not have any other control over the user's smart wallet. Furthermore, the Account Recovery Manager enforces a three-day timelock before any account can be recovered. A user can also permanently opt out of account recovery through the Account Recovery Manager, though this is not recommended unless the user is highly confident in their own key management. +- The [Dharma Account Recovery Manager](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/account-recovery/DharmaAccountRecoveryManagerV2.sol) will only be used in the event that a user has lost access to their Dharma Key Ring or it has been compromised - it will not have any other control over the user's smart wallet. Furthermore, the Account Recovery Manager enforces a three-day timelock before any account can be recovered. A user can also permanently opt out of account recovery through the Account Recovery Manager, though this is not recommended unless the user is highly confident in their own key management. - Both required signatures must be provided at the same time - this enables actions to be taken in a single transaction, and also lets an account that is not a signatory on the wallet submit the transaction and pay for the gas. One of the signatures can be omitted if the submitting account _is_ a valid signatory. - To protect against replay attacks, every call to the smart wallet will include a nonce that must match the current nonce on the smart wallet, as well as an optional minimum gas amount, and each time the smart wallet is called with enough gas and valid signatures that nonce will be incremented. This applies even when the action being taken by the smart wallet reverts, in which case an event will be emitted. - Additional features will be rolled out incrementally, like the ability to assume greater degrees of self-custody over the smart wallet or to designate alternate recovery mechanisms for the smart wallet. @@ -74,7 +76,7 @@ The Dharma Smart Wallet is controlled by the [Dharma Key Ring](https://github.co - It differentiates between two primary key types (note that "dual" keys can be both types at once): - Admin keys, which are used to add or remove other keys and to change thresholds or other properties of the key ring - Standard keys, which are used to verify most external signatures that it receives based on the data provided (notably, attempts to set a new user signing key for the smart wallet must provide signatures from Admin keys) -- Key Ring addresses are _also_ counterfactual, based on their initial signing key, and are only deployed once they are needed to make a withdrawal or to add an additional key. They can be deployed by anyone, using a [Dharma Key Ring Factory](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/factories/key-ring/DharmaKeyRingFactoryV3.sol) - furthermore, anyone can deploy their own Dharma Key Ring for use in other applications. +- Key Ring addresses are _also_ counterfactual, based on their initial signing key, and are only deployed once they are needed to make a withdrawal or to add an additional key. They can be deployed by anyone, using a [Dharma Key Ring Factory](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/factories/key-ring/DharmaKeyRingFactoryV2.sol) - furthermore, anyone can deploy their own Dharma Key Ring for use in other applications. - All required signatures must be provided at the same time - this enables actions to be taken in a single transaction. Provided signatures must be ordered based on the signing address, from lowest to highest, in order to be considered valid. - To protect against replay attacks, every call to the key ring to execute an Admin action will include a nonce that must match the current nonce on the key ring, and each time the smart wallet is called with enough gas and valid signatures that nonce will be incremented. Note that gas is not an input to signatures on the key ring, since there are no external calls made by the key ring during execution, so calls with insufficient gas can be replayed until they succeed or until another admin action is taken that increments the nonce. @@ -90,6 +92,7 @@ Both the Dharma Smart Wallet and the Dharma Key Ring are upgradeable: - Prior to each upgrade, a prospective implementation needs to first be deployed and registered as a potential upgrade candidate. This gives the community a chance to review the implementation, and to raise any potential concerns or opt-out of the upgrade by withdrawing their funds. - The Dharma Escape Hatch is an opt-in feature that enables a smart wallet to call into the [Dharma Escape Hatch Registry](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/registries/DharmaEscapeHatchRegistry.sol) and designate an "escape hatch" account that can sweep the entire balance from the wallet by [calling into the `escape()` function](https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV4.sol#L728) directly. This gives users with an existing, secure key the option to exit the system at any point without needing to first secure Dharma's approval. + ## Install To install locally, you'll need Node.js 10 through 12 and Yarn *(or npm)*. To get everything set up: ```sh @@ -99,6 +102,7 @@ $ yarn install $ yarn build ``` + ## Usage To run tests locally, start the testRPC, trigger the tests, run the linter, and tear down the testRPC *(you can do all of this at once via* `yarn all` *if you prefer)*: ```sh @@ -127,6 +131,7 @@ $ yarn build $ yarn forkCoverage ``` + ## Example Contracts and Notable Transactions Example Contracts: - Example UpgradeBeaconProxyV1 smart wallet instance @@ -148,6 +153,8 @@ Notable Transactions: - Upgrade Beacon Controller Manager ownership transferred to multisig - Dharma Account Recovery Manager V2 ownership transferred to multisig - V5 implementation set on Smart Wallet Upgrade Beacon +- V6 implementation set on Smart Wallet Upgrade Beacon + ## Additional Information Have any questions or feedback? Join the conversation in the Dharma_HQ Discord server. Also, see the "Why Smart Wallets Should Catch Your Interest" article for a more informal discussion around some of the motivations, features, and design decisions of the Dharma Smart Wallet. From 44cce9ecf983e288aa306ba84cc1a0fe6bba3082 Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Tue, 11 Feb 2020 11:04:08 -0800 Subject: [PATCH 42/47] migrateCSaiToDDai and small cDai mint failure --- scripts/test/test.js | 101 +++++++++++++++++++++++++++++++----- scripts/test/testHelpers.js | 1 - 2 files changed, 87 insertions(+), 15 deletions(-) diff --git a/scripts/test/test.js b/scripts/test/test.js index 15bc2a3..6d03178 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -6541,18 +6541,70 @@ async function test(testingContext) { assert.strictEqual(walletBalance.cSai, 10.0); await tester.runTest( - "V7 UserSmartWallet relay can trigger cSai to dDai migration", + "V7 UserSmartWallet can get next generic action ID", UserSmartWalletV7, - "migrateCSaiToDDai", - "send", - [], + "getNextGenericActionID", + "call", + [tester.address, "0x", 0], true, - receipt => { - // TODO: verify logs - }, - tester.originalAddress + value => { + genericActionID = value; + } + ); + + let allPreMigrationBalances = await tester.getBalances( + UserSmartWalletV7.options.address ); + let dDaiUnderlyingRaw = web3.utils.toBN( + allPreMigrationBalances.dDaiUnderlyingRaw + ); + let cSaiUnderlyingRaw = web3.utils.toBN( + allPreMigrationBalances.cSaiUnderlyingRaw + ); + let preMigrationBalances = { + dDaiUnderlyingRaw: dDaiUnderlyingRaw.toString(), + cSaiUnderlyingRaw: cSaiUnderlyingRaw.toString() + }; + + let postDDaiUnderlyingRaw = dDaiUnderlyingRaw.add(cSaiUnderlyingRaw); + let postMigrationBalances = { + dDaiUnderlyingRaw: postDDaiUnderlyingRaw.toString(), + cSaiUnderlyingRaw: ZERO.toString() + }; + + await tester.withBalanceCheck( + UserSmartWalletV7.options.address, + preMigrationBalances, + postMigrationBalances, + tester.runTest, + [ + "V7 UserSmartWallet relay can trigger cSai to dDai migration", + UserSmartWalletV7, + "migrateCSaiToDDai", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ] + ); + + // await tester.runTest( + // "V7 UserSmartWallet relay can trigger cSai to dDai migration", + // UserSmartWalletV7, + // "migrateCSaiToDDai", + // "send", + // [], + // true, + // receipt => { + // // TODO: verify logs + // }, + // tester.originalAddress + // ); + await tester.runTest( "V7 UserSmartWallet relay can trigger cSai to dDai migration again (no-op)", UserSmartWalletV7, @@ -6574,23 +6626,23 @@ async function test(testingContext) { [UserSmartWalletV7.options.address, web3.utils.toWei("1", "mwei")] ); - let allPreMigrationBalances = await tester.getBalances( + allPreMigrationBalances = await tester.getBalances( UserSmartWalletV7.options.address ); - const dDaiUnderlyingRaw = web3.utils.toBN( + dDaiUnderlyingRaw = web3.utils.toBN( allPreMigrationBalances.dDaiUnderlyingRaw ); - const cDaiUnderlyingRaw = web3.utils.toBN( + let cDaiUnderlyingRaw = web3.utils.toBN( allPreMigrationBalances.cDaiUnderlyingRaw ); - let preMigrationBalances = { + preMigrationBalances = { dDaiUnderlyingRaw: dDaiUnderlyingRaw.toString(), cDaiUnderlyingRaw: cDaiUnderlyingRaw.toString() }; - const postDDaiUnderlyingRaw = dDaiUnderlyingRaw.add(cDaiUnderlyingRaw); - let postMigrationBalances = { + postDDaiUnderlyingRaw = dDaiUnderlyingRaw.add(cDaiUnderlyingRaw); + postMigrationBalances = { dDaiUnderlyingRaw: postDDaiUnderlyingRaw.toString(), cDaiUnderlyingRaw: ZERO.toString() }; @@ -6614,6 +6666,27 @@ async function test(testingContext) { ] ); + await tester.runTest( + "Smal amount of cDai can be sent to V7 UserSmartWallet", + tester.CDAI, + "transfer", + "send", + [UserSmartWalletV7.options.address, web3.utils.toWei("1", "wei")] + ); + + await tester.runTest( + "V7 UserSmartWallet cDai to dDai migration fails with a small amount of cDai", + UserSmartWalletV7, + "migrateCDaiToDDai", + "send", + [], + false, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ); + await tester.runTest( "cDai can be sent to V7 UserSmartWallet again", tester.CDAI, diff --git a/scripts/test/testHelpers.js b/scripts/test/testHelpers.js index e1ea545..acb0eef 100644 --- a/scripts/test/testHelpers.js +++ b/scripts/test/testHelpers.js @@ -819,7 +819,6 @@ class Tester { // Get the final balances. const finalBalances = await this.getBalances(account); - const fiinalBalancesSet = new Set(Object.keys(finalBalances)); for (const balance of balanceChecks) { assert.strictEqual(finalBalances[balance], final[balance]); From 26aaf6b8cbb134c9ada5cc46df9d6ed6c6ce6e77 Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Tue, 11 Feb 2020 11:08:23 -0800 Subject: [PATCH 43/47] typo --- scripts/test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/test/test.js b/scripts/test/test.js index 6d03178..e51c687 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -6667,7 +6667,7 @@ async function test(testingContext) { ); await tester.runTest( - "Smal amount of cDai can be sent to V7 UserSmartWallet", + "Small amount of cDai can be sent to V7 UserSmartWallet", tester.CDAI, "transfer", "send", From 25a04d8432adad518f6d8f4a157e8bc0d0b119c2 Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Tue, 11 Feb 2020 11:24:34 -0800 Subject: [PATCH 44/47] approve --- scripts/test/test.js | 92 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/scripts/test/test.js b/scripts/test/test.js index e51c687..b108998 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -6666,6 +6666,98 @@ async function test(testingContext) { ] ); + await tester.runTest( + "V7 UserSmartWallet can get a generic action ID", + UserSmartWalletV7, + "getNextGenericActionID", + "call", + [ + tester.DAI.options.address, + tester.DAI.methods + .approve(tester.DDAI.options.address, 0) + .encodeABI(), + 0 + ], + true, + value => { + customActionId = value; + } + ); + + executeActionSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.address + ); + + executeActionUserSignature = tester.signHashedPrefixedHexString( + customActionId, + tester.addressTwo + ); + + await tester.runTest( + "V7 UserSmartWallet can call executeAction", + UserSmartWalletV7, + "executeAction", + "send", + [ + tester.DAI.options.address, + tester.DAI.methods + .approve(tester.DDAI.options.address, 0) + .encodeABI(), + 0, + executeActionUserSignature, + executeActionSignature + ] + ); + + await tester.runTest( + "cDai can be sent to V7 UserSmartWallet", + tester.CDAI, + "transfer", + "send", + [UserSmartWalletV7.options.address, web3.utils.toWei("1", "mwei")] + ); + + allPreMigrationBalances = await tester.getBalances( + UserSmartWalletV7.options.address + ); + + dDaiUnderlyingRaw = web3.utils.toBN( + allPreMigrationBalances.dDaiUnderlyingRaw + ); + cDaiUnderlyingRaw = web3.utils.toBN( + allPreMigrationBalances.cDaiUnderlyingRaw + ); + preMigrationBalances = { + dDaiUnderlyingRaw: dDaiUnderlyingRaw.toString(), + cDaiUnderlyingRaw: cDaiUnderlyingRaw.toString() + }; + + postDDaiUnderlyingRaw = dDaiUnderlyingRaw.add(cDaiUnderlyingRaw); + postMigrationBalances = { + dDaiUnderlyingRaw: postDDaiUnderlyingRaw.toString(), + cDaiUnderlyingRaw: ZERO.toString() + }; + + await tester.withBalanceCheck( + UserSmartWalletV7.options.address, + preMigrationBalances, + postMigrationBalances, + tester.runTest, + [ + "V7 UserSmartWallet relay can trigger cDai to dDai migration after allowance is 0", + UserSmartWalletV7, + "migrateCDaiToDDai", + "send", + [], + true, + receipt => { + // TODO: verify logs + }, + tester.originalAddress + ] + ); + await tester.runTest( "Small amount of cDai can be sent to V7 UserSmartWallet", tester.CDAI, From 7b31030859335067fde05437d5da6e83828b6362 Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Tue, 11 Feb 2020 11:44:32 -0800 Subject: [PATCH 45/47] allowance -> 0 --- scripts/test/test.js | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/scripts/test/test.js b/scripts/test/test.js index b108998..700c597 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -6592,19 +6592,6 @@ async function test(testingContext) { ] ); - // await tester.runTest( - // "V7 UserSmartWallet relay can trigger cSai to dDai migration", - // UserSmartWalletV7, - // "migrateCSaiToDDai", - // "send", - // [], - // true, - // receipt => { - // // TODO: verify logs - // }, - // tester.originalAddress - // ); - await tester.runTest( "V7 UserSmartWallet relay can trigger cSai to dDai migration again (no-op)", UserSmartWalletV7, @@ -6711,8 +6698,20 @@ async function test(testingContext) { ); await tester.runTest( - "cDai can be sent to V7 UserSmartWallet", - tester.CDAI, + "Check DAI allowance from DDAI is 0", + tester.DAI, + "allowance", + "call", + [UserSmartWalletV7.options.address, tester.DDAI.options.address], + true, + value => { + assert.strictEqual(value, ZERO.toString()); + } + ); + + await tester.runTest( + "cSai can be sent to V7 UserSmartWallet", + tester.CSAI, "transfer", "send", [UserSmartWalletV7.options.address, web3.utils.toWei("1", "mwei")] From 9016a2f3cfb9f506ac9147db21b2be77c931f08b Mon Sep 17 00:00:00 2001 From: Carlos Flores Date: Tue, 11 Feb 2020 11:58:46 -0800 Subject: [PATCH 46/47] hit require --- scripts/test/test.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/test/test.js b/scripts/test/test.js index 700c597..59dec0f 100644 --- a/scripts/test/test.js +++ b/scripts/test/test.js @@ -6724,18 +6724,18 @@ async function test(testingContext) { dDaiUnderlyingRaw = web3.utils.toBN( allPreMigrationBalances.dDaiUnderlyingRaw ); - cDaiUnderlyingRaw = web3.utils.toBN( - allPreMigrationBalances.cDaiUnderlyingRaw + cSaiUnderlyingRaw = web3.utils.toBN( + allPreMigrationBalances.cSaiUnderlyingRaw ); preMigrationBalances = { dDaiUnderlyingRaw: dDaiUnderlyingRaw.toString(), - cDaiUnderlyingRaw: cDaiUnderlyingRaw.toString() + cSaiUnderlyingRaw: cSaiUnderlyingRaw.toString() }; - postDDaiUnderlyingRaw = dDaiUnderlyingRaw.add(cDaiUnderlyingRaw); + postDDaiUnderlyingRaw = dDaiUnderlyingRaw.add(cSaiUnderlyingRaw); postMigrationBalances = { dDaiUnderlyingRaw: postDDaiUnderlyingRaw.toString(), - cDaiUnderlyingRaw: ZERO.toString() + cSaiUnderlyingRaw: ZERO.toString() }; await tester.withBalanceCheck( @@ -6744,9 +6744,9 @@ async function test(testingContext) { postMigrationBalances, tester.runTest, [ - "V7 UserSmartWallet relay can trigger cDai to dDai migration after allowance is 0", + "V7 UserSmartWallet relay can trigger cSai to dDai migration", UserSmartWalletV7, - "migrateCDaiToDDai", + "migrateCSaiToDDai", "send", [], true, From 7e88ced50ab561d3d54c0f9f7051642f9fc3ef56 Mon Sep 17 00:00:00 2001 From: 0age <37939117+0age@users.noreply.github.com> Date: Tue, 11 Feb 2020 15:05:01 -0500 Subject: [PATCH 47/47] version 1.5.0 Version 1.5.0 adds V7 for the Dharma Smart Wallet, which integrates with Dharma Dai and Dharma USD Coin. It also includes a significant testing refactor. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d69fa78..dfe1ff9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dharma-smart-wallet", - "version": "1.4.0", + "version": "1.5.0", "description": "An upgradeable, meta-transaction-enabled smart wallet for earning interest on stablecoins while retaining custody of funds, with an added security backstop provided by Dharma Labs.", "author": "Dharma Labs", "license": "MIT",