From 7f896a12de7bc73c57dd0c522f6587b1690a5e53 Mon Sep 17 00:00:00 2001 From: Lecky Lao Date: Sat, 4 Jul 2020 00:43:19 +1000 Subject: [PATCH] change connectorID method in stores to virtual view; adding connectorID method in connector as override and set model, id in constructor; modify migration to deploy and set model, id; update ganache to unlock master; fixing curveProtocol test to use master address and get dai from uniswap; fixing curveSBTCProtocol test to use cast for the sell connector method; --- contracts/common/stores.sol | 4 +- contracts/connectors/curvesbtc.sol | 11 +++++ migrations/2_deploy_connector.js | 11 +++-- package.json | 2 +- test/CurveProtocol.js | 34 ++++++++++++++- test/CurveSBTCProtocol.js | 67 ++++++++++++++++++++++++------ test/abi/account.json | 1 + test/abi/connectors.json | 1 + 8 files changed, 111 insertions(+), 20 deletions(-) create mode 100644 test/abi/account.json create mode 100644 test/abi/connectors.json diff --git a/contracts/common/stores.sol b/contracts/common/stores.sol index 7926bb7..00daf65 100644 --- a/contracts/common/stores.sol +++ b/contracts/common/stores.sol @@ -51,8 +51,8 @@ contract Stores { /** * @dev Connector Details - needs to be changed before deployment */ - function connectorID() public pure returns(uint model, uint id) { + function connectorID() public virtual view returns(uint model, uint id) { (model, id) = (0, 0); } -} \ No newline at end of file +} diff --git a/contracts/connectors/curvesbtc.sol b/contracts/connectors/curvesbtc.sol index 12ecb6e..8d5022f 100644 --- a/contracts/connectors/curvesbtc.sol +++ b/contracts/connectors/curvesbtc.sol @@ -206,5 +206,16 @@ contract CurveSBTCProtocol is CurveSBTCHelpers { contract ConnectSBTCCurve is CurveSBTCProtocol { string public name = "Curve-sbtc-v1"; + uint public _model; + uint public _id; + + constructor (uint model, uint id) public { + _model = model; + _id = id; + } + + function connectorID() public override view returns(uint model, uint id) { + (model, id) = (_model, _id); + } } diff --git a/migrations/2_deploy_connector.js b/migrations/2_deploy_connector.js index d3f69ce..18f5843 100644 --- a/migrations/2_deploy_connector.js +++ b/migrations/2_deploy_connector.js @@ -1,7 +1,12 @@ const CurveProtocol = artifacts.require("CurveProtocol"); -const CurveSBTCProtocol = artifacts.require("CurveSBTCProtocol"); +const ConnectSBTCCurve = artifacts.require("ConnectSBTCCurve"); -module.exports = function(deployer) { +const connectorsABI = require("../test/abi/connectors.json"); +let connectorsAddr = "0xD6A602C01a023B98Ecfb29Df02FBA380d3B21E0c"; +let connectorInstance = new web3.eth.Contract(connectorsABI, connectorsAddr); + +module.exports = async function(deployer) { deployer.deploy(CurveProtocol); - deployer.deploy(CurveSBTCProtocol); + let connectorLength = await connectorInstance.methods.connectorLength().call(); + deployer.deploy(ConnectSBTCCurve, 1, +connectorLength + 1); }; diff --git a/package.json b/package.json index 4f1376c..a354223 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "coverage": "./node_modules/.bin/solidity-coverage", "solium": "solium -d contracts/", "build-contracts": "sol-merger \"./contracts/connectors/mock.sol\" ./contracts/build", - "ganache": "ganache-cli --deterministic --unlock 0x9eb7f2591ed42dee9315b6e2aaf21ba85ea69f8c -f https://mainnet.infura.io/v3/" + "ganache": "ganache-cli --deterministic --unlock 0xfcd22438ad6ed564a1c26151df73f6b33b817b56 -f https://mainnet.infura.io/v3/" }, "repository": { "type": "git", diff --git a/test/CurveProtocol.js b/test/CurveProtocol.js index 29325fd..fdda7d3 100644 --- a/test/CurveProtocol.js +++ b/test/CurveProtocol.js @@ -3,6 +3,7 @@ const daiABI = require('./abi/dai'); const erc20 = require('./abi/erc20') const swap_abi = require('./abi/swap') const { ether, balance } = require('@openzeppelin/test-helpers'); +const uniswap = require("@studydefi/money-legos/uniswap"); const BN = require('bn.js') @@ -11,7 +12,7 @@ const expect = chai.expect chai.use(require('chai-bn')(BN)); // userAddress must be unlocked using --unlock ADDRESS -const userAddress = '0x9eb7f2591ed42dee9315b6e2aaf21ba85ea69f8c'; +const userAddress = '0xfcd22438ad6ed564a1c26151df73f6b33b817b56'; const daiAddress = '0x6b175474e89094c44da98b954eedeac495271d0f'; const daiContract = new web3.eth.Contract(daiABI, daiAddress); @@ -30,6 +31,37 @@ contract('Curve Protocol', async accounts => { beforeEach(async function() { account = accounts[0] contract = await CurveProtocol.deployed() + + let uniswapFactory = new web3.eth.Contract( + uniswap.factory.abi, + uniswap.factory.address + ); + + const daiExchangeAddress = await uniswapFactory.methods.getExchange( + daiAddress, + ).call(); + + const daiExchange = new web3.eth.Contract( + uniswap.exchange.abi, + daiExchangeAddress + ); + + const daiBefore = await daiContract.methods.balanceOf(userAddress).call(); + + await daiExchange.methods.ethToTokenSwapInput( + 1, // min amount of token retrieved + 2525644800, // random timestamp in the future (year 2050) + ).send( + { + gas: 4000000, + value: ether("5"), + from: userAddress + } + ); + + let daiAfter = await daiContract.methods.balanceOf(userAddress).call(); + + expect(daiAfter - daiBefore).to.be.at.least(+ether("1000")); }); it('should send ether to the user address', async () => { diff --git a/test/CurveSBTCProtocol.js b/test/CurveSBTCProtocol.js index e163d93..510d0a9 100644 --- a/test/CurveSBTCProtocol.js +++ b/test/CurveSBTCProtocol.js @@ -6,18 +6,29 @@ const { ether } = require('@openzeppelin/test-helpers'); -const CurveSBTCProtocol = artifacts.require('CurveSBTCProtocol'); +const ConnectSBTCCurve = artifacts.require('ConnectSBTCCurve'); const erc20 = require("@studydefi/money-legos/erc20"); const uniswap = require("@studydefi/money-legos/uniswap"); const sbtcABI = require("./abi/sbtc.json"); const erc20ABI = require("./abi/erc20.js"); +const connectorsABI = require("./abi/connectors.json"); +const accountABI = require("./abi/account.json"); -contract('CurveSBTCProtocol', async accounts => { +contract('ConnectSBTCCurve', async accounts => { const [sender, receiver] = accounts; - let contract; + let masterAddress = "0xfcd22438ad6ed564a1c26151df73f6b33b817b56"; + let accountID = 7; + let dsrAddr = "0xEEB007bea2Bbb0cA6502217E8867f8f7b021B8D5"; + + let connectorsAddr = "0xD6A602C01a023B98Ecfb29Df02FBA380d3B21E0c"; + let connectorInstance = new web3.eth.Contract(connectorsABI, connectorsAddr); + + // let accountAddr = "0x939Daad09fC4A9B8f8A9352A485DAb2df4F4B3F8"; + let accountInstance = new web3.eth.Contract(accountABI, dsrAddr); + let connectSBTCCurve; beforeEach(async function () { - contract = await CurveSBTCProtocol.deployed() + connectSBTCCurve = await ConnectSBTCCurve.deployed(); let wbtcContract = new web3.eth.Contract(erc20.wbtc.abi, erc20.wbtc.address); @@ -36,6 +47,10 @@ contract('CurveSBTCProtocol', async accounts => { ); const wbtcBefore = await wbtcContract.methods.balanceOf(sender).call(); + console.log("WBTC Before: ", wbtcBefore.toString()); + + const balanceBefore = await web3.eth.getBalance(sender); + console.log("Balance Before: ", balanceBefore.toString()); await wbtcExchange.methods.ethToTokenSwapInput( 1, // min amount of token retrieved @@ -49,38 +64,63 @@ contract('CurveSBTCProtocol', async accounts => { ); let wbtcAfter = await wbtcContract.methods.balanceOf(sender).call(); + console.log("WBTC After: ", wbtcAfter.toString()); + const balanceAfter = await web3.eth.getBalance(sender); + console.log("Balance After: ", balanceAfter.toString()); expect(wbtcAfter - wbtcBefore).to.be.at.least(10000000); + + // send WBTC to master + await wbtcContract.methods.transfer(dsrAddr, 10000000).send({from: sender}); + + // Send ETH to master + await web3.eth.sendTransaction({from: sender, to: masterAddress, value: ether("50")}); + + let connectorID = await connectSBTCCurve.connectorID(); + + // Enable the the given connector address + await connectorInstance.methods.enable(connectSBTCCurve.address).send({from: masterAddress}); + // check if the give connector address is enabled. + let isEnabled = await connectorInstance.methods.connectors(connectSBTCCurve.address).call(); + assert.ok(isEnabled); }); it('can sell WBTC for SBTC', async function () { const sbtcContract = new web3.eth.Contract(sbtcABI, "0xfe18be6b3bd88a2d2a7f928d00292e7a9963cfc6"); - const sbtcBefore = await sbtcContract.methods.balanceOf(sender).call(); + const sbtcBefore = await sbtcContract.methods.balanceOf(dsrAddr).call(); - const tx = await contract.sell( + const encoded = await connectSBTCCurve.contract.methods.sell( "0xfe18be6b3bd88a2d2a7f928d00292e7a9963cfc6", erc20.wbtc.address, 10000000, ( 0.09 / 0.1 * 1e18 ).toString(), 0, 0, - { - gas: 4000000, - from: sender - } - ); + ).encodeABI(); + + //Inputs for `cast()` function of DSA Account. + const castInputs = [ + [connectSBTCCurve.address], + [encoded], + masterAddress + ] + console.log("Cast Inputs: ", castInputs); + + // Execute `cast()` function + const tx = await accountInstance.methods.cast(...castInputs).send({from: masterAddress}); console.log(tx); const sbtcAfter = await sbtcContract.methods.balanceOf(sender).call(); expect(sbtcAfter - sbtcBefore).to.be.at.least(ether("0.09")); }); + /* it('can add and remove liquidity for wbtc', async function() { const curveTokenContract = new web3.eth.Contract( - erc20ABI, + erc20ABI, "0x075b1bb99792c9e1041ba13afef80c91a1e70fb3" - ) + ) const txDeposit = await contract.deposit( erc20.wbtc.address, @@ -116,5 +156,6 @@ contract('CurveSBTCProtocol', async accounts => { expect(balanceWithdraw).to.equal(0); }); + */ }); diff --git a/test/abi/account.json b/test/abi/account.json new file mode 100644 index 0000000..cdac97a --- /dev/null +++ b/test/abi/account.json @@ -0,0 +1 @@ +[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"origin","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"LogCast","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"LogDisable","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"LogEnable","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"_shield","type":"bool"}],"name":"LogSwitchShield","type":"event"},{"inputs":[{"internalType":"address[]","name":"_targets","type":"address[]"},{"internalType":"bytes[]","name":"_datas","type":"bytes[]"},{"internalType":"address","name":"_origin","type":"address"}],"name":"cast","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"disable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"enable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"instaIndex","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"isAuth","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"shield","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_shield","type":"bool"}],"name":"switchShield","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}] diff --git a/test/abi/connectors.json b/test/abi/connectors.json new file mode 100644 index 0000000..1462cdc --- /dev/null +++ b/test/abi/connectors.json @@ -0,0 +1 @@ +[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"}],"name":"LogAddController","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"connector","type":"address"}],"name":"LogDisable","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"connector","type":"address"}],"name":"LogEnable","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"connector","type":"address"}],"name":"LogEnableStatic","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"}],"name":"LogRemoveController","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"chief","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"connectorArray","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"connectorCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"connectorLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"connectors","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_connector","type":"address"}],"name":"disable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddress","type":"address"}],"name":"disableChief","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_connector","type":"address"}],"name":"enable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddress","type":"address"}],"name":"enableChief","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_connector","type":"address"}],"name":"enableStatic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"instaIndex","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_connectors","type":"address[]"}],"name":"isConnector","outputs":[{"internalType":"bool","name":"isOk","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_connectors","type":"address[]"}],"name":"isStaticConnector","outputs":[{"internalType":"bool","name":"isOk","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"staticConnectorArray","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"staticConnectorLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"staticConnectors","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]