fixed michaels comments and finished off writing the test
This commit is contained in:
parent
7267420874
commit
d3df985a42
@ -31,9 +31,6 @@ contract FundRecoveryFeature is
|
|||||||
string public constant override FEATURE_NAME = "FundRecoveryFeature";
|
string public constant override FEATURE_NAME = "FundRecoveryFeature";
|
||||||
/// @dev Version of this feature.
|
/// @dev Version of this feature.
|
||||||
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0);
|
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0);
|
||||||
|
|
||||||
/// @dev Construct this contract.
|
|
||||||
constructor() public {}
|
|
||||||
|
|
||||||
/// @dev Initialize and register this feature.
|
/// @dev Initialize and register this feature.
|
||||||
/// Should be delegatecalled by `Migrate.migrate()`.
|
/// Should be delegatecalled by `Migrate.migrate()`.
|
||||||
@ -46,9 +43,8 @@ contract FundRecoveryFeature is
|
|||||||
return LibMigrate.MIGRATE_SUCCESS;
|
return LibMigrate.MIGRATE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// solhint-enable state-visibility
|
/// @dev Recovers ERC20 tokens or ETH from the 0x Exchange Proxy contract
|
||||||
/// @dev recovers WETH from the 0x Exchange Proxy contract
|
/// @param erc20 ERC20 Token Address. (You can also pass in `0xeeeee...` to indicate ETH)
|
||||||
/// @param erc20 ERC20 Token Address.
|
|
||||||
/// @param amountOut Amount of tokens to withdraw.
|
/// @param amountOut Amount of tokens to withdraw.
|
||||||
/// @param recipientWallet Recipient wallet address.
|
/// @param recipientWallet Recipient wallet address.
|
||||||
function transferTrappedTokensTo(
|
function transferTrappedTokensTo(
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
pragma solidity ^0.6;
|
|
||||||
pragma experimental ABIEncoderV2;
|
|
||||||
import "../src/features/FundRecoveryFeature.sol";
|
|
||||||
|
|
||||||
contract TestFundRecoveryFeature is FundRecoveryFeature {
|
|
||||||
constructor(
|
|
||||||
// IERC20TokenV06 erc20,
|
|
||||||
// uint256 amountOut,
|
|
||||||
// address payable recipientWallet
|
|
||||||
)
|
|
||||||
FundRecoveryFeature()
|
|
||||||
public
|
|
||||||
{}
|
|
||||||
|
|
||||||
receive() external payable {}
|
|
||||||
}
|
|
@ -15,15 +15,12 @@
|
|||||||
"build:ts": "tsc -b",
|
"build:ts": "tsc -b",
|
||||||
"pre_build": "run-s compile contracts:gen generate_contract_wrappers contracts:copy",
|
"pre_build": "run-s compile contracts:gen generate_contract_wrappers contracts:copy",
|
||||||
"test": "yarn run_mocha",
|
"test": "yarn run_mocha",
|
||||||
"test:funds": " yarn run-s build run_mocha_fund",
|
|
||||||
"retest": "yarn run-s run_mocha_fund",
|
"retest": "yarn run-s run_mocha_fund",
|
||||||
"test:recovery": "mocha --grep 'FundRecovery'",
|
|
||||||
"rebuild_and_test": "run-s build test",
|
"rebuild_and_test": "run-s build test",
|
||||||
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
|
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
|
||||||
"test:profiler": "SOLIDITY_PROFILER=true run-s build run_mocha profiler:report:html",
|
"test:profiler": "SOLIDITY_PROFILER=true run-s build run_mocha profiler:report:html",
|
||||||
"test:trace": "SOLIDITY_REVERT_TRACE=true run-s build run_mocha",
|
"test:trace": "SOLIDITY_REVERT_TRACE=true run-s build run_mocha",
|
||||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
|
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
|
||||||
"run_mocha_fund": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/features/fund_recovery_tests.js' --timeout 10000000 --bail --exit",
|
|
||||||
"compile": "sol-compiler",
|
"compile": "sol-compiler",
|
||||||
"watch": "sol-compiler -w",
|
"watch": "sol-compiler -w",
|
||||||
"clean": "shx rm -rf lib test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers",
|
"clean": "shx rm -rf lib test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers",
|
||||||
|
@ -1,26 +1,21 @@
|
|||||||
import {
|
import {
|
||||||
blockchainTests,
|
blockchainTests,
|
||||||
constants,
|
constants,
|
||||||
describe,
|
|
||||||
expect,
|
expect,
|
||||||
getRandomPortion,
|
|
||||||
provider,
|
|
||||||
randomAddress,
|
randomAddress,
|
||||||
} from '@0x/contracts-test-utils';
|
} from '@0x/contracts-test-utils';
|
||||||
import { BigNumber, hexUtils } from '@0x/utils';
|
import { BigNumber, OwnableRevertErrors } from '@0x/utils';
|
||||||
import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contracts-erc20';
|
import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contracts-erc20';
|
||||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
import { IOwnableFeatureContract, IZeroExContract } from '../../src/wrappers';
|
||||||
import { IOwnableFeatureContract, IZeroExContract, LiquidityProviderFeatureContract } from '../../src/wrappers';
|
|
||||||
import {TestWethContract} from '../wrappers';
|
import {TestWethContract} from '../wrappers';
|
||||||
import { artifacts } from '../artifacts';
|
import { artifacts } from '../artifacts';
|
||||||
import { abis } from '../utils/abis';
|
import { abis } from '../utils/abis';
|
||||||
import { fullMigrateAsync } from '../utils/migration';
|
import { fullMigrateAsync } from '../utils/migration';
|
||||||
import { TestInitialMigrationContract } from '../generated-wrappers/test_initial_migration';
|
|
||||||
import { FundRecoveryFeatureContract } from '../generated-wrappers/fund_recovery_feature';
|
import { FundRecoveryFeatureContract } from '../generated-wrappers/fund_recovery_feature';
|
||||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||||
import { Address } from '@0x/utils/lib/src/abi_encoder';
|
import { OnlyOwnerError } from '@0x/utils/lib/src/revert_errors/utils/ownable_revert_errors';
|
||||||
|
|
||||||
blockchainTests('FundRecovery', async env => {
|
blockchainTests.only('FundRecovery', async env => {
|
||||||
|
|
||||||
let owner: string;
|
let owner: string;
|
||||||
let designatedAddress: string;
|
let designatedAddress: string;
|
||||||
@ -31,15 +26,9 @@ import { Address } from '@0x/utils/lib/src/abi_encoder';
|
|||||||
let feature: FundRecoveryFeatureContract;
|
let feature: FundRecoveryFeatureContract;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
env.blockchainLifecycle.startAsync();
|
|
||||||
const ZERO_EX_EXCHANGE_PROXY = '0xdef1c0ded9bec7f1a1670819833240f027b25eff';
|
|
||||||
[owner, designatedAddress, testAddress] = await env.getAccountAddressesAsync();
|
|
||||||
|
|
||||||
console.log(owner);
|
[owner, designatedAddress, testAddress] = await env.getAccountAddressesAsync();
|
||||||
//EP Migration
|
|
||||||
zeroEx = await fullMigrateAsync(owner, env.provider, env.txDefaults, {});
|
zeroEx = await fullMigrateAsync(owner, env.provider, env.txDefaults, {});
|
||||||
|
|
||||||
//deploy dummy erc20 token
|
|
||||||
token = await DummyERC20TokenContract.deployFrom0xArtifactAsync(
|
token = await DummyERC20TokenContract.deployFrom0xArtifactAsync(
|
||||||
erc20Artifacts.DummyERC20Token,
|
erc20Artifacts.DummyERC20Token,
|
||||||
env.provider,
|
env.provider,
|
||||||
@ -49,12 +38,9 @@ import { Address } from '@0x/utils/lib/src/abi_encoder';
|
|||||||
constants.DUMMY_TOKEN_SYMBOL,
|
constants.DUMMY_TOKEN_SYMBOL,
|
||||||
constants.DUMMY_TOKEN_DECIMALS,
|
constants.DUMMY_TOKEN_DECIMALS,
|
||||||
constants.DUMMY_TOKEN_TOTAL_SUPPLY,
|
constants.DUMMY_TOKEN_TOTAL_SUPPLY,
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await token.setBalance(zeroEx.address, constants.INITIAL_ERC20_BALANCE).awaitTransactionSuccessAsync();
|
await token.setBalance(zeroEx.address, constants.INITIAL_ERC20_BALANCE).awaitTransactionSuccessAsync();
|
||||||
const bal = await token.balanceOf(ZERO_EX_EXCHANGE_PROXY).callAsync();
|
const bal = await token.balanceOf(zeroEx.address).callAsync();
|
||||||
|
|
||||||
weth = await TestWethContract.deployFrom0xArtifactAsync(
|
weth = await TestWethContract.deployFrom0xArtifactAsync(
|
||||||
artifacts.TestWeth,
|
artifacts.TestWeth,
|
||||||
env.provider,
|
env.provider,
|
||||||
@ -62,10 +48,7 @@ import { Address } from '@0x/utils/lib/src/abi_encoder';
|
|||||||
artifacts,
|
artifacts,
|
||||||
);
|
);
|
||||||
await weth.mint(zeroEx.address, constants.INITIAL_ERC20_BALANCE).awaitTransactionSuccessAsync();
|
await weth.mint(zeroEx.address, constants.INITIAL_ERC20_BALANCE).awaitTransactionSuccessAsync();
|
||||||
await weth.mint(ZERO_EX_EXCHANGE_PROXY, constants.INITIAL_ERC20_BALANCE).awaitTransactionSuccessAsync();
|
|
||||||
const balweth = await weth.balanceOf(zeroEx.address).callAsync();
|
const balweth = await weth.balanceOf(zeroEx.address).callAsync();
|
||||||
|
|
||||||
//CREATE CONTRACT AND DEPLOY FEATURE
|
|
||||||
feature = new FundRecoveryFeatureContract(zeroEx.address, env.provider, env.txDefaults, abis);
|
feature = new FundRecoveryFeatureContract(zeroEx.address, env.provider, env.txDefaults, abis);
|
||||||
const featureImpl = await FundRecoveryFeatureContract.deployFrom0xArtifactAsync(
|
const featureImpl = await FundRecoveryFeatureContract.deployFrom0xArtifactAsync(
|
||||||
artifacts.FundRecoveryFeature,
|
artifacts.FundRecoveryFeature,
|
||||||
@ -73,15 +56,12 @@ import { Address } from '@0x/utils/lib/src/abi_encoder';
|
|||||||
env.txDefaults,
|
env.txDefaults,
|
||||||
artifacts
|
artifacts
|
||||||
);
|
);
|
||||||
|
|
||||||
await new IOwnableFeatureContract(zeroEx.address, env.provider, env.txDefaults, abis)
|
await new IOwnableFeatureContract(zeroEx.address, env.provider, env.txDefaults, abis)
|
||||||
.migrate(featureImpl.address, featureImpl.migrate().getABIEncodedTransactionData(), owner)
|
.migrate(featureImpl.address, featureImpl.migrate().getABIEncodedTransactionData(), owner)
|
||||||
.awaitTransactionSuccessAsync();
|
.awaitTransactionSuccessAsync();
|
||||||
|
|
||||||
});
|
});
|
||||||
blockchainTests.resets('Should delegatecall `transferTrappedTokensTo` from the exchange proxy', () => {
|
blockchainTests.resets('Should delegatecall `transferTrappedTokensTo` from the exchange proxy', () => {
|
||||||
const ETH_TOKEN_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
|
const ETH_TOKEN_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
|
||||||
const ZERO_EX_EXCHANGE_PROXY = '0xdef1c0ded9bec7f1a1670819833240f027b25eff';
|
|
||||||
it('Tranfers an arbitrary ERC-20 Token', async () => {
|
it('Tranfers an arbitrary ERC-20 Token', async () => {
|
||||||
const amountOut = Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18);
|
const amountOut = Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18);
|
||||||
const designatedAddressBalance = await token.balanceOf(designatedAddress).callAsync();
|
const designatedAddressBalance = await token.balanceOf(designatedAddress).callAsync();
|
||||||
@ -89,7 +69,7 @@ import { Address } from '@0x/utils/lib/src/abi_encoder';
|
|||||||
await zeroEx.transferTrappedTokensTo(token.address, amountOut, designatedAddress).awaitTransactionSuccessAsync({ from: owner });
|
await zeroEx.transferTrappedTokensTo(token.address, amountOut, designatedAddress).awaitTransactionSuccessAsync({ from: owner });
|
||||||
const epBalanceNew = await token.balanceOf(zeroEx.address).callAsync();
|
const epBalanceNew = await token.balanceOf(zeroEx.address).callAsync();
|
||||||
const designatedAddressBalanceAferTransfer = await token.balanceOf(designatedAddress).callAsync();
|
const designatedAddressBalanceAferTransfer = await token.balanceOf(designatedAddress).callAsync();
|
||||||
expect(designatedAddressBalanceAferTransfer.c![0]).to.equal(amountOut.c![0]);
|
expect(designatedAddressBalanceAferTransfer).to.bignumber.equal(amountOut);
|
||||||
});
|
});
|
||||||
it('Amount -1 transfers entire balance', async () => {
|
it('Amount -1 transfers entire balance', async () => {
|
||||||
const designatedAddressBalance = await token.balanceOf(designatedAddress).callAsync();
|
const designatedAddressBalance = await token.balanceOf(designatedAddress).callAsync();
|
||||||
@ -97,30 +77,27 @@ import { Address } from '@0x/utils/lib/src/abi_encoder';
|
|||||||
const tx = await zeroEx.transferTrappedTokensTo(token.address, constants.MAX_UINT256 , designatedAddress).awaitTransactionSuccessAsync({ from: owner });
|
const tx = await zeroEx.transferTrappedTokensTo(token.address, constants.MAX_UINT256 , designatedAddress).awaitTransactionSuccessAsync({ from: owner });
|
||||||
const balanceNew = await token.balanceOf(zeroEx.address).callAsync();
|
const balanceNew = await token.balanceOf(zeroEx.address).callAsync();
|
||||||
const designatedAddressBalanceAferTransfer = await token.balanceOf(designatedAddress).callAsync();
|
const designatedAddressBalanceAferTransfer = await token.balanceOf(designatedAddress).callAsync();
|
||||||
expect(balanceNew.c![0]).to.equal(0);
|
expect(balanceNew).to.bignumber.equal(0);
|
||||||
expect(designatedAddressBalanceAferTransfer.c![0]).to.equal(balanceOwner.c![0]);
|
expect(designatedAddressBalanceAferTransfer).to.bignumber.equal(balanceOwner);
|
||||||
});
|
});
|
||||||
it('Transfers ETH ', async () => {
|
it('Transfers ETH ', async () => {
|
||||||
//connect to mainnet contract address
|
const amountOut = new BigNumber(20);
|
||||||
const zrxContractMainnet = new IZeroExContract(ZERO_EX_EXCHANGE_PROXY, env.provider, env.txDefaults);
|
await env.web3Wrapper.awaitTransactionMinedAsync(
|
||||||
//await weth.withdraw(wethBal);
|
await env.web3Wrapper.sendTransactionAsync(
|
||||||
const bal = await env.web3Wrapper.getBalanceInWeiAsync(zrxContractMainnet.address);
|
{
|
||||||
//const designatedAddressBalance = await token.balanceOf(designatedAddress).callAsync();
|
from: owner,
|
||||||
const tx = await zrxContractMainnet.transferTrappedTokensTo(ETH_TOKEN_ADDRESS, constants.MAX_UINT256 , designatedAddress).awaitTransactionSuccessAsync({ from: owner });
|
to: zeroEx.address,
|
||||||
//const bal2 = await env.web3Wrapper.getBalanceInWeiAsync(zrxContractMainnet.address);
|
value: amountOut
|
||||||
const designatedAddressBalance = await env.web3Wrapper.getBalanceInWeiAsync(zrxContractMainnet.address);
|
}));
|
||||||
|
const bal = await env.web3Wrapper.getBalanceInWeiAsync(designatedAddress);
|
||||||
|
const tx = await zeroEx.transferTrappedTokensTo(ETH_TOKEN_ADDRESS, amountOut , designatedAddress).awaitTransactionSuccessAsync({ from: owner });
|
||||||
|
const designatedAddressBalance = await env.web3Wrapper.getBalanceInWeiAsync(designatedAddress);
|
||||||
|
return expect(designatedAddressBalance).to.bignumber.be.greaterThan(bal);
|
||||||
});
|
});
|
||||||
it('Feature `transferTrappedTokensTo` can only be called by owner', async () => {
|
it('Feature `transferTrappedTokensTo` can only be called by owner', async () => {
|
||||||
//need to be able to change caller context.
|
const notOwner = randomAddress();
|
||||||
const zrxContractMainnet = new IZeroExContract(ZERO_EX_EXCHANGE_PROXY, env.provider, env.txDefaults);
|
|
||||||
const tx = await zrxContractMainnet.transferTrappedTokensTo(ETH_TOKEN_ADDRESS, constants.MAX_UINT256 , designatedAddress).awaitTransactionSuccessAsync({ from: owner });
|
return expect(zeroEx.transferTrappedTokensTo(ETH_TOKEN_ADDRESS, constants.MAX_UINT256 , designatedAddress).awaitTransactionSuccessAsync({ from: notOwner })).to.revertWith(new OnlyOwnerError(notOwner,owner));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user