From bf80497bb27eddf13a5c99677fb6841048f176b1 Mon Sep 17 00:00:00 2001 From: eccheung4 Date: Wed, 11 Aug 2021 15:36:57 -0700 Subject: [PATCH] Add claimAll function --- .../connectors/pooltogether/events.sol | 3 + .../connectors/pooltogether/interface.sol | 4 + .../mainnet/connectors/pooltogether/main.sol | 21 +++- test/pooltogether/pooltogether.test.js | 99 +++++++++++++++++-- 4 files changed, 118 insertions(+), 9 deletions(-) diff --git a/contracts/mainnet/connectors/pooltogether/events.sol b/contracts/mainnet/connectors/pooltogether/events.sol index 840f5906..459f7431 100644 --- a/contracts/mainnet/connectors/pooltogether/events.sol +++ b/contracts/mainnet/connectors/pooltogether/events.sol @@ -1,7 +1,10 @@ pragma solidity ^0.7.0; +import { TokenFaucetInterface } from "./interface.sol"; + contract Events { event LogDepositTo(address prizePool, address to, uint256 amount, address controlledToken, address referrer, uint256 getId, uint256 setId); event LogWithdrawInstantlyFrom(address prizePool, address from, uint256 amount, address controlledToken, uint256 maximumExitFee, uint256 getId, uint256 setId); event LogClaim(address tokenFaucet, address user); + event LogClaimAll(address tokenFaucetProxyFactory, address user, TokenFaucetInterface[] tokenFaucets); } \ No newline at end of file diff --git a/contracts/mainnet/connectors/pooltogether/interface.sol b/contracts/mainnet/connectors/pooltogether/interface.sol index e7e4ac2f..c82d1b8b 100644 --- a/contracts/mainnet/connectors/pooltogether/interface.sol +++ b/contracts/mainnet/connectors/pooltogether/interface.sol @@ -9,3 +9,7 @@ interface PrizePoolInterface { interface TokenFaucetInterface { function claim( address user) external returns (uint256); } + +interface TokenFaucetProxyFactoryInterface { + function claimAll(address user, TokenFaucetInterface[] calldata tokenFaucets) external; +} \ No newline at end of file diff --git a/contracts/mainnet/connectors/pooltogether/main.sol b/contracts/mainnet/connectors/pooltogether/main.sol index 3936f86c..6684d2bf 100644 --- a/contracts/mainnet/connectors/pooltogether/main.sol +++ b/contracts/mainnet/connectors/pooltogether/main.sol @@ -7,7 +7,7 @@ pragma solidity ^0.7.0; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - import { PrizePoolInterface, TokenFaucetInterface} from "./interface.sol"; + import { PrizePoolInterface, TokenFaucetInterface, TokenFaucetProxyFactoryInterface } from "./interface.sol"; import { TokenInterface } from "../../common/interfaces.sol"; import { Events } from "./events.sol"; @@ -106,6 +106,25 @@ abstract contract PoolTogetherResolver is Events, DSMath, Basic { _eventParam = abi.encode(address(tokenFaucet), address(user)); } + /** + * @dev Runs claim on all passed comptrollers for a user. + * @notice Runs claim on all passed comptrollers for a user. + * @param tokenFaucetProxyFactory The TokenFaucetProxyFactory address + * @param user The user to claim tokens for + * @param tokenFaucets The tokenFaucets to call claim on. + */ + function claimAll ( + address tokenFaucetProxyFactory, + address user, + TokenFaucetInterface[] calldata tokenFaucets + ) external returns (string memory _eventName, bytes memory _eventParam) { + TokenFaucetProxyFactoryInterface tokenFaucetProxyFactoryContract = TokenFaucetProxyFactoryInterface(tokenFaucetProxyFactory); + + tokenFaucetProxyFactoryContract.claimAll(user, tokenFaucets); + + _eventName = "LogClaimAll(address,address,TokenFaucetInterface[])"; + _eventParam = abi.encode(address(tokenFaucetProxyFactory), address(user), tokenFaucets); + } } contract ConnectV2PoolTogether is PoolTogetherResolver { diff --git a/test/pooltogether/pooltogether.test.js b/test/pooltogether/pooltogether.test.js index 6d2c5256..22f120d8 100644 --- a/test/pooltogether/pooltogether.test.js +++ b/test/pooltogether/pooltogether.test.js @@ -142,13 +142,18 @@ describe("PoolTogether", function () { expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("9")); }); - it("Should withdraw all PrizePool and get back 100 DAI", async function () { + it("Should wait 11 days, withdraw all PrizePool, get back 100 DAI, and claim POOL", async function () { const amount = ethers.utils.parseEther("100") // 100 DAI const spells = [ { connector: ptConnectorName, method: "withdrawInstantlyFrom", args: [prizePool, dsaWallet0.address, amount, controlledToken, amount, 0, 0] + }, + { + connector: ptConnectorName, + method: "claim", + args: [daiPoolFaucet, dsaWallet0.address] } ] @@ -165,6 +170,12 @@ describe("PoolTogether", function () { const tokenName = await cToken.name() console.log("\tBalance before: ", balance.toString(), tokenName) + // PoolToken is 0 + let poolToken = await ethers.getContractAt(abis.basic.erc20, poolTokenAddress) + const poolBalance = await poolToken.balanceOf(dsaWallet0.address) + const poolTokenName = await poolToken.name() + console.log("\tBalance before: ", poolBalance.toString(), poolTokenName) + // Increase time by 11 days so we get back all DAI without early withdrawal fee await ethers.provider.send("evm_increaseTime", [11*24*60*60]); @@ -183,9 +194,14 @@ describe("PoolTogether", function () { const balanceAfter = await cToken.balanceOf(dsaWallet0.address) console.log("\tBalance after: ", balanceAfter.toString(), tokenName) expect(balanceAfter.toNumber()).to.be.eq(0); + + // Expect Pool Token Balance to be greater than 0 + const poolBalanceAfter = await poolToken.balanceOf(dsaWallet0.address) + console.log("\tBalance after: ", poolBalanceAfter.toString(), poolTokenName) + expect(poolBalanceAfter).to.be.gt(ethers.utils.parseEther("0")); }); - it("Should deposit and withdraw all PrizePool, get back less than 100 DAI, and claim POOL", async function() { + it("Should deposit and withdraw all PrizePool, get back less than 100 DAI", async function() { const amount = ethers.utils.parseEther("100") // 100 DAI const spells = [ { @@ -197,11 +213,6 @@ describe("PoolTogether", function () { connector: ptConnectorName, method: "withdrawInstantlyFrom", args: [prizePool, dsaWallet0.address, amount, controlledToken, amount, 0, 0] - }, - { - connector: ptConnectorName, - method: "claim", - args: [daiPoolFaucet, dsaWallet0.address] } ] @@ -240,7 +251,79 @@ describe("PoolTogether", function () { console.log("\tBalance after: ", balanceAfter.toString(), tokenName) expect(balanceAfter.toNumber()).to.be.eq(0); - // Expect Pool Token Balance to be greate than 0 + // Expect Pool Token Balance to greater than 0 + const poolBalanceAfter = await poolToken.balanceOf(dsaWallet0.address) + console.log("\tBalance after: ", poolBalanceAfter.toString(), poolTokenName) + expect(poolBalanceAfter).to.be.gt(ethers.utils.parseEther("0")); + + }); + + it("Should deposit, wait 11 days, and withdraw all PrizePool, get 99 DAI, and claim all POOL using claimAll", async function() { + const amount = ethers.utils.parseEther("99") // 99 DAI + const depositSpells = [ + { + connector: ptConnectorName, + method: "depositTo", + args: [prizePool, dsaWallet0.address, amount, controlledToken, constants.address_zero, 0, 0] + } + ] + + const withdrawSpells = [ + { + connector: ptConnectorName, + method: "withdrawInstantlyFrom", + args: [prizePool, dsaWallet0.address, amount, controlledToken, amount, 0, 0] + }, + { + connector: ptConnectorName, + method: "claimAll", + args: [tokenFaucetProxyFactory, dsaWallet0.address, [daiPoolFaucet]] + } + ] + + // Before spell + // DAI balance is 0 + let daiToken = await ethers.getContractAt(abis.basic.erc20, token) + let daiBalance = await daiToken.balanceOf(dsaWallet0.address); + console.log("Before Spell:") + console.log("\tBalance before: ", daiBalance.toString(), tokens.dai.symbol); + + // PT Dai Ticket is 0 + let cToken = await ethers.getContractAt(abis.basic.erc20, controlledToken) + const balance = await cToken.balanceOf(dsaWallet0.address) + const tokenName = await cToken.name() + console.log("\tBalance before: ", balance.toString(), tokenName) + + // PoolToken is 0 + let poolToken = await ethers.getContractAt(abis.basic.erc20, poolTokenAddress) + const poolBalance = await poolToken.balanceOf(dsaWallet0.address) + const poolTokenName = await poolToken.name() + console.log("\tBalance before: ", poolBalance.toString(), poolTokenName) + + // Run spell transaction + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(depositSpells), wallet1.address) + const receipt = await tx.wait() + + // Increase time by 11 days so we get back all DAI without early withdrawal fee + await ethers.provider.send("evm_increaseTime", [11*24*60*60]); + + // Run spell transaction + const tx2 = await dsaWallet0.connect(wallet0).cast(...encodeSpells(withdrawSpells), wallet1.address) + const receipt2 = await tx2.wait() + + // After spell + // Expect DAI balance to be 99 + daiBalance = await daiToken.balanceOf(dsaWallet0.address); + console.log("After spell: "); + console.log("\tBalance after: ", daiBalance.toString(), tokens.dai.symbol); + expect(daiBalance).to.be.eq(ethers.utils.parseEther("99")); + + // Expect PT Dai Ticket to equal 0 + const balanceAfter = await cToken.balanceOf(dsaWallet0.address) + console.log("\tBalance after: ", balanceAfter.toString(), tokenName) + expect(balanceAfter.toNumber()).to.be.eq(0); + + // Expect Pool Token Balance to be greateir than 0 const poolBalanceAfter = await poolToken.balanceOf(dsaWallet0.address) console.log("\tBalance after: ", poolBalanceAfter.toString(), poolTokenName) expect(poolBalanceAfter).to.be.gt(ethers.utils.parseEther("0"));