fix formating on connectors/curve.sol;

adding @openzeppelin/test-helpers, ganache-cli;
fixing test/CurveProtocol.js to pass;
added truffle network for tenderly proxy;
added .nvmrc to set to node v12 as ganache-cli requires;
This commit is contained in:
Lecky Lao 2020-06-28 23:15:51 +10:00
parent 076a836c03
commit bce54aba13
6 changed files with 1897 additions and 320 deletions

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
v12.18.1

View File

@ -6,224 +6,223 @@ import { Stores } from "../common/stores.sol";
import { DSMath } from "../common/math.sol"; import { DSMath } from "../common/math.sol";
interface ICurve { interface ICurve {
function underlying_coins(int128 tokenId) external view returns (address token); function underlying_coins(int128 tokenId) external view returns (address token);
function calc_token_amount(uint256[4] calldata amounts, bool deposit) external returns (uint256 amount); function calc_token_amount(uint256[4] calldata amounts, bool deposit) external returns (uint256 amount);
function add_liquidity(uint256[4] calldata amounts, uint256 min_mint_amount) external; function add_liquidity(uint256[4] calldata amounts, uint256 min_mint_amount) external;
function get_dy(int128 sellTokenId, int128 buyTokenId, uint256 sellTokenAmt) external returns (uint256 buyTokenAmt); function get_dy(int128 sellTokenId, int128 buyTokenId, uint256 sellTokenAmt) external returns (uint256 buyTokenAmt);
function exchange(int128 sellTokenId, int128 buyTokenId, uint256 sellTokenAmt, uint256 minBuyToken) external; function exchange(int128 sellTokenId, int128 buyTokenId, uint256 sellTokenAmt, uint256 minBuyToken) external;
function remove_liquidity_imbalance(uint256[4] calldata amounts, uint256 max_burn_amount) external; function remove_liquidity_imbalance(uint256[4] calldata amounts, uint256 max_burn_amount) external;
} }
interface ICurveZap { interface ICurveZap {
function calc_withdraw_one_coin(uint256 _token_amount, int128 i) external returns (uint256 amount); function calc_withdraw_one_coin(uint256 _token_amount, int128 i) external returns (uint256 amount);
} }
contract CurveHelpers is Stores, DSMath { contract CurveHelpers is Stores, DSMath {
/** /**
* @dev Return Curve Swap Address * @dev Return Curve Swap Address
*/ */
function getCurveSwapAddr() internal pure returns (address) { function getCurveSwapAddr() internal pure returns (address) {
return 0xA5407eAE9Ba41422680e2e00537571bcC53efBfD; return 0xA5407eAE9Ba41422680e2e00537571bcC53efBfD;
} }
/** /**
* @dev Return Curve Token Address * @dev Return Curve Token Address
*/ */
function getCurveTokenAddr() internal pure returns (address) { function getCurveTokenAddr() internal pure returns (address) {
return 0xC25a3A3b969415c80451098fa907EC722572917F; return 0xC25a3A3b969415c80451098fa907EC722572917F;
} }
/** /**
* @dev Return Curve Zap Address * @dev Return Curve Zap Address
*/ */
function getCurveZapAddr() internal pure returns (address) { function getCurveZapAddr() internal pure returns (address) {
return 0xFCBa3E75865d2d561BE8D220616520c171F12851; return 0xFCBa3E75865d2d561BE8D220616520c171F12851;
} }
function convert18ToDec(uint _dec, uint256 _amt) internal pure returns (uint256 amt) { function convert18ToDec(uint _dec, uint256 _amt) internal pure returns (uint256 amt) {
amt = (_amt / 10 ** (18 - _dec)); amt = (_amt / 10 ** (18 - _dec));
} }
function convertTo18(uint _dec, uint256 _amt) internal pure returns (uint256 amt) { function convertTo18(uint _dec, uint256 _amt) internal pure returns (uint256 amt) {
amt = mul(_amt, 10 ** (18 - _dec)); amt = mul(_amt, 10 ** (18 - _dec));
} }
function getTokenI(address token) internal pure returns (int128 i) { function getTokenI(address token) internal pure returns (int128 i) {
if (token == address(0x6B175474E89094C44Da98b954EedeAC495271d0F)) { if (token == address(0x6B175474E89094C44Da98b954EedeAC495271d0F)) {
// DAI Token // DAI Token
i = 0; i = 0;
} else if (token == address(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48)) { } else if (token == address(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48)) {
// USDC Token // USDC Token
i = 1; i = 1;
} else if (token == address(0xdAC17F958D2ee523a2206206994597C13D831ec7)) { } else if (token == address(0xdAC17F958D2ee523a2206206994597C13D831ec7)) {
// USDT Token // USDT Token
i = 2; i = 2;
} else if (token == address(0x57Ab1ec28D129707052df4dF418D58a2D46d5f51)) { } else if (token == address(0x57Ab1ec28D129707052df4dF418D58a2D46d5f51)) {
// sUSD Token // sUSD Token
i = 3; i = 3;
} else { } else {
revert("token-not-found."); revert("token-not-found.");
}
} }
}
function getTokenAddr(ICurve curve, uint256 i) internal view returns (address token) { function getTokenAddr(ICurve curve, uint256 i) internal view returns (address token) {
token = curve.underlying_coins(int128(i)); token = curve.underlying_coins(int128(i));
require(token != address(0), "token-not-found."); require(token != address(0), "token-not-found.");
} }
} }
contract CurveProtocol is CurveHelpers { contract CurveProtocol is CurveHelpers {
event LogSell( event LogSell(
address indexed buyToken, address indexed buyToken,
address indexed sellToken, address indexed sellToken,
uint256 buyAmt, uint256 buyAmt,
uint256 sellAmt, uint256 sellAmt,
uint256 getId, uint256 getId,
uint256 setId uint256 setId
); );
event LogDeposit(address token, uint256 amt, uint256 mintAmt, uint256 getId, uint256 setId); event LogDeposit(address token, uint256 amt, uint256 mintAmt, uint256 getId, uint256 setId);
event LogWithdraw(address token, uint256 amt, uint256 burnAmt, uint256 getId, uint256 setId); event LogWithdraw(address token, uint256 amt, uint256 burnAmt, uint256 getId, uint256 setId);
/** /**
* @dev Sell Stable ERC20_Token. * @dev Sell Stable ERC20_Token.
* @param buyAddr buying token address. * @param buyAddr buying token address.
* @param sellAddr selling token amount. * @param sellAddr selling token amount.
* @param sellAmt selling token amount. * @param sellAmt selling token amount.
* @param unitAmt unit amount of buyAmt/sellAmt with slippage. * @param unitAmt unit amount of buyAmt/sellAmt with slippage.
* @param getId Get token amount at this ID from `InstaMemory` Contract. * @param getId Get token amount at this ID from `InstaMemory` Contract.
* @param setId Set token amount at this ID in `InstaMemory` Contract. * @param setId Set token amount at this ID in `InstaMemory` Contract.
*/ */
function sell( function sell(
address buyAddr, address buyAddr,
address sellAddr, address sellAddr,
uint sellAmt, uint sellAmt,
uint unitAmt, uint unitAmt,
uint getId, uint getId,
uint setId uint setId
) external payable { ) external payable {
uint _sellAmt = getUint(getId, sellAmt); uint _sellAmt = getUint(getId, sellAmt);
ICurve curve = ICurve(getCurveSwapAddr()); ICurve curve = ICurve(getCurveSwapAddr());
TokenInterface _buyToken = TokenInterface(buyAddr); TokenInterface _buyToken = TokenInterface(buyAddr);
TokenInterface _sellToken = TokenInterface(sellAddr); TokenInterface _sellToken = TokenInterface(sellAddr);
_sellAmt = _sellAmt == uint(-1) ? _sellToken.balanceOf(address(this)) : _sellAmt; _sellAmt = _sellAmt == uint(-1) ? _sellToken.balanceOf(address(this)) : _sellAmt;
_sellToken.approve(address(curve), _sellAmt); _sellToken.approve(address(curve), _sellAmt);
uint _slippageAmt = convert18ToDec(_buyToken.decimals(), wmul(unitAmt, convertTo18(_sellToken.decimals(), _sellAmt))); uint _slippageAmt = convert18ToDec(_buyToken.decimals(), wmul(unitAmt, convertTo18(_sellToken.decimals(), _sellAmt)));
uint intialBal = _buyToken.balanceOf(address(this)); uint intialBal = _buyToken.balanceOf(address(this));
curve.exchange(getTokenI(sellAddr), getTokenI(buyAddr), _sellAmt, _slippageAmt); curve.exchange(getTokenI(sellAddr), getTokenI(buyAddr), _sellAmt, _slippageAmt);
uint finalBal = _buyToken.balanceOf(address(this)); uint finalBal = _buyToken.balanceOf(address(this));
uint _buyAmt = sub(finalBal, intialBal); uint _buyAmt = sub(finalBal, intialBal);
setUint(setId, _buyAmt); setUint(setId, _buyAmt);
emit LogSell(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId); emit LogSell(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId);
bytes32 _eventCode = keccak256("LogSell(address,address,uint256,uint256,uint256,uint256)"); bytes32 _eventCode = keccak256("LogSell(address,address,uint256,uint256,uint256,uint256)");
bytes memory _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId); bytes memory _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId);
emitEvent(_eventCode, _eventParam); emitEvent(_eventCode, _eventParam);
}
/**
* @dev Deposit Token.
* @param token token address.
* @param amt token amount.
* @param unitAmt unit amount of curve_amt/token_amt with slippage.
* @param getId Get token amount at this ID from `InstaMemory` Contract.
* @param setId Set token amount at this ID in `InstaMemory` Contract.
*/
function deposit(
address token,
uint amt,
uint unitAmt,
uint getId,
uint setId
) external payable {
uint256 _amt = getUint(getId, amt);
TokenInterface tokenContract = TokenInterface(token);
_amt = _amt == uint(-1) ? tokenContract.balanceOf(address(this)) : _amt;
uint[4] memory _amts;
_amts[uint(getTokenI(token))] = _amt;
tokenContract.approve(getCurveSwapAddr(), _amt);
uint _amt18 = convertTo18(tokenContract.decimals(), _amt);
uint _slippageAmt = wmul(unitAmt, _amt18);
TokenInterface curveTokenContract = TokenInterface(getCurveTokenAddr());
uint initialCurveBal = curveTokenContract.balanceOf(address(this));
ICurve(getCurveSwapAddr()).add_liquidity(_amts, _slippageAmt);
uint finalCurveBal = curveTokenContract.balanceOf(address(this));
uint mintAmt = sub(finalCurveBal, initialCurveBal);
setUint(setId, mintAmt);
emit LogDeposit(token, _amt, mintAmt, getId, setId);
bytes32 _eventCode = keccak256("LogDeposit(address,uint256,uint256,uint256,uint256)");
bytes memory _eventParam = abi.encode(token, _amt, mintAmt, getId, setId);
emitEvent(_eventCode, _eventParam);
}
/**
* @dev Withdraw Token.
* @param token token address.
* @param amt token amount.
* @param unitAmt unit amount of curve_amt/token_amt with slippage.
* @param getId Get token amount at this ID from `InstaMemory` Contract.
* @param setId Set token amount at this ID in `InstaMemory` Contract.
*/
function withdraw(
address token,
uint256 amt,
uint256 unitAmt,
uint getId,
uint setId
) external payable {
uint _amt = getUint(getId, amt);
int128 tokenId = getTokenI(token);
TokenInterface curveTokenContract = TokenInterface(getCurveTokenAddr());
ICurveZap curveZap = ICurveZap(getCurveZapAddr());
ICurve curveSwap = ICurve(getCurveSwapAddr());
uint _curveAmt;
uint[4] memory _amts;
if (_amt == uint(-1)) {
_curveAmt = curveTokenContract.balanceOf(address(this));
_amt = curveZap.calc_withdraw_one_coin(_curveAmt, tokenId);
_amts[uint(tokenId)] = _amt;
} else {
_amts[uint(tokenId)] = _amt;
_curveAmt = curveSwap.calc_token_amount(_amts, false);
} }
/**
* @dev Deposit Token.
* @param token token address.
* @param amt token amount.
* @param unitAmt unit amount of curve_amt/token_amt with slippage.
* @param getId Get token amount at this ID from `InstaMemory` Contract.
* @param setId Set token amount at this ID in `InstaMemory` Contract.
*/
function deposit(
address token,
uint amt,
uint unitAmt,
uint getId,
uint setId
) external payable {
uint256 _amt = getUint(getId, amt);
TokenInterface tokenContract = TokenInterface(token);
_amt = _amt == uint(-1) ? tokenContract.balanceOf(address(this)) : _amt; uint _amt18 = convertTo18(TokenInterface(token).decimals(), _amt);
uint[4] memory _amts; uint _slippageAmt = wmul(unitAmt, _amt18);
_amts[uint(getTokenI(token))] = _amt;
tokenContract.approve(getCurveSwapAddr(), _amt); curveTokenContract.approve(address(curveSwap), 0);
curveTokenContract.approve(address(curveSwap), _slippageAmt);
uint _amt18 = convertTo18(tokenContract.decimals(), _amt); curveSwap.remove_liquidity_imbalance(_amts, _slippageAmt);
uint _slippageAmt = wmul(unitAmt, _amt18);
TokenInterface curveTokenContract = TokenInterface(getCurveTokenAddr()); setUint(setId, _amt);
uint initialCurveBal = curveTokenContract.balanceOf(address(this));
ICurve(getCurveSwapAddr()).add_liquidity(_amts, _slippageAmt); emit LogWithdraw(token, _amt, _curveAmt, getId, setId);
bytes32 _eventCode = keccak256("LogWithdraw(address,uint256,uint256,uint256,uint256)");
uint finalCurveBal = curveTokenContract.balanceOf(address(this)); bytes memory _eventParam = abi.encode(token, _amt, _curveAmt, getId, setId);
emitEvent(_eventCode, _eventParam);
uint mintAmt = sub(finalCurveBal, initialCurveBal); }
setUint(setId, mintAmt);
emit LogDeposit(token, _amt, mintAmt, getId, setId);
bytes32 _eventCode = keccak256("LogDeposit(address,uint256,uint256,uint256,uint256)");
bytes memory _eventParam = abi.encode(token, _amt, mintAmt, getId, setId);
emitEvent(_eventCode, _eventParam);
}
/**
* @dev Withdraw Token.
* @param token token address.
* @param amt token amount.
* @param unitAmt unit amount of curve_amt/token_amt with slippage.
* @param getId Get token amount at this ID from `InstaMemory` Contract.
* @param setId Set token amount at this ID in `InstaMemory` Contract.
*/
function withdraw(
address token,
uint256 amt,
uint256 unitAmt,
uint getId,
uint setId
) external payable {
uint _amt = getUint(getId, amt);
int128 tokenId = getTokenI(token);
TokenInterface curveTokenContract = TokenInterface(getCurveTokenAddr());
ICurveZap curveZap = ICurveZap(getCurveZapAddr());
ICurve curveSwap = ICurve(getCurveSwapAddr());
uint _curveAmt;
uint[4] memory _amts;
if (_amt == uint(-1)) {
_curveAmt = curveTokenContract.balanceOf(address(this));
_amt = curveZap.calc_withdraw_one_coin(_curveAmt, tokenId);
_amts[uint(tokenId)] = _amt;
} else {
_amts[uint(tokenId)] = _amt;
_curveAmt = curveSwap.calc_token_amount(_amts, false);
}
uint _amt18 = convertTo18(TokenInterface(token).decimals(), _amt);
uint _slippageAmt = wmul(unitAmt, _amt18);
curveTokenContract.approve(address(curveSwap), 0);
curveTokenContract.approve(address(curveSwap), _slippageAmt);
curveSwap.remove_liquidity_imbalance(_amts, _slippageAmt);
setUint(setId, _amt);
emit LogWithdraw(token, _amt, _curveAmt, getId, setId);
bytes32 _eventCode = keccak256("LogWithdraw(address,uint256,uint256,uint256,uint256)");
bytes memory _eventParam = abi.encode(token, _amt, _curveAmt, getId, setId);
emitEvent(_eventCode, _eventParam);
}
} }
contract ConnectCurve is CurveProtocol { contract ConnectCurve is CurveProtocol {
string public name = "Curve-susd-v1.2"; string public name = "Curve-susd-v1.2";
} }

