mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
Fix: Add convertEthToWeth logic for WETH PrizePools
This commit is contained in:
parent
a8a7dd48d0
commit
2705ab4ad9
|
@ -4,7 +4,7 @@ import { TokenFaucetInterface } from "./interface.sol";
|
||||||
|
|
||||||
contract Events {
|
contract Events {
|
||||||
event LogDepositTo(address prizePool, address to, uint256 amount, address controlledToken, uint256 getId, uint256 setId);
|
event LogDepositTo(address prizePool, address to, uint256 amount, address controlledToken, uint256 getId, uint256 setId);
|
||||||
event LogWithdrawInstantlyFrom(address prizePool, address from, uint256 amount, address controlledToken, uint256 maximumExitFee, uint256 getId, uint256 setId);
|
event LogWithdrawInstantlyFrom(address prizePool, address from, uint256 amount, address controlledToken, uint256 maximumExitFee, uint256 exitFee, uint256 getId, uint256 setId);
|
||||||
event LogClaim(address tokenFaucet, address user, uint256 claimed, uint256 setId);
|
event LogClaim(address tokenFaucet, address user, uint256 claimed, uint256 setId);
|
||||||
event LogClaimAll(address tokenFaucetProxyFactory, address user, TokenFaucetInterface[] tokenFaucets);
|
event LogClaimAll(address tokenFaucetProxyFactory, address user, TokenFaucetInterface[] tokenFaucets);
|
||||||
event LogDepositToPod(address prizePoolToken, address pod, address to, uint256 amount, uint256 podShare, uint256 getId, uint256 setId);
|
event LogDepositToPod(address prizePoolToken, address pod, address to, uint256 amount, uint256 podShare, uint256 getId, uint256 setId);
|
||||||
|
|
|
@ -4,7 +4,6 @@ interface PrizePoolInterface {
|
||||||
function token() external view returns (address);
|
function token() external view returns (address);
|
||||||
function depositTo( address to, uint256 amount, address controlledToken, address referrer) external;
|
function depositTo( address to, uint256 amount, address controlledToken, address referrer) external;
|
||||||
function withdrawInstantlyFrom( address from, uint256 amount, address controlledToken, uint256 maximumExitFee) external returns (uint256);
|
function withdrawInstantlyFrom( address from, uint256 amount, address controlledToken, uint256 maximumExitFee) external returns (uint256);
|
||||||
function calculateEarlyExitFee( address from, address controlledToken, uint256 amount) external returns ( uint256 exitFee, uint256 burnedCredit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TokenFaucetInterface {
|
interface TokenFaucetInterface {
|
||||||
|
@ -16,6 +15,7 @@ interface TokenFaucetProxyFactoryInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PodInterface {
|
interface PodInterface {
|
||||||
|
function token() external view returns (address);
|
||||||
function depositTo(address to, uint256 tokenAmount) external returns (uint256);
|
function depositTo(address to, uint256 tokenAmount) external returns (uint256);
|
||||||
function withdraw(uint256 shareAmount, uint256 maxFee) external returns (uint256);
|
function withdraw(uint256 shareAmount, uint256 maxFee) external returns (uint256);
|
||||||
function balanceOf(address account) external view returns (uint256);
|
function balanceOf(address account) external view returns (uint256);
|
||||||
|
|
|
@ -10,6 +10,7 @@ pragma solidity ^0.7.0;
|
||||||
import { PrizePoolInterface, TokenFaucetInterface, TokenFaucetProxyFactoryInterface, PodInterface } from "./interface.sol";
|
import { PrizePoolInterface, TokenFaucetInterface, TokenFaucetProxyFactoryInterface, PodInterface } from "./interface.sol";
|
||||||
|
|
||||||
import { TokenInterface } from "../../common/interfaces.sol";
|
import { TokenInterface } from "../../common/interfaces.sol";
|
||||||
|
import { Stores } from "../../common/stores.sol";
|
||||||
import { Events } from "./events.sol";
|
import { Events } from "./events.sol";
|
||||||
import { DSMath } from "../../common/math.sol";
|
import { DSMath } from "../../common/math.sol";
|
||||||
import { Basic } from "../../common/basic.sol";
|
import { Basic } from "../../common/basic.sol";
|
||||||
|
@ -39,10 +40,18 @@ abstract contract PoolTogetherResolver is Events, DSMath, Basic {
|
||||||
PrizePoolInterface prizePoolContract = PrizePoolInterface(prizePool);
|
PrizePoolInterface prizePoolContract = PrizePoolInterface(prizePool);
|
||||||
address prizePoolToken = prizePoolContract.token();
|
address prizePoolToken = prizePoolContract.token();
|
||||||
|
|
||||||
// Approve prizePool
|
bool isEth = prizePoolToken == wethAddr;
|
||||||
TokenInterface tokenContract = TokenInterface(prizePoolToken);
|
TokenInterface tokenContract = TokenInterface(prizePoolToken);
|
||||||
|
|
||||||
|
if (isEth) {
|
||||||
|
_amount = _amount == uint256(-1) ? address(this).balance : _amount;
|
||||||
|
convertEthToWeth(isEth, tokenContract, _amount);
|
||||||
|
} else {
|
||||||
_amount = _amount == uint256(-1) ? tokenContract.balanceOf(address(this)) : _amount;
|
_amount = _amount == uint256(-1) ? tokenContract.balanceOf(address(this)) : _amount;
|
||||||
tokenContract.approve(prizePool, _amount);
|
}
|
||||||
|
|
||||||
|
// Approve prizePool
|
||||||
|
approve(tokenContract, prizePool, _amount);
|
||||||
|
|
||||||
prizePoolContract.depositTo(address(this), _amount, controlledToken, address(0));
|
prizePoolContract.depositTo(address(this), _amount, controlledToken, address(0));
|
||||||
|
|
||||||
|
@ -74,16 +83,22 @@ abstract contract PoolTogetherResolver is Events, DSMath, Basic {
|
||||||
uint _amount = getUint(getId, amount);
|
uint _amount = getUint(getId, amount);
|
||||||
|
|
||||||
PrizePoolInterface prizePoolContract = PrizePoolInterface(prizePool);
|
PrizePoolInterface prizePoolContract = PrizePoolInterface(prizePool);
|
||||||
|
address prizePoolToken = prizePoolContract.token();
|
||||||
|
TokenInterface tokenContract = TokenInterface(prizePoolToken);
|
||||||
|
|
||||||
TokenInterface ticketToken = TokenInterface(controlledToken);
|
TokenInterface ticketToken = TokenInterface(controlledToken);
|
||||||
_amount = _amount == uint256(-1) ? ticketToken.balanceOf(address(this)) : _amount;
|
_amount = _amount == uint256(-1) ? ticketToken.balanceOf(address(this)) : _amount;
|
||||||
|
|
||||||
prizePoolContract.withdrawInstantlyFrom(address(this), _amount, controlledToken, maximumExitFee);
|
uint exitFee = prizePoolContract.withdrawInstantlyFrom(address(this), _amount, controlledToken, maximumExitFee);
|
||||||
|
|
||||||
|
_amount = _amount - exitFee;
|
||||||
|
|
||||||
|
convertWethToEth(prizePoolToken == wethAddr, tokenContract, _amount);
|
||||||
|
|
||||||
setUint(setId, _amount);
|
setUint(setId, _amount);
|
||||||
|
|
||||||
_eventName = "LogWithdrawInstantlyFrom(address,address,uint256,address,uint256,uint256,uint256)";
|
_eventName = "LogWithdrawInstantlyFrom(address,address,uint256,address,uint256,uint256,uint256,uint256)";
|
||||||
_eventParam = abi.encode(address(prizePool), address(this), _amount, address(controlledToken), maximumExitFee, getId, setId);
|
_eventParam = abi.encode(address(prizePool), address(this), _amount, address(controlledToken), maximumExitFee, exitFee, getId, setId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,10 +159,17 @@ abstract contract PoolTogetherResolver is Events, DSMath, Basic {
|
||||||
|
|
||||||
PodInterface podContract = PodInterface(pod);
|
PodInterface podContract = PodInterface(pod);
|
||||||
|
|
||||||
|
bool isEth = prizePoolToken == wethAddr;
|
||||||
|
|
||||||
// Approve pod
|
// Approve pod
|
||||||
TokenInterface tokenContract = TokenInterface(prizePoolToken);
|
TokenInterface tokenContract = TokenInterface(prizePoolToken);
|
||||||
|
if (isEth) {
|
||||||
|
_tokenAmount = _tokenAmount == uint256(-1) ? address(this).balance : _tokenAmount;
|
||||||
|
convertEthToWeth(isEth, tokenContract, _tokenAmount);
|
||||||
|
} else {
|
||||||
_tokenAmount = _tokenAmount == uint256(-1) ? tokenContract.balanceOf(address(this)) : _tokenAmount;
|
_tokenAmount = _tokenAmount == uint256(-1) ? tokenContract.balanceOf(address(this)) : _tokenAmount;
|
||||||
tokenContract.approve(pod, _tokenAmount);
|
}
|
||||||
|
approve(tokenContract, pod, _tokenAmount);
|
||||||
|
|
||||||
uint256 _podShare = podContract.depositTo(address(this), _tokenAmount);
|
uint256 _podShare = podContract.depositTo(address(this), _tokenAmount);
|
||||||
|
|
||||||
|
@ -182,6 +204,8 @@ abstract contract PoolTogetherResolver is Events, DSMath, Basic {
|
||||||
|
|
||||||
uint256 _tokenAmount = podContract.withdraw(_shareAmount, maxFee);
|
uint256 _tokenAmount = podContract.withdraw(_shareAmount, maxFee);
|
||||||
|
|
||||||
|
convertWethToEth(address(podContract.token()) == wethAddr, TokenInterface(podContract.token()), _tokenAmount);
|
||||||
|
|
||||||
setUint(setId, _tokenAmount);
|
setUint(setId, _tokenAmount);
|
||||||
|
|
||||||
_eventName = "LogWithdrawFromPod(address,uint256,uint256,uint256,uint256,uint256)";
|
_eventName = "LogWithdrawFromPod(address,uint256,uint256,uint256,uint256,uint256)";
|
||||||
|
|
|
@ -34,12 +34,22 @@ const POOL_PRIZE_POOL_ADDR = "0x396b4489da692788e327e2e4b2b0459a5ef26791" // P
|
||||||
const PT_POOL_TICKET_ADDR = "0x27d22a7648e955e510a40bdb058333e9190d12d4" // Pool Together POOL Ticket
|
const PT_POOL_TICKET_ADDR = "0x27d22a7648e955e510a40bdb058333e9190d12d4" // Pool Together POOL Ticket
|
||||||
const WETH_ADDR = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" // WETH
|
const WETH_ADDR = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" // WETH
|
||||||
|
|
||||||
|
// Community WETH Prize Pool (Rari): https://reference-app.pooltogether.com/pools/mainnet/0xa88ca010b32a54d446fc38091ddbca55750cbfc3/manage#stats
|
||||||
|
const WETH_PRIZE_POOL_ADDR = "0xa88ca010b32a54d446fc38091ddbca55750cbfc3" // Community WETH Prize Pool (Rari)
|
||||||
|
const WETH_POOL_TICKET_ADDR = "0x9b5c30aeb9ce2a6a121cea9a85bc0d662f6d9b40" // Community WETH Prize Pool Ticket (Rari)
|
||||||
|
|
||||||
const prizePoolABI = [
|
const prizePoolABI = [
|
||||||
"function calculateEarlyExitFee( address from, address controlledToken, uint256 amount) external returns ( uint256 exitFee, uint256 burnedCredit)"
|
"function calculateEarlyExitFee( address from, address controlledToken, uint256 amount) external returns ( uint256 exitFee, uint256 burnedCredit)"
|
||||||
]
|
]
|
||||||
|
|
||||||
const podABI = [
|
const podABI = [
|
||||||
"function getEarlyExitFee(uint256 amount) external returns (uint256)"
|
"function getEarlyExitFee(uint256 amount) external returns (uint256)",
|
||||||
|
"function balanceOfUnderlying(address user) external view returns (uint256 amount)"
|
||||||
|
]
|
||||||
|
|
||||||
|
const POD_FACTORY_ADDRESS = "0x4e3a9f9fbafb2ec49727cffa2a411f7a0c1c4ce1"
|
||||||
|
const podFactoryABI = [
|
||||||
|
"function create( address _prizePool, address _ticket, address _faucet, address _manager, uint8 _decimals) external returns (address pod)"
|
||||||
]
|
]
|
||||||
|
|
||||||
describe("PoolTogether", function () {
|
describe("PoolTogether", function () {
|
||||||
|
@ -603,4 +613,151 @@ describe("PoolTogether", function () {
|
||||||
expect(poolPoolTicketBalanceAfter, `PoolTogether POOL Ticket greater than 0`).to.be.gt(0);
|
expect(poolPoolTicketBalanceAfter, `PoolTogether POOL Ticket greater than 0`).to.be.gt(0);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("Main - WETH Prize Pool Test", function () {
|
||||||
|
it("Deposit 1 ETH into WETH Prize Pool and withdraw immediately", async function () {
|
||||||
|
const amount = ethers.utils.parseEther("1") // 1 ETH
|
||||||
|
const setId = "83478237"
|
||||||
|
const spells = [
|
||||||
|
{
|
||||||
|
connector: ptConnectorName,
|
||||||
|
method: "depositTo",
|
||||||
|
args: [WETH_PRIZE_POOL_ADDR, amount, WETH_POOL_TICKET_ADDR, 0, setId]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
connector: ptConnectorName,
|
||||||
|
method: "withdrawInstantlyFrom",
|
||||||
|
args: [WETH_PRIZE_POOL_ADDR, amount, WETH_POOL_TICKET_ADDR, amount, setId, 0]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
// Before Spell
|
||||||
|
const ethBalanceBefore = await ethers.provider.getBalance(dsaWallet0.address);
|
||||||
|
|
||||||
|
// Run spell transaction
|
||||||
|
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||||
|
const receipt = await tx.wait()
|
||||||
|
|
||||||
|
// After spell
|
||||||
|
const ethBalanceAfter = await ethers.provider.getBalance(dsaWallet0.address);
|
||||||
|
|
||||||
|
// ETH used for transaction
|
||||||
|
expect(ethBalanceAfter, `ETH Balance less than before spell because of early withdrawal fee`).to.be.lte(ethBalanceBefore);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Deposit 1 ETH into WETH Prize Pool, wait 14 days, then withdraw", async function () {
|
||||||
|
const amount = ethers.utils.parseEther("1") // 1 ETH
|
||||||
|
const depositSpell = [
|
||||||
|
{
|
||||||
|
connector: ptConnectorName,
|
||||||
|
method: "depositTo",
|
||||||
|
args: [WETH_PRIZE_POOL_ADDR, amount, WETH_POOL_TICKET_ADDR, 0, 0]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const withdrawSpell = [
|
||||||
|
{
|
||||||
|
connector: ptConnectorName,
|
||||||
|
method: "withdrawInstantlyFrom",
|
||||||
|
args: [WETH_PRIZE_POOL_ADDR, amount, WETH_POOL_TICKET_ADDR, amount, 0, 0]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// Before Deposit Spell
|
||||||
|
let ethBalanceBefore = await ethers.provider.getBalance(dsaWallet0.address);
|
||||||
|
|
||||||
|
// Run deposit spell transaction
|
||||||
|
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(depositSpell), wallet1.address)
|
||||||
|
const receipt = await tx.wait()
|
||||||
|
|
||||||
|
// After Deposit spell
|
||||||
|
let ethBalanceAfter = await ethers.provider.getBalance(dsaWallet0.address);
|
||||||
|
|
||||||
|
expect(ethBalanceAfter, `ETH Balance less than before spell`).to.be.lte(ethBalanceBefore);
|
||||||
|
|
||||||
|
// Increase time by 11 days so we get back all ETH without early withdrawal fee
|
||||||
|
await ethers.provider.send("evm_increaseTime", [14*24*60*60]);
|
||||||
|
await ethers.provider.send("evm_mine");
|
||||||
|
|
||||||
|
// Run withdraw spell transaction
|
||||||
|
const tx2 = await dsaWallet0.connect(wallet0).cast(...encodeSpells(withdrawSpell), wallet1.address)
|
||||||
|
const receipt2 = await tx.wait()
|
||||||
|
|
||||||
|
// After Deposit spell
|
||||||
|
ethBalanceAfter = await ethers.provider.getBalance(dsaWallet0.address);
|
||||||
|
|
||||||
|
expect(ethBalanceAfter, `ETH Balance equal to before spell because no early exit fee`).to.be.eq(ethBalanceBefore);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Main - WETH Pod Test", function() {
|
||||||
|
let podAddress
|
||||||
|
it("Should deposit 1 ETH in WETH Pod and get Pod Ticket", async function() {
|
||||||
|
const amount = ethers.utils.parseEther("1")
|
||||||
|
|
||||||
|
// Create Pod for WETH Prize Pool (Rari)
|
||||||
|
const podFactoryContract = new ethers.Contract(POD_FACTORY_ADDRESS, podFactoryABI, masterSigner)
|
||||||
|
podAddress = await podFactoryContract.callStatic.create(WETH_PRIZE_POOL_ADDR, WETH_POOL_TICKET_ADDR, constants.address_zero, wallet0.address, 18)
|
||||||
|
await podFactoryContract.create(WETH_PRIZE_POOL_ADDR, WETH_POOL_TICKET_ADDR, constants.address_zero, wallet0.address, 18)
|
||||||
|
|
||||||
|
const spells = [
|
||||||
|
{
|
||||||
|
connector: ptConnectorName,
|
||||||
|
method: "depositToPod",
|
||||||
|
args: [WETH_ADDR, podAddress, amount, 0, 0]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// Before Deposit Spell
|
||||||
|
const podContract = new ethers.Contract(podAddress, podABI, ethers.provider);
|
||||||
|
let podBalanceBefore = await podContract.balanceOfUnderlying(dsaWallet0.address)
|
||||||
|
expect(podBalanceBefore, `Pod balance equal to 0`).to.be.eq(0);
|
||||||
|
|
||||||
|
let ethBalanceBefore = await ethers.provider.getBalance(dsaWallet0.address);
|
||||||
|
|
||||||
|
// Run spell transaction
|
||||||
|
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||||
|
const receipt = await tx.wait()
|
||||||
|
|
||||||
|
// After Deposit spell
|
||||||
|
let ethBalanceAfter = await ethers.provider.getBalance(dsaWallet0.address);
|
||||||
|
expect(ethBalanceAfter, `ETH balance less than before`).to.be.lt(ethBalanceBefore);
|
||||||
|
|
||||||
|
podBalanceAfter = await podContract.balanceOfUnderlying(dsaWallet0.address)
|
||||||
|
expect(podBalanceAfter, `Pod balance equal to 1`).to.be.eq(ethers.utils.parseEther("1"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should withdraw 1 Ticket from WETH Pod and get back ETH", async function() {
|
||||||
|
const amount = ethers.utils.parseEther("1")
|
||||||
|
|
||||||
|
const podContract = new ethers.Contract(podAddress, podABI, ethers.provider);
|
||||||
|
let maxFee = await podContract.callStatic["getEarlyExitFee"](amount);
|
||||||
|
expect(maxFee, "Exit Fee equal to 0 DAI because token still in float").to.be.eq(0);
|
||||||
|
// maxFee depends on if token has been deposited to PrizePool yet
|
||||||
|
|
||||||
|
const spells = [
|
||||||
|
{
|
||||||
|
connector: ptConnectorName,
|
||||||
|
method: "withdrawFromPod",
|
||||||
|
args: [podAddress, amount, maxFee, 0, 0]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// Before Deposit Spell
|
||||||
|
let podBalanceBefore = await podContract.balanceOfUnderlying(dsaWallet0.address)
|
||||||
|
expect(podBalanceBefore, `Pod balance equal to 1`).to.be.eq(ethers.utils.parseEther("1"));
|
||||||
|
|
||||||
|
let ethBalanceBefore = await ethers.provider.getBalance(dsaWallet0.address);
|
||||||
|
|
||||||
|
// Run spell transaction
|
||||||
|
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||||
|
const receipt = await tx.wait()
|
||||||
|
|
||||||
|
// After Deposit spell
|
||||||
|
let ethBalanceAfter = await ethers.provider.getBalance(dsaWallet0.address);
|
||||||
|
expect(ethBalanceAfter, `ETH balance greater than before`).to.be.gt(ethBalanceBefore);
|
||||||
|
|
||||||
|
podBalanceAfter = await podContract.balanceOfUnderlying(dsaWallet0.address)
|
||||||
|
expect(podBalanceAfter, `Pod balance equal to 0`).to.be.eq(ethers.utils.parseEther("0"));
|
||||||
|
});
|
||||||
|
});
|
||||||
})
|
})
|
Loading…
Reference in New Issue
Block a user