1669
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,10 +5,11 @@
"main": "truffle-config.js", "main": "truffle-config.js",
"directories": {}, "directories": {},
"scripts": { "scripts": {
"test": "npm run ganache sleep 5 && truffle test && npm run stop", "test": "truffle test",
"coverage": "./node_modules/.bin/solidity-coverage", "coverage": "./node_modules/.bin/solidity-coverage",
"solium": "solium -d contracts/", "solium": "solium -d contracts/",
"build-contracts": "sol-merger \"./contracts/connectors/mock.sol\" ./contracts/build" "build-contracts": "sol-merger \"./contracts/connectors/mock.sol\" ./contracts/build",
"ganache": "ganache-cli --deterministic --unlock 0x9eb7f2591ed42dee9315b6e2aaf21ba85ea69f8c -f https://mainnet.infura.io/v3/<Your Key>"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -35,6 +36,8 @@
"truffle-verify": "^1.0.8" "truffle-verify": "^1.0.8"
}, },
"devDependencies": { "devDependencies": {
"@openzeppelin/test-helpers": "^0.5.6",
"ganache-cli": "^6.10.0-beta.2",
"sol-merger": "^2.0.1", "sol-merger": "^2.0.1",
"solidity-coverage": "0.5.11", "solidity-coverage": "0.5.11",
"solium": "1.2.3" "solium": "1.2.3"

View File

@ -2,7 +2,7 @@ const CurveProtocol = artifacts.require('CurveProtocol')
const daiABI = require('./abi/dai'); const daiABI = require('./abi/dai');
const erc20 = require('./abi/erc20') const erc20 = require('./abi/erc20')
const swap_abi = require('./abi/swap') const swap_abi = require('./abi/swap')
const { ether, balance } = require('openzeppelin-test-helpers'); const { ether, balance } = require('@openzeppelin/test-helpers');
const BN = require('bn.js') const BN = require('bn.js')
@ -24,99 +24,106 @@ const swapContract = new web3.eth.Contract(swap_abi, swap)
const swapToken = '0xC25a3A3b969415c80451098fa907EC722572917F' const swapToken = '0xC25a3A3b969415c80451098fa907EC722572917F'
const tokenContract = new web3.eth.Contract(erc20, swapToken) const tokenContract = new web3.eth.Contract(erc20, swapToken)
contract('Curve Protocol', async accounts => { contract('Curve Protocol', async accounts => {
it('should send ether to the user address', async () => {
let account = accounts[0]
let contract = await CurveProtocol.deployed()
const ethBalanceBefore = await balance.current(userAddress);
// Send 0.1 eth to userAddress to have gas to send an ERC20 tx.
await web3.eth.sendTransaction({
from: accounts[0],
to: userAddress,
value: ether('0.1')
});
const ethBalanceAfter = await balance.current(userAddress);
expect(+ethBalanceAfter - +ethBalanceBefore).to.equal(+ether('0.1'))
});
it('should send ether to the DAI address', async () => { it('should transfer DAI to CurveProtocol', async () => {
let account = accounts[0] let account = accounts[0]
let contract = await CurveProtocol.deployed() let contract = await CurveProtocol.deployed()
// Send 0.1 eth to userAddress to have gas to send an ERC20 tx. // Get 100 DAI for first 5 accounts
await web3.eth.sendTransaction({ // daiAddress is passed to ganache-cli with flag `--unlock`
from: accounts[0], // so we can use the `transfer` method
to: userAddress, //
value: ether('0.1') // Note: This only works as userAddress has 2546221640728945323079640 Dai,
}); // should remove this dependence in the future
const ethBalance = await balance.current(userAddress); const daiBalanceUser = await daiContract.methods.balanceOf(userAddress).call();
expect(+ethBalance).to.be.at.least(+ether('0.1')) await daiContract.methods
}); .transfer(contract.address, ether('100').toString())
.send({ from: userAddress, gasLimit: 800000 });
const daiBalance = await daiContract.methods.balanceOf(contract.address).call();
expect(+daiBalance).to.be.at.least(+ether('100'))
});
it('should transfer DAI to CurveProtocol', async () => { it('should approve DAI to CurveProtocol', async() => {
let account = accounts[0] let account = accounts[0]
let contract = await CurveProtocol.deployed() let contract = await CurveProtocol.deployed()
// Get 100 DAI for first 5 accounts
// daiAddress is passed to ganache-cli with flag `--unlock`
// so we can use the `transfer` method
await daiContract.methods
.transfer(contract.address, ether('100').toString())
.send({ from: userAddress, gasLimit: 800000 });
const daiBalance = await daiContract.methods.balanceOf(contract.address).call();
expect(+daiBalance).to.be.at.least(+ether('100'))
});
it('should approve DAI to CurveProtocol', async() => { await daiContract.methods
let account = accounts[0] .approve(contract.address, ether('100').toString())
let contract = await CurveProtocol.deployed() .send({ from: account, gasLimit: 800000 });
const daiAllowance = await daiContract.methods.allowance(account, contract.address).call()
expect(+daiAllowance).to.be.at.least(+ether('100'))
});
await daiContract.methods /* Deprecated as CurveProtocol is not ICurve and exchange has been implemented into sell method
.approve(contract.address, ether('100').toString()) it('should exchange', async () => {
.send({ from: account, gasLimit: 800000 }); let account = accounts[0]
const daiAllowance = await daiContract.methods.allowance(account, contract.address).call() let contract = await CurveProtocol.deployed()
expect(+daiAllowance).to.be.at.least(+ether('100'))
});
it('should exchange', async () => { // Get 100 DAI for first 5 accounts
let account = accounts[0] console.log('before');
let contract = await CurveProtocol.deployed() let get_dy = await contract.get_dy.call(0, 1, ether('1').toString())
console.log('after');
let min_dy = +get_dy * 0.99
let receipt = await contract.exchange(0, 1, ether('1').toString(), 1, { from: account })
let buyAmount = receipt.logs[0].args.buyAmount.toString()
expect(+buyAmount).to.be.at.least(min_dy);
});
*/
// Get 100 DAI for first 5 accounts /* Deprecated as CurveProtocol is not ICurve and calc_token_amount has been implemented into withdraw method
let get_dy = await contract.get_dy.call(0, 1, ether('1').toString()) it('should add liquidity', async () => {
let min_dy = +get_dy * 0.99 let account = accounts[0]
let receipt = await contract.exchange(0, 1, ether('1').toString(), 1, { from: account }) let contract = await CurveProtocol.deployed()
let buyAmount = receipt.logs[0].args.buyAmount.toString()
expect(+buyAmount).to.be.at.least(min_dy);
}); let amounts = [ether('1').toString(), 0, 0, 0]
let token_amount = await contract.calc_token_amount.call(amounts, true)
it('should add liquidity', async () => { let receipt = await contract.add_liquidity(amounts, 1, { from: account })
let account = accounts[0] let mintAmount = receipt.logs[0].args.mintAmount.toString()
let contract = await CurveProtocol.deployed() expect(+mintAmount).to.be.at.least(+mintAmount)
})
let amounts = [ether('1').toString(), 0, 0, 0] it('should remove liquidity imbalance', async () => {
let token_amount = await contract.calc_token_amount.call(amounts, true) let account = accounts[0]
let contract = await CurveProtocol.deployed()
let receipt = await contract.add_liquidity(amounts, 1, { from: account }) let tokenBalance = await tokenContract.methods.balanceOf(contract.address).call()
let mintAmount = receipt.logs[0].args.mintAmount.toString() let receipt = await contract.remove_liquidity_imbalance(["100000000000", 0, 0, 0], { from: account })
expect(+mintAmount).to.be.at.least(+mintAmount) let burnAmount = receipt.logs[0].args.burnAmount.toString()
}) let tokenBalanceAfter = await tokenContract.methods.balanceOf(contract.address).call()
it('should remove liquidity imbalance', async () => { //weird Ganache errors sometimes "cannot decode event"
let account = accounts[0] console.log(+tokenBalance, +tokenBalanceAfter, +burnAmount)
let contract = await CurveProtocol.deployed() //expect(BN(tokenBalance)).to.be.a.bignumber.equal(BN(tokenBalanceAfter).add(burnAmount))
let tokenBalance = await tokenContract.methods.balanceOf(contract.address).call() })
let receipt = await contract.remove_liquidity_imbalance(["100000000000", 0, 0, 0], { from: account })
let burnAmount = receipt.logs[0].args.burnAmount.toString()
let tokenBalanceAfter = await tokenContract.methods.balanceOf(contract.address).call()
//weird Ganache errors sometimes "cannot decode event" it('should remove liquidity in one coin', async() => {
console.log(+tokenBalance, +tokenBalanceAfter, +burnAmount) let account = accounts[0]
//expect(BN(tokenBalance)).to.be.a.bignumber.equal(BN(tokenBalanceAfter).add(burnAmount)) let contract = await CurveProtocol.deployed()
}) let daiBalance = await daiContract.methods.balanceOf(contract.address).call()
let receipt = await contract.remove_liquidity_one_coin("100000000000", 0, 1, { from: account })
let withdrawnAmount = receipt.logs[0].args.withdrawnAmount.toString()
let daiBalanceAfter = await daiContract.methods.balanceOf(contract.address).call()
it('should remove liquidity in one coin', async() => { //weird Ganache errors sometimes "cannot decode event"
let account = accounts[0] console.log(+daiBalance, +daiBalanceAfter, +withdrawnAmount)
let contract = await CurveProtocol.deployed() //expect(BN(daiBalance)).to.be.a.bignumber.equal(BN(daiBalanceAfter).sub(withdrawnAmount));
})
let daiBalance = await daiContract.methods.balanceOf(contract.address).call() */
let receipt = await contract.remove_liquidity_one_coin("100000000000", 0, 1, { from: account }) });
let withdrawnAmount = receipt.logs[0].args.withdrawnAmount.toString()
let daiBalanceAfter = await daiContract.methods.balanceOf(contract.address).call()
//weird Ganache errors sometimes "cannot decode event"
console.log(+daiBalance, +daiBalanceAfter, +withdrawnAmount)
//expect(BN(daiBalance)).to.be.a.bignumber.equal(BN(daiBalanceAfter).sub(withdrawnAmount));
})
});

View File

@ -54,6 +54,12 @@ module.exports = {
port: 8545, // Standard Ethereum port (default: none) port: 8545, // Standard Ethereum port (default: none)
network_id: "*", // Any network (default: none) network_id: "*", // Any network (default: none)
}, },
// Tenderly Proxy
proxy: {
host: "127.0.0.1", // Localhost (default: none)
port: 9545, // Standard Ethereum port (default: none)
network_id: "*", // Any network (default: none)
},
// Another network with more advanced options... // Another network with more advanced options...
// advanced: { // advanced: {
@ -108,7 +114,7 @@ module.exports = {
// Configure your compilers // Configure your compilers
compilers: { compilers: {
solc: { solc: {
version: "v0.6.0", // Fetch exact version from solc-bin (default: truffle's version) version: "v0.6.2", // Fetch exact version from solc-bin (default: truffle's version)
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false) // docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
// settings: { // See the solidity docs for advice about optimization and evmVersion // settings: { // See the solidity docs for advice about optimization and evmVersion
// optimizer: { // optimizer: {