mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
Merge branch 'main' into ubiquity
This commit is contained in:
commit
684bc6acb9
10
contracts/avalanche/connectors/instapool_v3/events.sol
Normal file
10
contracts/avalanche/connectors/instapool_v3/events.sol
Normal file
|
@ -0,0 +1,10 @@
|
|||
pragma solidity >=0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract Events {
|
||||
event LogFlashBorrow(address token, uint256 tokenAmt);
|
||||
event LogFlashPayback(address token, uint256 tokenAmt);
|
||||
|
||||
event LogFlashMultiBorrow(address[] token, uint256[] tokenAmts);
|
||||
event LogFlashMultiPayback(address[] token, uint256[] tokenAmts);
|
||||
}
|
17
contracts/avalanche/connectors/instapool_v3/interfaces.sol
Normal file
17
contracts/avalanche/connectors/instapool_v3/interfaces.sol
Normal file
|
@ -0,0 +1,17 @@
|
|||
pragma solidity >=0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
interface InstaFlashV2Interface {
|
||||
function initiateFlashLoan(address token, uint256 amt, uint route, bytes calldata data) external;
|
||||
function initiateMultiFlashLoan(
|
||||
address[] memory tokens_,
|
||||
uint256[] memory amounts_,
|
||||
uint256,
|
||||
bytes calldata data
|
||||
) external;
|
||||
}
|
||||
|
||||
interface AccountInterface {
|
||||
function enable(address) external;
|
||||
function disable(address) external;
|
||||
}
|
139
contracts/avalanche/connectors/instapool_v3/main.sol
Normal file
139
contracts/avalanche/connectors/instapool_v3/main.sol
Normal file
|
@ -0,0 +1,139 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @title Instapool.
|
||||
* @dev Inbuilt Flash Loan in DSA
|
||||
*/
|
||||
|
||||
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
|
||||
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
|
||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { AccountInterface } from "./interfaces.sol";
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Stores } from "../../common/stores.sol";
|
||||
import { Variables } from "./variables.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
||||
contract LiquidityResolver is DSMath, Stores, Variables, Events {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/**
|
||||
* @dev Borrow Flashloan and Cast spells.
|
||||
* @notice Borrow Flashloan and Cast spells.
|
||||
* @param token Token Address.
|
||||
* @param amt Token Amount.
|
||||
* @param route Flashloan source route.
|
||||
* @param data targets & data for cast.
|
||||
*/
|
||||
function flashBorrowAndCast(
|
||||
address token,
|
||||
uint amt,
|
||||
uint route,
|
||||
bytes memory data
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
AccountInterface(address(this)).enable(address(instaPool));
|
||||
(string[] memory _targets, bytes[] memory callDatas) = abi.decode(data, (string[], bytes[]));
|
||||
|
||||
bytes memory callData = abi.encodeWithSignature("cast(string[],bytes[],address)", _targets, callDatas, address(instaPool));
|
||||
|
||||
instaPool.initiateFlashLoan(token, amt, route, callData);
|
||||
|
||||
AccountInterface(address(this)).disable(address(instaPool));
|
||||
|
||||
_eventName = "LogFlashBorrow(address,uint256)";
|
||||
_eventParam = abi.encode(token, amt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return token to InstaPool.
|
||||
* @notice Return token to InstaPool.
|
||||
* @param token Token Address.
|
||||
* @param amt Token Amount.
|
||||
* @param getId Get token amount at this ID from `InstaMemory` Contract.
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function flashPayback(
|
||||
address token,
|
||||
uint amt,
|
||||
uint getId,
|
||||
uint setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amt = getUint(getId, amt);
|
||||
|
||||
IERC20 tokenContract = IERC20(token);
|
||||
|
||||
if (token == avaxAddr) {
|
||||
Address.sendValue(payable(address(instaPool)), _amt);
|
||||
} else {
|
||||
tokenContract.safeTransfer(address(instaPool), _amt);
|
||||
}
|
||||
|
||||
setUint(setId, _amt);
|
||||
|
||||
_eventName = "LogFlashPayback(address,uint256)";
|
||||
_eventParam = abi.encode(token, amt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Borrow multi-tokens Flashloan and Cast spells.
|
||||
* @notice Borrow multi-tokens Flashloan and Cast spells.
|
||||
* @param tokens_ Array of Token Addresses.
|
||||
* @param amts_ Array of Token Amounts.
|
||||
* @param route Flashloan source route.
|
||||
* @param data targets & data for cast.
|
||||
*/
|
||||
function flashMultiBorrowAndCast(
|
||||
address[] memory tokens_,
|
||||
uint[] memory amts_,
|
||||
uint route,
|
||||
bytes memory data
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
AccountInterface(address(this)).enable(address(instaPool));
|
||||
(string[] memory _targets, bytes[] memory callDatas) = abi.decode(data, (string[], bytes[]));
|
||||
|
||||
bytes memory callData = abi.encodeWithSignature("cast(string[],bytes[],address)", _targets, callDatas, address(instaPool));
|
||||
|
||||
instaPool.initiateMultiFlashLoan(tokens_, amts_, route, callData);
|
||||
|
||||
AccountInterface(address(this)).disable(address(instaPool));
|
||||
_eventName = "LogFlashMultiBorrow(address[],uint256[])";
|
||||
_eventParam = abi.encode(tokens_, amts_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return multi-tokens to InstaPool.
|
||||
* @notice Return multi-tokens to InstaPool.
|
||||
* @param tokens_ Array of Token Addresses.
|
||||
* @param amts_ Array of Token Amounts.
|
||||
* @param getIds Array of getId token amounts.
|
||||
* @param setIds Array of setId token amounts.
|
||||
*/
|
||||
function flashMultiPayback(
|
||||
address[] memory tokens_,
|
||||
uint[] memory amts_,
|
||||
uint[] memory getIds,
|
||||
uint[] memory setIds
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
for (uint i = 0; i < tokens_.length; i++) {
|
||||
amts_[i] = getUint(getIds[i], amts_[i]);
|
||||
|
||||
if (tokens_[i] == avaxAddr) {
|
||||
Address.sendValue(payable(address(instaPool)), amts_[i]);
|
||||
} else {
|
||||
IERC20(tokens_[i]).safeTransfer(address(instaPool), amts_[i]);
|
||||
}
|
||||
|
||||
setUint(setIds[i], amts_[i]);
|
||||
}
|
||||
|
||||
_eventName = "LogFlashMultiPayback(address[],uint256[])";
|
||||
_eventParam = abi.encode(tokens_, amts_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
contract ConnectV2InstaPoolV3Avalanche is LiquidityResolver {
|
||||
string public name = "Instapool-v3";
|
||||
}
|
13
contracts/avalanche/connectors/instapool_v3/variables.sol
Normal file
13
contracts/avalanche/connectors/instapool_v3/variables.sol
Normal file
|
@ -0,0 +1,13 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import { InstaFlashV2Interface } from "./interfaces.sol";
|
||||
|
||||
contract Variables {
|
||||
|
||||
/**
|
||||
* @dev Instapool contract proxy
|
||||
*/
|
||||
InstaFlashV2Interface public constant instaPool = InstaFlashV2Interface(0x9686CE6Ad5C3f7b212CAF401b928c4bB3422E7Ba);
|
||||
|
||||
}
|
|
@ -21,6 +21,7 @@ contract LiquidityResolver is DSMath, Stores, Variables, Events {
|
|||
|
||||
/**
|
||||
* @dev Borrow Flashloan and Cast spells.
|
||||
* @notice Borrow Flashloan and Cast spells.
|
||||
* @param token Token Address.
|
||||
* @param amt Token Amount.
|
||||
* @param route Flashloan source route. (0: dYdX(ETH,DAI,USDC only), 1: MakerDAO(DAI only), 2: Compound(All borrowable tokens in Compound), 3: AaveV2(All borrowable tokens in AaveV2))
|
||||
|
@ -45,6 +46,7 @@ contract LiquidityResolver is DSMath, Stores, Variables, Events {
|
|||
|
||||
/**
|
||||
* @dev Return token to InstaPool.
|
||||
* @notice Return token to InstaPool.
|
||||
* @param token Token Address.
|
||||
* @param amt Token Amount.
|
||||
* @param getId Get token amount at this ID from `InstaMemory` Contract.
|
||||
|
|
10
contracts/mainnet/connectors/instapool_v3/events.sol
Normal file
10
contracts/mainnet/connectors/instapool_v3/events.sol
Normal file
|
@ -0,0 +1,10 @@
|
|||
pragma solidity >=0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract Events {
|
||||
event LogFlashBorrow(address token, uint256 tokenAmt);
|
||||
event LogFlashPayback(address token, uint256 tokenAmt);
|
||||
|
||||
event LogFlashMultiBorrow(address[] token, uint256[] tokenAmts);
|
||||
event LogFlashMultiPayback(address[] token, uint256[] tokenAmts);
|
||||
}
|
17
contracts/mainnet/connectors/instapool_v3/interfaces.sol
Normal file
17
contracts/mainnet/connectors/instapool_v3/interfaces.sol
Normal file
|
@ -0,0 +1,17 @@
|
|||
pragma solidity >=0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
interface InstaFlashV2Interface {
|
||||
function initiateFlashLoan(address token, uint256 amt, uint route, bytes calldata data) external;
|
||||
function initiateMultiFlashLoan(
|
||||
address[] memory tokens_,
|
||||
uint256[] memory amounts_,
|
||||
uint256,
|
||||
bytes calldata data
|
||||
) external;
|
||||
}
|
||||
|
||||
interface AccountInterface {
|
||||
function enable(address) external;
|
||||
function disable(address) external;
|
||||
}
|
139
contracts/mainnet/connectors/instapool_v3/main.sol
Normal file
139
contracts/mainnet/connectors/instapool_v3/main.sol
Normal file
|
@ -0,0 +1,139 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @title Instapool.
|
||||
* @dev Inbuilt Flash Loan in DSA
|
||||
*/
|
||||
|
||||
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
|
||||
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
|
||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { AccountInterface } from "./interfaces.sol";
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Stores } from "../../common/stores.sol";
|
||||
import { Variables } from "./variables.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
||||
contract LiquidityResolver is DSMath, Stores, Variables, Events {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/**
|
||||
* @dev Borrow Flashloan and Cast spells.
|
||||
* @notice Borrow Flashloan and Cast spells.
|
||||
* @param token Token Address.
|
||||
* @param amt Token Amount.
|
||||
* @param route Flashloan source route.
|
||||
* @param data targets & data for cast.
|
||||
*/
|
||||
function flashBorrowAndCast(
|
||||
address token,
|
||||
uint amt,
|
||||
uint route,
|
||||
bytes memory data
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
AccountInterface(address(this)).enable(address(instaPool));
|
||||
(string[] memory _targets, bytes[] memory callDatas) = abi.decode(data, (string[], bytes[]));
|
||||
|
||||
bytes memory callData = abi.encodeWithSignature("cast(string[],bytes[],address)", _targets, callDatas, address(instaPool));
|
||||
|
||||
instaPool.initiateFlashLoan(token, amt, route, callData);
|
||||
|
||||
AccountInterface(address(this)).disable(address(instaPool));
|
||||
|
||||
_eventName = "LogFlashBorrow(address,uint256)";
|
||||
_eventParam = abi.encode(token, amt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return token to InstaPool.
|
||||
* @notice Return token to InstaPool.
|
||||
* @param token Token Address.
|
||||
* @param amt Token Amount.
|
||||
* @param getId Get token amount at this ID from `InstaMemory` Contract.
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function flashPayback(
|
||||
address token,
|
||||
uint amt,
|
||||
uint getId,
|
||||
uint setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amt = getUint(getId, amt);
|
||||
|
||||
IERC20 tokenContract = IERC20(token);
|
||||
|
||||
if (token == ethAddr) {
|
||||
Address.sendValue(payable(address(instaPool)), _amt);
|
||||
} else {
|
||||
tokenContract.safeTransfer(address(instaPool), _amt);
|
||||
}
|
||||
|
||||
setUint(setId, _amt);
|
||||
|
||||
_eventName = "LogFlashPayback(address,uint256)";
|
||||
_eventParam = abi.encode(token, amt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Borrow multi-tokens Flashloan and Cast spells.
|
||||
* @notice Borrow multi-tokens Flashloan and Cast spells.
|
||||
* @param tokens_ Array of Token Addresses.
|
||||
* @param amts_ Array of Token Amounts.
|
||||
* @param route Flashloan source route.
|
||||
* @param data targets & data for cast.
|
||||
*/
|
||||
function flashMultiBorrowAndCast(
|
||||
address[] memory tokens_,
|
||||
uint[] memory amts_,
|
||||
uint route,
|
||||
bytes memory data
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
AccountInterface(address(this)).enable(address(instaPool));
|
||||
(string[] memory _targets, bytes[] memory callDatas) = abi.decode(data, (string[], bytes[]));
|
||||
|
||||
bytes memory callData = abi.encodeWithSignature("cast(string[],bytes[],address)", _targets, callDatas, address(instaPool));
|
||||
|
||||
instaPool.initiateMultiFlashLoan(tokens_, amts_, route, callData);
|
||||
|
||||
AccountInterface(address(this)).disable(address(instaPool));
|
||||
_eventName = "LogFlashMultiBorrow(address[],uint256[])";
|
||||
_eventParam = abi.encode(tokens_, amts_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return multi-tokens to InstaPool.
|
||||
* @notice Return multi-tokens to InstaPool.
|
||||
* @param tokens_ Array of Token Addresses.
|
||||
* @param amts_ Array of Token Amounts.
|
||||
* @param getIds Array of getId token amounts.
|
||||
* @param setIds Array of setId token amounts.
|
||||
*/
|
||||
function flashMultiPayback(
|
||||
address[] memory tokens_,
|
||||
uint[] memory amts_,
|
||||
uint[] memory getIds,
|
||||
uint[] memory setIds
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
for (uint i = 0; i < tokens_.length; i++) {
|
||||
amts_[i] = getUint(getIds[i], amts_[i]);
|
||||
|
||||
if (tokens_[i] == ethAddr) {
|
||||
Address.sendValue(payable(address(instaPool)), amts_[i]);
|
||||
} else {
|
||||
IERC20(tokens_[i]).safeTransfer(address(instaPool), amts_[i]);
|
||||
}
|
||||
|
||||
setUint(setIds[i], amts_[i]);
|
||||
}
|
||||
|
||||
_eventName = "LogFlashMultiPayback(address[],uint256[])";
|
||||
_eventParam = abi.encode(tokens_, amts_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
contract ConnectV2InstaPoolV3 is LiquidityResolver {
|
||||
string public name = "Instapool-v3";
|
||||
}
|
13
contracts/mainnet/connectors/instapool_v3/variables.sol
Normal file
13
contracts/mainnet/connectors/instapool_v3/variables.sol
Normal file
|
@ -0,0 +1,13 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import { InstaFlashV2Interface } from "./interfaces.sol";
|
||||
|
||||
contract Variables {
|
||||
|
||||
/**
|
||||
* @dev Instapool contract proxy
|
||||
*/
|
||||
InstaFlashV2Interface public constant instaPool = InstaFlashV2Interface(0xF77A5935f35aDD4C2f524788805293EF86B87560);
|
||||
|
||||
}
|
13
contracts/mainnet/connectors/pooltogether/events.sol
Normal file
13
contracts/mainnet/connectors/pooltogether/events.sol
Normal file
|
@ -0,0 +1,13 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenFaucetInterface } from "./interface.sol";
|
||||
|
||||
contract Events {
|
||||
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 exitFee, uint256 getId, uint256 setId);
|
||||
event LogClaim(address tokenFaucet, address user, uint256 claimed, uint256 setId);
|
||||
event LogClaimAll(address tokenFaucetProxyFactory, address user, TokenFaucetInterface[] tokenFaucets);
|
||||
event LogClaimPodTokenDrop(address podTokenDrop, address user, uint256 claimed, uint256 setId);
|
||||
event LogDepositToPod(address prizePoolToken, address pod, address to, uint256 amount, uint256 podShare, uint256 getId, uint256 setId);
|
||||
event LogWithdrawFromPod(address pod, uint256 shareAmount, uint256 tokenAmount, uint256 maxFee, uint256 getId, uint256 setId);
|
||||
}
|
26
contracts/mainnet/connectors/pooltogether/interface.sol
Normal file
26
contracts/mainnet/connectors/pooltogether/interface.sol
Normal file
|
@ -0,0 +1,26 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
interface PrizePoolInterface {
|
||||
function token() external view returns (address);
|
||||
function depositTo( address to, uint256 amount, address controlledToken, address referrer) external;
|
||||
function withdrawInstantlyFrom( address from, uint256 amount, address controlledToken, uint256 maximumExitFee) external returns (uint256);
|
||||
}
|
||||
|
||||
interface PodTokenDropInterface {
|
||||
function claim(address user) external returns (uint256);
|
||||
}
|
||||
|
||||
interface TokenFaucetInterface {
|
||||
function claim( address user) external returns (uint256);
|
||||
}
|
||||
|
||||
interface TokenFaucetProxyFactoryInterface {
|
||||
function claimAll(address user, TokenFaucetInterface[] calldata tokenFaucets) external;
|
||||
}
|
||||
|
||||
interface PodInterface {
|
||||
function token() external view returns (address);
|
||||
function depositTo(address to, uint256 tokenAmount) external returns (uint256);
|
||||
function withdraw(uint256 shareAmount, uint256 maxFee) external returns (uint256);
|
||||
function balanceOf(address account) external view returns (uint256);
|
||||
}
|
238
contracts/mainnet/connectors/pooltogether/main.sol
Normal file
238
contracts/mainnet/connectors/pooltogether/main.sol
Normal file
|
@ -0,0 +1,238 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
/**
|
||||
* @title PoolTogether
|
||||
* @dev Deposit & Withdraw from PoolTogether
|
||||
*/
|
||||
|
||||
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
|
||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import { PrizePoolInterface, TokenFaucetInterface, TokenFaucetProxyFactoryInterface, PodInterface, PodTokenDropInterface } from "./interface.sol";
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { Stores } from "../../common/stores.sol";
|
||||
import { Events } from "./events.sol";
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
|
||||
abstract contract PoolTogetherResolver is Events, DSMath, Basic {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/**
|
||||
* @dev Deposit into Prize Pool
|
||||
* @notice Deposit assets into the Prize Pool in exchange for tokens
|
||||
* @param prizePool PrizePool address to deposit to
|
||||
* @param amount The amount of the underlying asset the user wishes to deposit. The Prize Pool contract should have been pre-approved by the caller to transfer the underlying ERC20 tokens.
|
||||
* @param controlledToken The address of the token that they wish to mint. For our default Prize Strategy this will either be the Ticket address or the Sponsorship address. Those addresses can be looked up on the Prize Strategy.
|
||||
* @param getId Get token amount at this ID from `InstaMemory` Contract.
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
|
||||
function depositTo(
|
||||
address prizePool,
|
||||
uint256 amount,
|
||||
address controlledToken,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable returns ( string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amount = getUint(getId, amount);
|
||||
|
||||
PrizePoolInterface prizePoolContract = PrizePoolInterface(prizePool);
|
||||
address prizePoolToken = prizePoolContract.token();
|
||||
|
||||
bool isEth = prizePoolToken == wethAddr;
|
||||
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;
|
||||
}
|
||||
|
||||
// Approve prizePool
|
||||
approve(tokenContract, prizePool, _amount);
|
||||
|
||||
prizePoolContract.depositTo(address(this), _amount, controlledToken, address(0));
|
||||
|
||||
setUint(setId, _amount);
|
||||
|
||||
_eventName = "LogDepositTo(address,address,uint256,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(address(prizePool), address(this), _amount, address(controlledToken), getId, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw from Prize Pool
|
||||
* @notice Withdraw assets from the Prize Pool instantly. A fairness fee may be charged for an early exit.
|
||||
* @param prizePool PrizePool address to withdraw from
|
||||
* @param amount The amount of tokens to redeem for assets.
|
||||
* @param controlledToken The address of the token to redeem (i.e. ticket or sponsorship)
|
||||
* @param maximumExitFee The maximum early exit fee the caller is willing to pay. This prevents the Prize Strategy from changing the fee on the fly. This should be pre-calculated by the calculateExitFee() fxn.
|
||||
* @param getId Get token amount at this ID from `InstaMemory` Contract.
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
|
||||
function withdrawInstantlyFrom (
|
||||
address prizePool,
|
||||
uint256 amount,
|
||||
address controlledToken,
|
||||
uint256 maximumExitFee,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amount = getUint(getId, amount);
|
||||
|
||||
PrizePoolInterface prizePoolContract = PrizePoolInterface(prizePool);
|
||||
address prizePoolToken = prizePoolContract.token();
|
||||
TokenInterface tokenContract = TokenInterface(prizePoolToken);
|
||||
|
||||
TokenInterface ticketToken = TokenInterface(controlledToken);
|
||||
_amount = _amount == uint256(-1) ? ticketToken.balanceOf(address(this)) : _amount;
|
||||
|
||||
uint exitFee = prizePoolContract.withdrawInstantlyFrom(address(this), _amount, controlledToken, maximumExitFee);
|
||||
|
||||
_amount = _amount - exitFee;
|
||||
|
||||
convertWethToEth(prizePoolToken == wethAddr, tokenContract, _amount);
|
||||
|
||||
setUint(setId, _amount);
|
||||
|
||||
_eventName = "LogWithdrawInstantlyFrom(address,address,uint256,address,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(address(prizePool), address(this), _amount, address(controlledToken), maximumExitFee, exitFee, getId, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Claim token from a Token Faucet
|
||||
* @notice Claim token from a Token Faucet
|
||||
* @param tokenFaucet TokenFaucet address
|
||||
* @param setId Set claimed amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function claim (
|
||||
address tokenFaucet,
|
||||
uint256 setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
TokenFaucetInterface tokenFaucetContract = TokenFaucetInterface(tokenFaucet);
|
||||
|
||||
uint256 claimed = tokenFaucetContract.claim(address(this));
|
||||
|
||||
setUint(setId, claimed);
|
||||
|
||||
_eventName = "LogClaim(address,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(address(tokenFaucet), address(this), claimed, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 tokenFaucets The tokenFaucets to call claim on.
|
||||
*/
|
||||
function claimAll (
|
||||
address tokenFaucetProxyFactory,
|
||||
TokenFaucetInterface[] calldata tokenFaucets
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
TokenFaucetProxyFactoryInterface tokenFaucetProxyFactoryContract = TokenFaucetProxyFactoryInterface(tokenFaucetProxyFactory);
|
||||
|
||||
tokenFaucetProxyFactoryContract.claimAll(address(this), tokenFaucets);
|
||||
|
||||
_eventName = "LogClaimAll(address,address,TokenFaucetInterface[])";
|
||||
_eventParam = abi.encode(address(tokenFaucetProxyFactory), address(this), tokenFaucets);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Claim asset rewards from a Pod TokenDrop
|
||||
* @notice Claim asset rewards from a TokenDrop
|
||||
* @param podTokenDrop Pod TokenDrop address
|
||||
* @param setId Set claimed amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function claimPodTokenDrop (
|
||||
address podTokenDrop,
|
||||
uint256 setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
PodTokenDropInterface podTokenDropContract = PodTokenDropInterface(podTokenDrop);
|
||||
|
||||
uint256 claimed = podTokenDropContract.claim(address(this));
|
||||
|
||||
setUint(setId, claimed);
|
||||
|
||||
_eventName = "LogClaimPodTokenDrop(address,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(address(podTokenDrop), address(this), claimed, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Deposit into Pod
|
||||
* @notice Deposit assets into the Pod in exchange for share tokens
|
||||
* @param prizePoolToken Prize Pool Token Address
|
||||
* @param pod Pod address to deposit to
|
||||
* @param tokenAmount The amount of tokens to deposit. These are the same tokens used to deposit into the underlying prize pool.
|
||||
* @param getId Get token amount at this ID from `InstaMemory` Contract.
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function depositToPod(
|
||||
address prizePoolToken,
|
||||
address pod,
|
||||
uint256 tokenAmount,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable returns ( string memory _eventName, bytes memory _eventParam) {
|
||||
uint _tokenAmount= getUint(getId, tokenAmount);
|
||||
|
||||
PodInterface podContract = PodInterface(pod);
|
||||
|
||||
bool isEth = prizePoolToken == wethAddr;
|
||||
|
||||
// Approve pod
|
||||
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;
|
||||
}
|
||||
approve(tokenContract, pod, _tokenAmount);
|
||||
|
||||
uint256 _podShare = podContract.depositTo(address(this), _tokenAmount);
|
||||
|
||||
setUint(setId, _podShare);
|
||||
|
||||
_eventName = "LogDepositToPod(address,address,address,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(address(prizePoolToken), address(pod), address(this), _tokenAmount, _podShare, getId, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw from shares from Pod
|
||||
* @notice Withdraws a users share of the prize pool.
|
||||
* @dev The function should first withdraw from the 'float'; i.e. the funds that have not yet been deposited.
|
||||
* @param pod Pod address
|
||||
* @param shareAmount The number of Pod shares to burn.
|
||||
* @param maxFee Max fee amount for withdrawl if amount isn't available in float.
|
||||
* @param getId Get token amount at this ID from `InstaMemory` Contract.
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
|
||||
function withdrawFromPod (
|
||||
address pod,
|
||||
uint256 shareAmount,
|
||||
uint256 maxFee,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _shareAmount = getUint(getId, shareAmount);
|
||||
|
||||
PodInterface podContract = PodInterface(pod);
|
||||
_shareAmount = _shareAmount == uint256(-1) ? podContract.balanceOf(address(this)) : _shareAmount;
|
||||
|
||||
uint256 _tokenAmount = podContract.withdraw(_shareAmount, maxFee);
|
||||
|
||||
convertWethToEth(address(podContract.token()) == wethAddr, TokenInterface(podContract.token()), _tokenAmount);
|
||||
|
||||
setUint(setId, _tokenAmount);
|
||||
|
||||
_eventName = "LogWithdrawFromPod(address,uint256,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(address(pod), _shareAmount, _tokenAmount, maxFee, getId, setId);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2PoolTogether is PoolTogetherResolver {
|
||||
string public constant name = "PoolTogether-v1";
|
||||
}
|
|
@ -9,12 +9,12 @@ abstract contract Helpers is DSMath, Basic {
|
|||
/**
|
||||
* @dev Aave Lending Pool Provider
|
||||
*/
|
||||
AaveLendingPoolProviderInterface constant internal aaveProvider = AaveLendingPoolProviderInterface(0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5);
|
||||
AaveLendingPoolProviderInterface constant internal aaveProvider = AaveLendingPoolProviderInterface(0xd05e3E715d945B59290df0ae8eF85c1BdB684744);
|
||||
|
||||
/**
|
||||
* @dev Aave Protocol Data Provider
|
||||
*/
|
||||
AaveDataProviderInterface constant internal aaveData = AaveDataProviderInterface(0x057835Ad21a177dbdd3090bB1CAE03EaCF78Fc6d);
|
||||
AaveDataProviderInterface constant internal aaveData = AaveDataProviderInterface(0x7551b5D2763519d4e37e8B81929D336De671d46d);
|
||||
|
||||
/**
|
||||
* @dev Aave Referral Code
|
||||
|
|
10
contracts/polygon/connectors/pooltogether/events.sol
Normal file
10
contracts/polygon/connectors/pooltogether/events.sol
Normal file
|
@ -0,0 +1,10 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenFaucetInterface } from "./interface.sol";
|
||||
|
||||
contract Events {
|
||||
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 exitFee, uint256 getId, uint256 setId);
|
||||
event LogClaim(address tokenFaucet, address user, uint256 claimed, uint256 setId);
|
||||
event LogClaimAll(address tokenFaucetProxyFactory, address user, TokenFaucetInterface[] tokenFaucets);
|
||||
}
|
15
contracts/polygon/connectors/pooltogether/interface.sol
Normal file
15
contracts/polygon/connectors/pooltogether/interface.sol
Normal file
|
@ -0,0 +1,15 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
interface PrizePoolInterface {
|
||||
function token() external view returns (address);
|
||||
function depositTo( address to, uint256 amount, address controlledToken, address referrer) external;
|
||||
function withdrawInstantlyFrom( address from, uint256 amount, address controlledToken, uint256 maximumExitFee) external returns (uint256);
|
||||
}
|
||||
|
||||
interface TokenFaucetInterface {
|
||||
function claim( address user) external returns (uint256);
|
||||
}
|
||||
|
||||
interface TokenFaucetProxyFactoryInterface {
|
||||
function claimAll(address user, TokenFaucetInterface[] calldata tokenFaucets) external;
|
||||
}
|
145
contracts/polygon/connectors/pooltogether/main.sol
Normal file
145
contracts/polygon/connectors/pooltogether/main.sol
Normal file
|
@ -0,0 +1,145 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
/**
|
||||
* @title PoolTogether
|
||||
* @dev Deposit & Withdraw from PoolTogether
|
||||
*/
|
||||
|
||||
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
|
||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import { PrizePoolInterface, TokenFaucetInterface, TokenFaucetProxyFactoryInterface } from "./interface.sol";
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { Stores } from "../../common/stores.sol";
|
||||
import { Events } from "./events.sol";
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
|
||||
abstract contract PoolTogetherResolver is Events, DSMath, Basic {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/**
|
||||
* @dev Deposit into Prize Pool
|
||||
* @notice Deposit assets into the Prize Pool in exchange for tokens
|
||||
* @param prizePool PrizePool address to deposit to
|
||||
* @param amount The amount of the underlying asset the user wishes to deposit. The Prize Pool contract should have been pre-approved by the caller to transfer the underlying ERC20 tokens.
|
||||
* @param controlledToken The address of the token that they wish to mint. For our default Prize Strategy this will either be the Ticket address or the Sponsorship address. Those addresses can be looked up on the Prize Strategy.
|
||||
* @param getId Get token amount at this ID from `InstaMemory` Contract.
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
|
||||
function depositTo(
|
||||
address prizePool,
|
||||
uint256 amount,
|
||||
address controlledToken,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable returns ( string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amount = getUint(getId, amount);
|
||||
|
||||
PrizePoolInterface prizePoolContract = PrizePoolInterface(prizePool);
|
||||
address prizePoolToken = prizePoolContract.token();
|
||||
|
||||
bool isMatic = prizePoolToken == wmaticAddr;
|
||||
TokenInterface tokenContract = TokenInterface(prizePoolToken);
|
||||
|
||||
if (isMatic) {
|
||||
_amount = _amount == uint256(-1) ? address(this).balance : _amount;
|
||||
convertMaticToWmatic(isMatic, tokenContract, _amount);
|
||||
} else {
|
||||
_amount = _amount == uint256(-1) ? tokenContract.balanceOf(address(this)) : _amount;
|
||||
}
|
||||
|
||||
// Approve prizePool
|
||||
approve(tokenContract, prizePool, _amount);
|
||||
|
||||
prizePoolContract.depositTo(address(this), _amount, controlledToken, address(0));
|
||||
|
||||
setUint(setId, _amount);
|
||||
|
||||
_eventName = "LogDepositTo(address,address,uint256,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(address(prizePool), address(this), _amount, address(controlledToken), getId, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw from Prize Pool
|
||||
* @notice Withdraw assets from the Prize Pool instantly. A fairness fee may be charged for an early exit.
|
||||
* @param prizePool PrizePool address to withdraw from
|
||||
* @param amount The amount of tokens to redeem for assets.
|
||||
* @param controlledToken The address of the token to redeem (i.e. ticket or sponsorship)
|
||||
* @param maximumExitFee The maximum early exit fee the caller is willing to pay. This prevents the Prize Strategy from changing the fee on the fly. This should be pre-calculated by the calculateExitFee() fxn.
|
||||
* @param getId Get token amount at this ID from `InstaMemory` Contract.
|
||||
* @param setId Set token amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
|
||||
function withdrawInstantlyFrom (
|
||||
address prizePool,
|
||||
uint256 amount,
|
||||
address controlledToken,
|
||||
uint256 maximumExitFee,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amount = getUint(getId, amount);
|
||||
|
||||
PrizePoolInterface prizePoolContract = PrizePoolInterface(prizePool);
|
||||
address prizePoolToken = prizePoolContract.token();
|
||||
TokenInterface tokenContract = TokenInterface(prizePoolToken);
|
||||
|
||||
TokenInterface ticketToken = TokenInterface(controlledToken);
|
||||
_amount = _amount == uint256(-1) ? ticketToken.balanceOf(address(this)) : _amount;
|
||||
|
||||
uint exitFee = prizePoolContract.withdrawInstantlyFrom(address(this), _amount, controlledToken, maximumExitFee);
|
||||
|
||||
_amount = _amount - exitFee;
|
||||
|
||||
convertWmaticToMatic(prizePoolToken == wmaticAddr, tokenContract, _amount);
|
||||
|
||||
setUint(setId, _amount);
|
||||
|
||||
_eventName = "LogWithdrawInstantlyFrom(address,address,uint256,address,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(address(prizePool), address(this), _amount, address(controlledToken), maximumExitFee, exitFee, getId, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Claim token from a Token Faucet
|
||||
* @notice Claim token from a Token Faucet
|
||||
* @param tokenFaucet TokenFaucet address
|
||||
* @param setId Set claimed amount at this ID in `InstaMemory` Contract.
|
||||
*/
|
||||
function claim (
|
||||
address tokenFaucet,
|
||||
uint256 setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
TokenFaucetInterface tokenFaucetContract = TokenFaucetInterface(tokenFaucet);
|
||||
|
||||
uint256 claimed = tokenFaucetContract.claim(address(this));
|
||||
|
||||
setUint(setId, claimed);
|
||||
|
||||
_eventName = "LogClaim(address,address, uint256, uint256)";
|
||||
_eventParam = abi.encode(address(tokenFaucet), address(this), claimed, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 tokenFaucets The tokenFaucets to call claim on.
|
||||
*/
|
||||
function claimAll (
|
||||
address tokenFaucetProxyFactory,
|
||||
TokenFaucetInterface[] calldata tokenFaucets
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
TokenFaucetProxyFactoryInterface tokenFaucetProxyFactoryContract = TokenFaucetProxyFactoryInterface(tokenFaucetProxyFactory);
|
||||
|
||||
tokenFaucetProxyFactoryContract.claimAll(address(this), tokenFaucets);
|
||||
|
||||
_eventName = "LogClaimAll(address,address,TokenFaucetInterface[])";
|
||||
_eventParam = abi.encode(address(tokenFaucetProxyFactory), address(this), tokenFaucets);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2PoolTogetherPolygon is PoolTogetherResolver {
|
||||
string public constant name = "PoolTogether-v1";
|
||||
}
|
6028
package-lock.json
generated
6028
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
27
scripts/deployAvaxConnector.js
Normal file
27
scripts/deployAvaxConnector.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
const hre = require("hardhat");
|
||||
const { ethers, deployments, getUnnamedAccounts } = hre;
|
||||
const { deploy } = deployments;
|
||||
|
||||
|
||||
async function main() {
|
||||
|
||||
const deployer = (await getUnnamedAccounts())[0]
|
||||
|
||||
const connector = "ConnectV2InstaPoolV3Avalanche"
|
||||
|
||||
const connectorInstance = await deploy(connector, {
|
||||
from: deployer,
|
||||
})
|
||||
console.log(`${connector} deployed: `, connectorInstance.address);
|
||||
|
||||
await hre.run("sourcify", {
|
||||
address: connectorInstance.address,
|
||||
})
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
15
scripts/polygon/buildDSAv2.js
Normal file
15
scripts/polygon/buildDSAv2.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
const hre = require("hardhat");
|
||||
const { ethers } = hre;
|
||||
const addresses = require("./constant/addresses");
|
||||
const abis = require("../constant/abis");
|
||||
|
||||
const instaImplementations_m1 = require("../../deployements/mainnet/Implementation_m1.sol/InstaImplementationM1.json")
|
||||
|
||||
module.exports = async function (owner) {
|
||||
const instaIndex = await ethers.getContractAt(abis.core.instaIndex, addresses.core.instaIndex)
|
||||
|
||||
const tx = await instaIndex.build(owner, 2, owner);
|
||||
const receipt = await tx.wait()
|
||||
const event = receipt.events.find(a => a.event === "LogAccountCreated")
|
||||
return await ethers.getContractAt(instaImplementations_m1.abi, event.args.account)
|
||||
};
|
10
scripts/polygon/constant/addresses.js
Normal file
10
scripts/polygon/constant/addresses.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
module.exports = {
|
||||
connectors: {
|
||||
basic: "0x1cAF5EC802ca602E98139AD96A8f2B7BC524264E",
|
||||
auth: "0xf6474aD0dA75A0dE15D2c915e601D9f754B9e6fe",
|
||||
},
|
||||
core: {
|
||||
connectorsV2: "0x2A00684bFAb9717C21271E0751BCcb7d2D763c88",
|
||||
instaIndex: "0xA9B99766E6C676Cf1975c0D3166F96C0848fF5ad",
|
||||
},
|
||||
};
|
7
scripts/polygon/constant/constant.js
Normal file
7
scripts/polygon/constant/constant.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
module.exports = {
|
||||
address_zero: "0x0000000000000000000000000000000000000000",
|
||||
eth_addr: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
|
||||
matic_addr: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
|
||||
max_value: "115792089237316195423570985008687907853269984665640564039457584007913129639935"
|
||||
};
|
||||
|
30
scripts/polygon/constant/tokens.js
Normal file
30
scripts/polygon/constant/tokens.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
module.exports = {
|
||||
"matic": {
|
||||
"type": "token",
|
||||
"symbol": "MATIC",
|
||||
"name": "Matic",
|
||||
"address": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
|
||||
"decimals": 18
|
||||
},
|
||||
"eth": {
|
||||
"type": "token",
|
||||
"symbol": "ETH",
|
||||
"name": "Ethereum",
|
||||
"address": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
|
||||
"decimals": 18
|
||||
},
|
||||
"dai": {
|
||||
"type": "token",
|
||||
"symbol": "DAI",
|
||||
"name": "DAI Stable",
|
||||
"address": "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
|
||||
"decimals": 18
|
||||
},
|
||||
"usdc": {
|
||||
"type": "token",
|
||||
"symbol": "USDC",
|
||||
"name": "USD Coin",
|
||||
"address": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
|
||||
"decimals": 6
|
||||
}
|
||||
}
|
19
scripts/polygon/deployAndEnableConnector.js
Normal file
19
scripts/polygon/deployAndEnableConnector.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
const abis = require("../constant/abis");
|
||||
const addresses = require("./constant/addresses");
|
||||
|
||||
const hre = require("hardhat");
|
||||
const { ethers, waffle } = hre;
|
||||
const { deployContract } = waffle;
|
||||
const fs = require("fs")
|
||||
|
||||
|
||||
module.exports = async function ({connectorName, contractArtifact, signer, connectors}) {
|
||||
const connectorInstanace = await deployContract(signer, contractArtifact, []);
|
||||
|
||||
await connectors.connect(signer).addConnectors([connectorName], [connectorInstanace.address])
|
||||
|
||||
addresses.connectors[connectorName] = connectorInstanace.address
|
||||
abis.connectors[connectorName] = contractArtifact.abi;
|
||||
|
||||
return connectorInstanace;
|
||||
};
|
18
scripts/polygon/encodeSpells.js
Normal file
18
scripts/polygon/encodeSpells.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
const abis = require("../constant/abis");
|
||||
const addresses = require("./constant/addresses");
|
||||
const { web3 } = hre;
|
||||
|
||||
module.exports = function (spells) {
|
||||
const targets = spells.map(a => a.connector)
|
||||
const calldatas = spells.map(a => {
|
||||
const functionName = a.method;
|
||||
// console.log(functionName)
|
||||
const abi = abis.connectors[a.connector].find(b => {
|
||||
return b.name === functionName
|
||||
});
|
||||
// console.log(functionName)
|
||||
if (!abi) throw new Error("Couldn't find function")
|
||||
return web3.eth.abi.encodeFunctionCall(abi, a.args)
|
||||
})
|
||||
return [targets, calldatas]
|
||||
};
|
25
scripts/polygon/getMasterSigner.js
Normal file
25
scripts/polygon/getMasterSigner.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
const hre = require("hardhat");
|
||||
const { ethers } = hre;
|
||||
const addresses = require("./constant/addresses");
|
||||
const abis = require("../constant/abis");
|
||||
|
||||
module.exports = async function() {
|
||||
const [_, __, ___, wallet3] = await ethers.getSigners();
|
||||
const instaIndex = new ethers.Contract(
|
||||
addresses.core.instaIndex,
|
||||
abis.core.instaIndex,
|
||||
wallet3
|
||||
);
|
||||
|
||||
const masterAddress = await instaIndex.master(); // TODO: make it constant?
|
||||
await hre.network.provider.request({
|
||||
method: "hardhat_impersonateAccount",
|
||||
params: [masterAddress],
|
||||
});
|
||||
await wallet3.sendTransaction({
|
||||
to: masterAddress,
|
||||
value: ethers.utils.parseEther("10"),
|
||||
});
|
||||
|
||||
return await ethers.getSigner(masterAddress);
|
||||
};
|
420
test/pooltogether-polygon/pooltogether.test.js
Normal file
420
test/pooltogether-polygon/pooltogether.test.js
Normal file
|
@ -0,0 +1,420 @@
|
|||
const { expect } = require("chai");
|
||||
const hre = require("hardhat");
|
||||
const { web3, deployments, waffle, ethers } = hre;
|
||||
const { provider, deployContract } = waffle
|
||||
|
||||
const ALCHEMY_ID = process.env.ALCHEMY_ID;
|
||||
|
||||
const deployAndEnableConnector = require("../../scripts/polygon/deployAndEnableConnector.js")
|
||||
const buildDSAv2 = require("../../scripts/polygon/buildDSAv2")
|
||||
const encodeSpells = require("../../scripts/polygon/encodeSpells.js")
|
||||
const getMasterSigner = require("../../scripts/polygon/getMasterSigner")
|
||||
|
||||
const addresses = require("../../scripts/polygon/constant/addresses");
|
||||
const abis = require("../../scripts/constant/abis");
|
||||
const constants = require("../../scripts/polygon/constant/constant");
|
||||
const tokens = require("../../scripts/polygon/constant/tokens");
|
||||
|
||||
const connectV2AaveV2Artifacts = require("../../artifacts/contracts/polygon/connectors/aave/v2/main.sol/ConnectV2AaveV2Polygon.json")
|
||||
const connectV2PoolTogetherArtifacts = require("../../artifacts/contracts/polygon/connectors/pooltogether/main.sol/ConnectV2PoolTogetherPolygon.json")
|
||||
|
||||
const DAI_TOKEN_ADDR = tokens.dai.address // DAI Token
|
||||
// PoolTogether Address: https://docs.pooltogether.com/resources/networks/matic
|
||||
const USDC_PRIZE_POOL_ADDR = "0xEE06AbE9e2Af61cabcb13170e01266Af2DEFa946" // USDC Prize Pool
|
||||
const PT_USDC_TICKET_ADDR = "0x473E484c722EF9ec6f63B509b07Bb9cfB258820b" // PT USDC Ticket
|
||||
const PT_USDC_SPONGSOR_TICKET_ADDR = "0x19c0e557ee5a9b456f613ba3d025a4dc45b52c35" // PT USDC Sponsor Ticket
|
||||
const USDC_POOL_FAUCET_ADDR = "0x6cbc003fE015D753180f072d904bA841b2415498" // USDC POOL Faucet
|
||||
const POOL_TOKEN_ADDRESS = "0x25788a1a171ec66Da6502f9975a15B609fF54CF6" // POOL Tocken
|
||||
const TOKEN_FAUCET_PROXY_FACTORY_ADDR = "0xeaa636304a7C8853324B6b603dCdE55F92dfbab1" // TokenFaucetProxyFactory for claimAll
|
||||
|
||||
// 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 = [
|
||||
"function calculateEarlyExitFee( address from, address controlledToken, uint256 amount) external returns ( uint256 exitFee, uint256 burnedCredit)",
|
||||
"function creditPlanOf( address controlledToken) external view returns ( uint128 creditLimitMantissa, uint128 creditRateMantissa)"
|
||||
]
|
||||
|
||||
const connectorsABI = [
|
||||
"function isConnectors(string[] calldata connectorNames) external view returns (bool, address[] memory)"
|
||||
]
|
||||
|
||||
describe("PoolTogether", function () {
|
||||
const connectorName = "AAVEV2-TEST-A"
|
||||
const ptConnectorName = "POOLTOGETHER-TEST-A"
|
||||
|
||||
let dsaWallet0
|
||||
let masterSigner;
|
||||
let instaConnectorsV2;
|
||||
let connector;
|
||||
let ptConnector;
|
||||
|
||||
const wallets = provider.getWallets()
|
||||
const [wallet0, wallet1, wallet2, wallet3] = wallets
|
||||
before(async () => {
|
||||
await hre.network.provider.request({
|
||||
method: "hardhat_reset",
|
||||
params: [
|
||||
{
|
||||
forking: {
|
||||
jsonRpcUrl: `https://polygon-mainnet.g.alchemy.com/v2/${ALCHEMY_ID}`,
|
||||
blockNumber: 18717337,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
masterSigner = await getMasterSigner()
|
||||
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
|
||||
|
||||
// Deploy and enable Compound Connector
|
||||
connector = await deployAndEnableConnector({
|
||||
connectorName,
|
||||
contractArtifact: connectV2AaveV2Artifacts,
|
||||
signer: masterSigner,
|
||||
connectors: instaConnectorsV2
|
||||
})
|
||||
|
||||
// Deploy and enable Pool Together Connector
|
||||
ptConnector = await deployAndEnableConnector({
|
||||
connectorName: ptConnectorName,
|
||||
contractArtifact: connectV2PoolTogetherArtifacts,
|
||||
signer: masterSigner,
|
||||
connectors: instaConnectorsV2
|
||||
})
|
||||
})
|
||||
|
||||
it("Should have contracts deployed.", async function () {
|
||||
expect(!!instaConnectorsV2.address).to.be.true;
|
||||
expect(!!connector.address).to.be.true;
|
||||
expect(!!ptConnector.address).to.be.true;
|
||||
expect(!!masterSigner.address).to.be.true;
|
||||
});
|
||||
|
||||
describe("DSA wallet setup", function () {
|
||||
it("Should build DSA v2", async function () {
|
||||
dsaWallet0 = await buildDSAv2(wallet0.address)
|
||||
expect(!!dsaWallet0.address).to.be.true;
|
||||
});
|
||||
|
||||
it("Deposit 1000 MATIC into DSA wallet", async function () {
|
||||
await wallet0.sendTransaction({
|
||||
to: dsaWallet0.address,
|
||||
value: ethers.utils.parseEther("1000")
|
||||
});
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("1000"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("Main - USDC Prize Pool Test", function () {
|
||||
|
||||
it("Should deposit 100 MATIC in AAVE V2", async function () {
|
||||
const amount = ethers.utils.parseEther("100") // 100 MATIC
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "deposit",
|
||||
args: [tokens.matic.address, amount, 0, 0]
|
||||
}
|
||||
]
|
||||
|
||||
const tx = await dsaWallet0.cast(...encodeSpells(spells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("900"));
|
||||
});
|
||||
|
||||
it("Should borrow 10 USDC from AAVE V2 and deposit USDC into USDC Prize Pool", async function () {
|
||||
const amount = ethers.utils.parseUnits("10", 6) // 10 USDC
|
||||
const setId = "83478237"
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "borrow",
|
||||
args: [tokens.usdc.address, amount, 2, 0, setId]
|
||||
},
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "depositTo",
|
||||
args: [USDC_PRIZE_POOL_ADDR, amount, PT_USDC_SPONGSOR_TICKET_ADDR, setId, 0]
|
||||
}
|
||||
]
|
||||
// Before Spell
|
||||
let usdcToken = await ethers.getContractAt(abis.basic.erc20, tokens.usdc.address)
|
||||
let usdcBalance = await usdcToken.balanceOf(dsaWallet0.address);
|
||||
expect(usdcBalance, `USDC balance is 0`).to.be.eq(ethers.utils.parseUnits("0", 6));
|
||||
|
||||
let cToken = await ethers.getContractAt(abis.basic.erc20, PT_USDC_SPONGSOR_TICKET_ADDR)
|
||||
const balance = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balance,`PoolTogether USDC Ticket balance is 0`).to.be.eq(0);
|
||||
|
||||
// Run spell transaction
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
|
||||
// After spell
|
||||
usdcBalance = await usdcToken.balanceOf(dsaWallet0.address);
|
||||
expect(usdcBalance, `Expect USDC balance to still equal 0 since it was deposited into Prize Pool`).to.be.eq(0);
|
||||
|
||||
const balanceAfter = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balanceAfter, `PoolTogether USDC Ticket balance equals 10`).to.be.eq(ethers.utils.parseUnits("10", 6));
|
||||
|
||||
// ETH used for transaction
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("900"));
|
||||
});
|
||||
|
||||
it("Should wait 11 days, withdraw all PrizePool, get back 10 USDC, and claim POOL", async function () {
|
||||
const amount = ethers.utils.parseUnits("10", 6) // 10 USDC
|
||||
|
||||
let prizePoolContract = new ethers.Contract(USDC_PRIZE_POOL_ADDR, prizePoolABI, ethers.provider);
|
||||
// const { creditLimitMantissa, creditRateMantissa } = await prizePoolContract.creditPlanOf(PT_USDC_TICKET_ADDR);
|
||||
// console.log("CreditLimitMantiss: ", creditLimitMantissa.toString());
|
||||
// console.log("CreditRateMantiss: ", creditRateMantissa.toString());
|
||||
let earlyExitFee = await prizePoolContract.callStatic["calculateEarlyExitFee"](dsaWallet0.address, PT_USDC_SPONGSOR_TICKET_ADDR, amount);
|
||||
expect(earlyExitFee.exitFee, "Exit Fee equal to 0 USDC because 0% fee for sponsorship ticket").to.be.eq(ethers.utils.parseUnits("0", 6));
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "claim",
|
||||
args: [USDC_POOL_FAUCET_ADDR, 0]
|
||||
},
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "withdrawInstantlyFrom",
|
||||
args: [USDC_PRIZE_POOL_ADDR, amount, PT_USDC_SPONGSOR_TICKET_ADDR, earlyExitFee.exitFee, 0, 0]
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
// Before spell
|
||||
let usdcToken = await ethers.getContractAt(abis.basic.erc20, tokens.usdc.address)
|
||||
let usdcBalance = await usdcToken.balanceOf(dsaWallet0.address);
|
||||
expect(usdcBalance, `USDC balance equals 0`).to.be.eq(ethers.utils.parseEther("0"));
|
||||
|
||||
let cToken = await ethers.getContractAt(abis.basic.erc20, PT_USDC_SPONGSOR_TICKET_ADDR)
|
||||
const balance = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balance, `PoolTogether USDC Ticket is 10`).to.be.eq(ethers.utils.parseUnits("10", 6));
|
||||
|
||||
let poolToken = await ethers.getContractAt(abis.basic.erc20, POOL_TOKEN_ADDRESS)
|
||||
const poolBalance = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalance, `POOL Token equals 0`).to.be.eq(ethers.utils.parseEther("0"));
|
||||
|
||||
// Increase time by 11 days so we get back all USDC without early withdrawal fee
|
||||
await ethers.provider.send("evm_increaseTime", [15*24*60*60]);
|
||||
await ethers.provider.send("evm_mine");
|
||||
|
||||
earlyExitFee = await prizePoolContract.callStatic["calculateEarlyExitFee"](dsaWallet0.address, PT_USDC_SPONGSOR_TICKET_ADDR, amount);
|
||||
expect(earlyExitFee.exitFee, "Exit Fee equal to 0 DAI because past 14 days").to.be.eq(0);
|
||||
|
||||
// Run spell transaction
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
|
||||
// After spell
|
||||
usdcBalance = await usdcToken.balanceOf(dsaWallet0.address);
|
||||
console.log("USDC BALANCE: ", usdcBalance.toString());
|
||||
console.log("USDC BALANCE: ", ethers.utils.parseUnits("10", 6).toString());
|
||||
expect(usdcBalance,
|
||||
`USDC balance to be equal to 10, because of no early withdrawal fee`
|
||||
).to.be.eq(ethers.utils.parseUnits("10", 6));
|
||||
|
||||
const balanceAfter = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balanceAfter, `PoolTogether USDC Ticket to equal 0`).to.be.eq(0);
|
||||
|
||||
const poolBalanceAfter = await poolToken.balanceOf(dsaWallet0.address)
|
||||
console.log("POOL BALANCE AFTER:" ,poolBalanceAfter.toString());
|
||||
expect(poolBalanceAfter, `POOL Token Balance to be greater than 0`).to.be.gt(ethers.utils.parseEther("0"));
|
||||
});
|
||||
|
||||
it("Should deposit and withdraw all PrizePool, get back less than 10 USDC", async function() {
|
||||
const amount = ethers.utils.parseUnits("10", 6) // 10 USDC
|
||||
const exitFee = ethers.utils.parseUnits(".1", 6) // 1 USDC is 1% of 100 USDC
|
||||
const spells = [
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "depositTo",
|
||||
args: [USDC_PRIZE_POOL_ADDR, amount, PT_USDC_TICKET_ADDR, 0, 0]
|
||||
},
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "withdrawInstantlyFrom",
|
||||
args: [USDC_PRIZE_POOL_ADDR, amount, PT_USDC_TICKET_ADDR, exitFee, 0, 0]
|
||||
}
|
||||
]
|
||||
|
||||
// Before spell
|
||||
let usdcToken = await ethers.getContractAt(abis.basic.erc20, tokens.usdc.address)
|
||||
let usdcBalance = await usdcToken.balanceOf(dsaWallet0.address);
|
||||
expect(usdcBalance, `USDC Balance equals 100`).to.be.eq(ethers.utils.parseUnits("10", 6));
|
||||
|
||||
let cToken = await ethers.getContractAt(abis.basic.erc20, PT_USDC_TICKET_ADDR)
|
||||
const balance = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balance, `PoolTogether USDC Ticket equals 0`).to.be.eq(0);
|
||||
|
||||
let poolToken = await ethers.getContractAt(abis.basic.erc20, POOL_TOKEN_ADDRESS)
|
||||
const poolBalance = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalance, `PoolTogether Token greater than 0`).to.be.gt(0);
|
||||
|
||||
// Run spell transaction
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
|
||||
// After spell
|
||||
usdcBalance = await usdcToken.balanceOf(dsaWallet0.address);
|
||||
expect(usdcBalance,
|
||||
`USDC balance to be less than 10, because of early withdrawal fee`
|
||||
).to.be.lt(ethers.utils.parseUnits("10",6));
|
||||
|
||||
console.log("USDC BALANCE AFTER:", usdcBalance.toString());
|
||||
|
||||
const balanceAfter = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balanceAfter, `PoolTogether USDC Ticket to equal 0`).to.be.eq(0);
|
||||
|
||||
const poolBalanceAfter = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalanceAfter, `POOL Token Balance to greater than 0`).to.be.gt(ethers.utils.parseEther("0"));
|
||||
|
||||
});
|
||||
|
||||
it("Should deposit, wait 11 days, and withdraw all PrizePool, get 10 USDC, and claim all POOL using claimAll", async function() {
|
||||
const amount = ethers.utils.parseUnits("9.9", 6) // 9 USDC
|
||||
const depositSpells = [
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "depositTo",
|
||||
args: [USDC_PRIZE_POOL_ADDR, amount, PT_USDC_SPONGSOR_TICKET_ADDR, 0, 0]
|
||||
}
|
||||
]
|
||||
|
||||
// Before spell
|
||||
let usdcToken = await ethers.getContractAt(abis.basic.erc20, tokens.usdc.address)
|
||||
let usdcBalance = await usdcToken.balanceOf(dsaWallet0.address);
|
||||
expect(usdcBalance, `USDC balance less than 10`).to.be.lt(ethers.utils.parseUnits("10", 6));
|
||||
|
||||
let cToken = await ethers.getContractAt(abis.basic.erc20, PT_USDC_SPONGSOR_TICKET_ADDR)
|
||||
const balance = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balance, `PoolTogether USDC Ticket equal 0`).to.be.eq(0);
|
||||
|
||||
let poolToken = await ethers.getContractAt(abis.basic.erc20, POOL_TOKEN_ADDRESS)
|
||||
const poolBalance = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalance, `POOL Token is greater than 0`).to.be.gt(ethers.utils.parseEther("0"));
|
||||
|
||||
// Run spell transaction
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(depositSpells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
|
||||
const prizePoolContract = new ethers.Contract(USDC_PRIZE_POOL_ADDR, prizePoolABI, ethers.provider);
|
||||
let earlyExitFee = await prizePoolContract.callStatic["calculateEarlyExitFee"](dsaWallet0.address, PT_USDC_SPONGSOR_TICKET_ADDR, amount);
|
||||
expect(earlyExitFee.exitFee, "Exit Fee equal to 0 USDC because fee 0%").to.be.eq(0);
|
||||
|
||||
// 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]);
|
||||
await ethers.provider.send("evm_mine");
|
||||
|
||||
const withdrawSpells = [
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "withdrawInstantlyFrom",
|
||||
args: [USDC_PRIZE_POOL_ADDR, amount, PT_USDC_SPONGSOR_TICKET_ADDR, earlyExitFee.exitFee, 0, 0]
|
||||
},
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "claimAll",
|
||||
args: [TOKEN_FAUCET_PROXY_FACTORY_ADDR, [USDC_POOL_FAUCET_ADDR]]
|
||||
}
|
||||
]
|
||||
|
||||
// Run spell transaction
|
||||
const tx2 = await dsaWallet0.connect(wallet0).cast(...encodeSpells(withdrawSpells), wallet1.address)
|
||||
const receipt2 = await tx2.wait()
|
||||
|
||||
// After spell
|
||||
usdcBalance = await usdcToken.balanceOf(dsaWallet0.address);
|
||||
expect(usdcBalance, `USDC balance equals 9.9`).to.be.eq(ethers.utils.parseUnits("9.9", 6));
|
||||
|
||||
const balanceAfter = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balanceAfter, `PoolTogether USDC Ticket equal 0`).to.be.eq(0);
|
||||
|
||||
// Expect
|
||||
const poolBalanceAfter = await poolToken.balanceOf(dsaWallet0.address)
|
||||
console.log("POOL BALANCE AFTER:" ,poolBalanceAfter.toString());
|
||||
expect(poolBalanceAfter, `Pool Token to be greater than before`).to.be.gt(poolBalance);
|
||||
});
|
||||
// })
|
||||
|
||||
// NO WMATIC POOLS: https://reference-app.pooltogether.com/pools/polygon
|
||||
// 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);
|
||||
// });
|
||||
});
|
||||
})
|
811
test/pooltogether/pooltogether.test.js
Normal file
811
test/pooltogether/pooltogether.test.js
Normal file
|
@ -0,0 +1,811 @@
|
|||
const { expect } = require("chai");
|
||||
const hre = require("hardhat");
|
||||
const { web3, deployments, waffle, ethers } = hre;
|
||||
const { provider, deployContract } = waffle
|
||||
|
||||
const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js")
|
||||
const buildDSAv2 = require("../../scripts/buildDSAv2")
|
||||
const encodeSpells = require("../../scripts/encodeSpells.js")
|
||||
const getMasterSigner = require("../../scripts/getMasterSigner")
|
||||
|
||||
const addresses = require("../../scripts/constant/addresses");
|
||||
const abis = require("../../scripts/constant/abis");
|
||||
const constants = require("../../scripts/constant/constant");
|
||||
const tokens = require("../../scripts/constant/tokens");
|
||||
|
||||
const connectV2CompoundArtifacts = require("../../artifacts/contracts/mainnet/connectors/compound/main.sol/ConnectV2Compound.json")
|
||||
const connectV2PoolTogetherArtifacts = require("../../artifacts/contracts/mainnet/connectors/pooltogether/main.sol/ConnectV2PoolTogether.json")
|
||||
const connectV2UniswapArtifacts = require("../../artifacts/contracts/mainnet/connectors/uniswap/main.sol/ConnectV2UniswapV2.json")
|
||||
|
||||
const DAI_TOKEN_ADDR = tokens.dai.address // DAI Token
|
||||
|
||||
// PoolTogether Address: https://docs.pooltogether.com/resources/networks/ethereum
|
||||
const DAI_PRIZE_POOL_ADDR = "0xEBfb47A7ad0FD6e57323C8A42B2E5A6a4F68fc1a" // DAI Prize Pool
|
||||
const PT_DAI_TICKET_ADDR = "0x334cBb5858417Aee161B53Ee0D5349cCF54514CF" // PT DAI Ticket
|
||||
const DAI_POOL_FAUCET_ADDR = "0xF362ce295F2A4eaE4348fFC8cDBCe8d729ccb8Eb" // DAI POOL Faucet
|
||||
const POOL_TOKEN_ADDRESS = "0x0cEC1A9154Ff802e7934Fc916Ed7Ca50bDE6844e" // POOL Tocken
|
||||
const TOKEN_FAUCET_PROXY_FACTORY_ADDR = "0xE4E9cDB3E139D7E8a41172C20b6Ed17b6750f117" // TokenFaucetProxyFactory for claimAll
|
||||
const DAI_POD_ADDR = "0x2f994e2E4F3395649eeE8A89092e63Ca526dA829" // DAI Pod
|
||||
const UNISWAP_POOLETHLP_PRIZE_POOL_ADDR = "0x3AF7072D29Adde20FC7e173a7CB9e45307d2FB0A" // Uniswap Pool/ETH LP PrizePool
|
||||
const UNISWAP_POOLETHLP_FAUCET_ADDR = "0x9A29401EF1856b669f55Ae5b24505b3B6fAEb370" // Uniswap Pool/ETH LP Faucet
|
||||
const UNISWAP_POOLETHLP_TOKEN_ADDR = "0x85cb0bab616fe88a89a35080516a8928f38b518b" // Uniswap Pool/ETH Token
|
||||
const PT_UNISWAP_POOLETHLP_TICKET_ADDR = "0xeb8928ee92efb06c44d072a24c2bcb993b61e543" // Pool Together Uniswap Pool/ETH LP Ticket
|
||||
const POOL_PRIZE_POOL_ADDR = "0x396b4489da692788e327e2e4b2b0459a5ef26791" // POOL Prize Pool
|
||||
const PT_POOL_TICKET_ADDR = "0x27d22a7648e955e510a40bdb058333e9190d12d4" // Pool Together POOL Ticket
|
||||
const WETH_ADDR = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" // WETH
|
||||
const DAI_POD_TOKEN_DROP = "0xc5209623E3dFdf9C0cCbe497c8012883C4147731"
|
||||
|
||||
// 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 = [
|
||||
"function calculateEarlyExitFee( address from, address controlledToken, uint256 amount) external returns ( uint256 exitFee, uint256 burnedCredit)"
|
||||
]
|
||||
|
||||
const podABI = [
|
||||
"function getEarlyExitFee(uint256 amount) external returns (uint256)",
|
||||
"function balanceOfUnderlying(address user) external view returns (uint256 amount)",
|
||||
"function drop() public returns (uint256)",
|
||||
"function balanceOf(address account) external view returns (uint256)"
|
||||
]
|
||||
|
||||
const POD_FACTORY_ADDRESS = "0x4e3a9f9fbafb2ec49727cffa2a411f7a0c1c4ce1"
|
||||
const podFactoryABI = [
|
||||
"function create( address _prizePool, address _ticket, address _faucet, address _manager, uint8 _decimals) external returns (address pod)"
|
||||
]
|
||||
|
||||
const tokenDropABI = [
|
||||
"function claim(address user) external returns (uint256)",
|
||||
]
|
||||
|
||||
describe("PoolTogether", function () {
|
||||
const connectorName = "COMPOUND-TEST-A"
|
||||
const uniswapConnectorName = "UNISWAP-TEST-A"
|
||||
const ptConnectorName = "POOLTOGETHER-TEST-A"
|
||||
|
||||
let dsaWallet0
|
||||
let masterSigner;
|
||||
let instaConnectorsV2;
|
||||
let connector;
|
||||
let ptConnector;
|
||||
let uniswapConnector;
|
||||
|
||||
const wallets = provider.getWallets()
|
||||
const [wallet0, wallet1, wallet2, wallet3] = wallets
|
||||
before(async () => {
|
||||
masterSigner = await getMasterSigner(wallet3)
|
||||
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
|
||||
|
||||
// Deploy and enable Compound Connector
|
||||
connector = await deployAndEnableConnector({
|
||||
connectorName,
|
||||
contractArtifact: connectV2CompoundArtifacts,
|
||||
signer: masterSigner,
|
||||
connectors: instaConnectorsV2
|
||||
})
|
||||
|
||||
// Deploy and enable Pool Together Connector
|
||||
ptConnector = await deployAndEnableConnector({
|
||||
connectorName: ptConnectorName,
|
||||
contractArtifact: connectV2PoolTogetherArtifacts,
|
||||
signer: masterSigner,
|
||||
connectors: instaConnectorsV2
|
||||
})
|
||||
|
||||
// Deploy and enable Uniswap Connector
|
||||
uniswapConnector = await deployAndEnableConnector({
|
||||
connectorName: uniswapConnectorName,
|
||||
contractArtifact: connectV2UniswapArtifacts,
|
||||
signer: masterSigner,
|
||||
connectors: instaConnectorsV2
|
||||
})
|
||||
})
|
||||
|
||||
it("Should have contracts deployed.", async function () {
|
||||
expect(!!instaConnectorsV2.address).to.be.true;
|
||||
expect(!!connector.address).to.be.true;
|
||||
expect(!!ptConnector.address).to.be.true;
|
||||
expect(!!uniswapConnector.address).to.be.true;
|
||||
expect(!!masterSigner.address).to.be.true;
|
||||
});
|
||||
|
||||
describe("DSA wallet setup", function () {
|
||||
it("Should build DSA v2", async function () {
|
||||
dsaWallet0 = await buildDSAv2(wallet0.address)
|
||||
expect(!!dsaWallet0.address).to.be.true;
|
||||
});
|
||||
|
||||
it("Deposit 10 ETH into DSA wallet", async function () {
|
||||
await wallet0.sendTransaction({
|
||||
to: dsaWallet0.address,
|
||||
value: ethers.utils.parseEther("10")
|
||||
});
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("Main - DAI Prize Pool Test", function () {
|
||||
|
||||
it("Should deposit 1 ETH in Compound", async function () {
|
||||
const amount = ethers.utils.parseEther("1") // 1 ETH
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "deposit",
|
||||
args: ["ETH-A", amount, 0, 0]
|
||||
}
|
||||
]
|
||||
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("9"));
|
||||
});
|
||||
|
||||
it("Should borrow 100 DAI from Compound and deposit DAI into DAI Prize Pool", async function () {
|
||||
const amount = ethers.utils.parseEther("100") // 100 DAI
|
||||
const setId = "83478237"
|
||||
const spells = [
|
||||
{
|
||||
connector: connectorName,
|
||||
method: "borrow",
|
||||
args: ["DAI-A", amount, 0, setId]
|
||||
},
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "depositTo",
|
||||
args: [DAI_PRIZE_POOL_ADDR, amount, PT_DAI_TICKET_ADDR, setId, 0]
|
||||
}
|
||||
]
|
||||
// Before Spell
|
||||
let daiToken = await ethers.getContractAt(abis.basic.erc20, DAI_TOKEN_ADDR)
|
||||
let daiBalance = await daiToken.balanceOf(dsaWallet0.address);
|
||||
expect(daiBalance, `DAI balance is 0`).to.be.eq(ethers.utils.parseEther("0"));
|
||||
|
||||
let cToken = await ethers.getContractAt(abis.basic.erc20, PT_DAI_TICKET_ADDR)
|
||||
const balance = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balance,`PoolTogether DAI Ticket balance is 0`).to.be.eq(0);
|
||||
|
||||
// Run spell transaction
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
|
||||
// After spell
|
||||
daiBalance = await daiToken.balanceOf(dsaWallet0.address);
|
||||
expect(daiBalance, `Expect DAI balance to still equal 0 since it was deposited into Prize Pool`).to.be.eq(0);
|
||||
|
||||
const balanceAfter = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balanceAfter, `PoolTogether DAI Ticket balance equals 100`).to.be.eq(ethers.utils.parseEther("100"));
|
||||
|
||||
// ETH used for transaction
|
||||
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("9"));
|
||||
});
|
||||
|
||||
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
|
||||
|
||||
let prizePoolContract = new ethers.Contract(DAI_PRIZE_POOL_ADDR, prizePoolABI, ethers.provider);
|
||||
let earlyExitFee = await prizePoolContract.callStatic["calculateEarlyExitFee"](dsaWallet0.address, PT_DAI_TICKET_ADDR, amount);
|
||||
expect(earlyExitFee.exitFee, "Exit Fee equal to 1 DAI because starts at 10%").to.be.eq(ethers.utils.parseEther("1"));
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "withdrawInstantlyFrom",
|
||||
args: [DAI_PRIZE_POOL_ADDR, amount, PT_DAI_TICKET_ADDR, earlyExitFee.exitFee, 0, 0]
|
||||
},
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "claim",
|
||||
args: [DAI_POOL_FAUCET_ADDR, 0]
|
||||
}
|
||||
]
|
||||
|
||||
// Before spell
|
||||
let daiToken = await ethers.getContractAt(abis.basic.erc20, DAI_TOKEN_ADDR)
|
||||
let daiBalance = await daiToken.balanceOf(dsaWallet0.address);
|
||||
expect(daiBalance, `DAI balance equals 0`).to.be.eq(ethers.utils.parseEther("0"));
|
||||
|
||||
let cToken = await ethers.getContractAt(abis.basic.erc20, PT_DAI_TICKET_ADDR)
|
||||
const balance = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balance, `PoolTogether Dai Ticket is 100`).to.be.eq(ethers.utils.parseEther("100"));
|
||||
|
||||
let poolToken = await ethers.getContractAt(abis.basic.erc20, POOL_TOKEN_ADDRESS)
|
||||
const poolBalance = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalance, `POOL Token equals 0`).to.be.eq(ethers.utils.parseEther("0"));
|
||||
|
||||
// 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]);
|
||||
await ethers.provider.send("evm_mine");
|
||||
|
||||
earlyExitFee = await prizePoolContract.callStatic["calculateEarlyExitFee"](dsaWallet0.address, PT_DAI_TICKET_ADDR, amount);
|
||||
expect(earlyExitFee.exitFee, "Exit Fee equal to 0 DAI because past 10 days").to.be.eq(0);
|
||||
|
||||
// Run spell transaction
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
|
||||
// After spell
|
||||
daiBalance = await daiToken.balanceOf(dsaWallet0.address);
|
||||
expect(daiBalance,
|
||||
`DAI balance to be equal to 100, because of no early withdrawal fee`
|
||||
).to.be.eq(ethers.utils.parseEther("100"));
|
||||
|
||||
const balanceAfter = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balanceAfter, `PoolTogether Dai Ticket to equal 0`).to.be.eq(0);
|
||||
|
||||
const poolBalanceAfter = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalanceAfter, `POOL Token Balance to be greater than 0`).to.be.gt(ethers.utils.parseEther("0"));
|
||||
});
|
||||
|
||||
it("Should deposit and withdraw all PrizePool, get back less than 100 DAI", async function() {
|
||||
const amount = ethers.utils.parseEther("100") // 100 DAI
|
||||
const exitFee = ethers.utils.parseEther("1") // 1 DAI is 10% of 100 DAI
|
||||
const spells = [
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "depositTo",
|
||||
args: [DAI_PRIZE_POOL_ADDR, amount, PT_DAI_TICKET_ADDR, 0, 0]
|
||||
},
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "withdrawInstantlyFrom",
|
||||
args: [DAI_PRIZE_POOL_ADDR, amount, PT_DAI_TICKET_ADDR, exitFee, 0, 0]
|
||||
}
|
||||
]
|
||||
|
||||
// Before spell
|
||||
let daiToken = await ethers.getContractAt(abis.basic.erc20, DAI_TOKEN_ADDR)
|
||||
let daiBalance = await daiToken.balanceOf(dsaWallet0.address);
|
||||
expect(daiBalance, `DAI Balance equals 0`).to.be.eq(ethers.utils.parseEther("100"));
|
||||
|
||||
let cToken = await ethers.getContractAt(abis.basic.erc20, PT_DAI_TICKET_ADDR)
|
||||
const balance = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balance, `PoolTogether DAI Ticket equals 0`).to.be.eq(0);
|
||||
|
||||
let poolToken = await ethers.getContractAt(abis.basic.erc20, POOL_TOKEN_ADDRESS)
|
||||
const poolBalance = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalance, `PoolTogether Token greater than 0`).to.be.gt(0);
|
||||
|
||||
// Run spell transaction
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
|
||||
// After spell
|
||||
daiBalance = await daiToken.balanceOf(dsaWallet0.address);
|
||||
expect(daiBalance,
|
||||
`DAI balance to be less than 100, because of early withdrawal fee`
|
||||
).to.be.lt(ethers.utils.parseEther("100"));
|
||||
|
||||
const balanceAfter = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balanceAfter, `PoolTogether Dai Ticket to equal 0`).to.be.eq(0);
|
||||
|
||||
const poolBalanceAfter = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalanceAfter, `POOL Token Balance to greater than 0`).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: [DAI_PRIZE_POOL_ADDR, amount, PT_DAI_TICKET_ADDR, 0, 0]
|
||||
}
|
||||
]
|
||||
|
||||
// Before spell
|
||||
let daiToken = await ethers.getContractAt(abis.basic.erc20, DAI_TOKEN_ADDR)
|
||||
let daiBalance = await daiToken.balanceOf(dsaWallet0.address);
|
||||
expect(daiBalance, `DAI balance less than 100`).to.be.lt(ethers.utils.parseEther("100"));
|
||||
|
||||
let cToken = await ethers.getContractAt(abis.basic.erc20, PT_DAI_TICKET_ADDR)
|
||||
const balance = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balance, `PoolTogether DAI Ticket equal 0`).to.be.eq(0);
|
||||
|
||||
let poolToken = await ethers.getContractAt(abis.basic.erc20, POOL_TOKEN_ADDRESS)
|
||||
const poolBalance = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalance, `POOL Token is greater than 0`).to.be.gt(ethers.utils.parseEther("0"));
|
||||
|
||||
// Run spell transaction
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(depositSpells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
|
||||
const prizePoolContract = new ethers.Contract(DAI_PRIZE_POOL_ADDR, prizePoolABI, ethers.provider);
|
||||
let earlyExitFee = await prizePoolContract.callStatic["calculateEarlyExitFee"](dsaWallet0.address, PT_DAI_TICKET_ADDR, amount);
|
||||
expect(earlyExitFee.exitFee, "Exit Fee equal to .99 DAI because starts at 10%").to.be.eq(ethers.utils.parseEther(".99"));
|
||||
|
||||
|
||||
// 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]);
|
||||
await ethers.provider.send("evm_mine");
|
||||
|
||||
earlyExitFee = await prizePoolContract.callStatic["calculateEarlyExitFee"](dsaWallet0.address, PT_DAI_TICKET_ADDR, amount);
|
||||
expect(earlyExitFee.exitFee, "Exit Fee equal to 0 DAI because past 10 days").to.be.eq(0);
|
||||
|
||||
const withdrawSpells = [
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "withdrawInstantlyFrom",
|
||||
args: [DAI_PRIZE_POOL_ADDR, amount, PT_DAI_TICKET_ADDR, earlyExitFee.exitFee, 0, 0]
|
||||
},
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "claimAll",
|
||||
args: [TOKEN_FAUCET_PROXY_FACTORY_ADDR, [DAI_POOL_FAUCET_ADDR]]
|
||||
}
|
||||
]
|
||||
|
||||
// Run spell transaction
|
||||
const tx2 = await dsaWallet0.connect(wallet0).cast(...encodeSpells(withdrawSpells), wallet1.address)
|
||||
const receipt2 = await tx2.wait()
|
||||
|
||||
// After spell
|
||||
daiBalance = await daiToken.balanceOf(dsaWallet0.address);
|
||||
expect(daiBalance, `DAI balance equals 99`).to.be.eq(ethers.utils.parseEther("99"));
|
||||
|
||||
const balanceAfter = await cToken.balanceOf(dsaWallet0.address)
|
||||
expect(balanceAfter, `PoolTogether DAI Ticket equal 0`).to.be.eq(0);
|
||||
|
||||
// Expect
|
||||
const poolBalanceAfter = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalanceAfter, `Pool Token to be greateir than 0`).to.be.gt(ethers.utils.parseEther("0"));
|
||||
});
|
||||
})
|
||||
|
||||
describe("Main - DAI Pod Test", function() {
|
||||
it("Should deposit 99 DAI in DAI Pod", async function() {
|
||||
const amount = ethers.utils.parseEther("99") // 99 DAI
|
||||
const spells = [
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "depositToPod",
|
||||
args: [DAI_TOKEN_ADDR, DAI_POD_ADDR, amount, 0, 0]
|
||||
}
|
||||
]
|
||||
|
||||
// Before spell
|
||||
let daiToken = await ethers.getContractAt(abis.basic.erc20, DAI_TOKEN_ADDR)
|
||||
let daiBalance = await daiToken.balanceOf(dsaWallet0.address);
|
||||
expect(daiBalance, `DAI balance equals 99`).to.be.eq(ethers.utils.parseEther("99"));
|
||||
|
||||
let poolToken = await ethers.getContractAt(abis.basic.erc20, POOL_TOKEN_ADDRESS)
|
||||
const poolBalance = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalance, `POOL Token greater than 0`).to.be.gt(0);
|
||||
|
||||
let podToken = await ethers.getContractAt(abis.basic.erc20, DAI_POD_ADDR)
|
||||
const podBalance = await podToken.balanceOf(dsaWallet0.address)
|
||||
expect(podBalance, `Pod DAI Token equals 0`).to.be.eq(0);
|
||||
|
||||
// Run spell transaction
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
|
||||
// After spell
|
||||
daiBalance = await daiToken.balanceOf(dsaWallet0.address);
|
||||
expect(daiBalance, `DAI equals 0`).to.be.eq(0);
|
||||
|
||||
const poolBalanceAfter = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalanceAfter, `POOL Token greater than 0`).to.be.gt(0);
|
||||
|
||||
const podBalanceAfter = await podToken.balanceOf(dsaWallet0.address)
|
||||
expect(podBalanceAfter, `Pod DAI token greater than 0`).to.be.eq(ethers.utils.parseEther("99"));
|
||||
});
|
||||
|
||||
it("Should claim rewards from pod token drop", async function() {
|
||||
const spells = [
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "claimPodTokenDrop",
|
||||
args: [DAI_POD_TOKEN_DROP, 0]
|
||||
}
|
||||
]
|
||||
|
||||
const tokenDropContract = new ethers.Contract(DAI_POD_TOKEN_DROP, tokenDropABI, ethers.provider);
|
||||
const podContract = new ethers.Contract(DAI_POD_ADDR, podABI, masterSigner);
|
||||
|
||||
// drop(): Claim TokenDrop asset for PrizePool Pod and transfers token(s) to external Pod TokenDrop
|
||||
// dropt() also calls batch which, Deposit Pod float into PrizePool. Deposits the current float
|
||||
// amount into the PrizePool and claims current POOL rewards.
|
||||
const dropTx = await podContract.drop();
|
||||
await dropTx.wait();
|
||||
|
||||
// POOL Rewards able to claim from Pod Token Drop
|
||||
let claimAmount = await tokenDropContract.callStatic["claim"](dsaWallet0.address);
|
||||
|
||||
// Before spell
|
||||
let poolToken = await ethers.getContractAt(abis.basic.erc20, POOL_TOKEN_ADDRESS)
|
||||
const poolBalance = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalance, `POOL Token greater than 0`).to.be.gt(0);
|
||||
|
||||
// Run spell transaction
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
|
||||
// After spell
|
||||
const poolBalanceAfter = await poolToken.balanceOf(dsaWallet0.address)
|
||||
const total = claimAmount.add(poolBalance);
|
||||
expect(poolBalanceAfter, `POOL Token same as before spell`).to.be.eq(total);
|
||||
});
|
||||
|
||||
it("Should wait 11 days, withdraw all podTokens, get back 99 DAI", async function () {
|
||||
const amount = ethers.utils.parseEther("99") // 99 DAI
|
||||
|
||||
const podContract = new ethers.Contract(DAI_POD_ADDR, podABI, ethers.provider);
|
||||
let maxFee = await podContract.callStatic["getEarlyExitFee"](amount);
|
||||
// maxFee depends on if token has been deposited to PrizePool yet
|
||||
// since we called drop in previous test case, the tokens were deposited to PrizePool
|
||||
expect(maxFee, "Exit Fee equal to .99 DAI because token still in float").to.be.eq(ethers.utils.parseEther(".99"));
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "withdrawFromPod",
|
||||
args: [DAI_POD_ADDR, amount, maxFee, 0, 0]
|
||||
}
|
||||
]
|
||||
|
||||
// Before spell
|
||||
let daiToken = await ethers.getContractAt(abis.basic.erc20, DAI_TOKEN_ADDR)
|
||||
let daiBalance = await daiToken.balanceOf(dsaWallet0.address);
|
||||
expect(daiBalance, `DAI Balance equals 0`).to.be.eq(0);
|
||||
|
||||
let poolToken = await ethers.getContractAt(abis.basic.erc20, POOL_TOKEN_ADDRESS)
|
||||
const poolBalance = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalance, `POOL Token balance greater than 0`).to.be.gt(0);
|
||||
|
||||
let podToken = await ethers.getContractAt(abis.basic.erc20, DAI_POD_ADDR)
|
||||
const podBalance = await podToken.balanceOf(dsaWallet0.address)
|
||||
expect(podBalance, `Pod DAI Token equals 99`).to.be.eq(ethers.utils.parseEther("99"));
|
||||
|
||||
// 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]);
|
||||
await ethers.provider.send("evm_mine");
|
||||
|
||||
// Run spell transaction
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
|
||||
// After spell
|
||||
daiBalance = await daiToken.balanceOf(dsaWallet0.address);
|
||||
expect(daiBalance,
|
||||
`DAI balance equals 99, because of no early withdrawal fee`
|
||||
).to.be.eq(ethers.utils.parseEther("99"));
|
||||
|
||||
const poolBalanceAfter = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalanceAfter, `POOL Token to be greater than 0`).to.be.gt(0);
|
||||
|
||||
const podBalanceAfter = await podToken.balanceOf(dsaWallet0.address)
|
||||
expect(podBalanceAfter, `Pod DAI Token equals 0`).to.be.eq(0);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
it("Should deposit and withdraw from pod, get back same amount of 99 DAI", async function() {
|
||||
const amount = ethers.utils.parseEther("99")
|
||||
const maxFee = 0; // maxFee 0 since it doesn't give chance for Pod to actually deposit into PrizePool
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "depositToPod",
|
||||
args: [DAI_TOKEN_ADDR, DAI_POD_ADDR, amount, 0, 0]
|
||||
},
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "withdrawFromPod",
|
||||
args: [DAI_POD_ADDR, amount, maxFee, 0, 0]
|
||||
}
|
||||
]
|
||||
|
||||
// Before spell
|
||||
let daiToken = await ethers.getContractAt(abis.basic.erc20, DAI_TOKEN_ADDR)
|
||||
let daiBalance = await daiToken.balanceOf(dsaWallet0.address);
|
||||
expect(daiBalance, `DAI equals 99`).to.be.eq(ethers.utils.parseEther("99"));
|
||||
|
||||
let poolToken = await ethers.getContractAt(abis.basic.erc20, POOL_TOKEN_ADDRESS)
|
||||
const poolBalance = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalance, `POOL Token greater than 0`).to.be.gt(0);
|
||||
|
||||
// PodToken is 0
|
||||
let podToken = await ethers.getContractAt(abis.basic.erc20, DAI_POD_ADDR)
|
||||
const podBalance = await podToken.balanceOf(dsaWallet0.address)
|
||||
expect(podBalance, `Pod DAI Token equals 0`).to.be.eq(0);
|
||||
|
||||
// Run spell transaction
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
|
||||
// After spell
|
||||
daiBalance = await daiToken.balanceOf(dsaWallet0.address);
|
||||
expect(daiBalance,
|
||||
`DAI balance to be equal to 99, because funds still in 'float`
|
||||
).to.be.eq(ethers.utils.parseEther("99"));
|
||||
|
||||
const poolBalanceAfter = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalanceAfter, `POOL Token same as before spell`).to.be.eq(poolBalance);
|
||||
|
||||
// Expect Pod Token Balance to equal 0
|
||||
const podBalanceAfter = await podToken.balanceOf(dsaWallet0.address)
|
||||
expect(podBalanceAfter, `Pod DAI Token equals 0`).to.be.eq(ethers.utils.parseEther("0"));
|
||||
});
|
||||
})
|
||||
|
||||
describe("Main - UNISWAP POOL/ETH Prize Pool Test", function () {
|
||||
it("Should use uniswap to swap ETH for POOL, deposit to POOL/ETH LP, deposit POOL/ETH LP to PrizePool", async function () {
|
||||
const amount = ethers.utils.parseEther("100") // 100 POOL
|
||||
const slippage = ethers.utils.parseEther("0.03");
|
||||
const setId = "83478237"
|
||||
|
||||
const UniswapV2Router02ABI = [
|
||||
"function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts)"
|
||||
];
|
||||
|
||||
// Get amount of ETH for 100 POOL from Uniswap
|
||||
const UniswapV2Router02 = await ethers.getContractAt(UniswapV2Router02ABI, "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D");
|
||||
const amounts = await UniswapV2Router02.getAmountsOut(amount, [POOL_TOKEN_ADDRESS, WETH_ADDR]);
|
||||
const unitAmount = ethers.utils.parseEther(((amounts[1]*1.03)/amounts[0]).toString());
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: uniswapConnectorName,
|
||||
method: "buy",
|
||||
args: [POOL_TOKEN_ADDRESS, tokens.eth.address, amount, unitAmount, 0, setId]
|
||||
},
|
||||
{
|
||||
connector: uniswapConnectorName,
|
||||
method: "deposit",
|
||||
args: [POOL_TOKEN_ADDRESS, tokens.eth.address, amount, unitAmount, slippage, 0, setId]
|
||||
},
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "depositTo",
|
||||
args: [UNISWAP_POOLETHLP_PRIZE_POOL_ADDR, 0, PT_UNISWAP_POOLETHLP_TICKET_ADDR, setId, 0]
|
||||
}
|
||||
]
|
||||
|
||||
// Before Spell
|
||||
let ethBalance = await ethers.provider.getBalance(dsaWallet0.address);
|
||||
expect(ethBalance, `ETH Balance equals 9`).to.be.eq(ethers.utils.parseEther("9"));
|
||||
|
||||
let poolToken = await ethers.getContractAt(abis.basic.erc20, POOL_TOKEN_ADDRESS)
|
||||
const poolBalance = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalance, `POOL Token greater than 0`).to.be.gt(0);
|
||||
|
||||
let uniswapLPToken = await ethers.getContractAt(abis.basic.erc20, UNISWAP_POOLETHLP_TOKEN_ADDR)
|
||||
const uniswapPoolEthBalance = await uniswapLPToken.balanceOf(dsaWallet0.address)
|
||||
expect(uniswapPoolEthBalance, `Uniswap POOL/ETH LP equals 0`).to.be.eq(0);
|
||||
|
||||
let ptUniswapPoolEthToken = await ethers.getContractAt(abis.basic.erc20, PT_UNISWAP_POOLETHLP_TICKET_ADDR)
|
||||
const ptUniswapPoolEthBalance = await ptUniswapPoolEthToken.balanceOf(dsaWallet0.address)
|
||||
expect(ptUniswapPoolEthBalance, `PoolTogether Uniswap POOL?ETH LP equals 0`).to.be.eq(0);
|
||||
|
||||
// Run spell transaction
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
|
||||
// After spell
|
||||
ethBalance = await ethers.provider.getBalance(dsaWallet0.address);
|
||||
expect(ethBalance, `ETH Balance less than 9`).to.be.lt(ethers.utils.parseEther("9"));
|
||||
|
||||
const poolBalanceAfter = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalanceAfter, `POOL Token to be same after spell`).to.be.eq(poolBalance);
|
||||
|
||||
const uniswapPoolEthBalanceAfter = await uniswapLPToken.balanceOf(dsaWallet0.address)
|
||||
expect(uniswapPoolEthBalanceAfter, `Uniswap POOL/ETH LP equals 0`).to.be.eq(0);
|
||||
|
||||
const ptUniswapPoolEthBalanceAfter = await ptUniswapPoolEthToken.balanceOf(dsaWallet0.address)
|
||||
expect(ptUniswapPoolEthBalanceAfter, `PT Uniswap POOL/ETH LP to greater than 0`).to.be.gt(0);
|
||||
});
|
||||
|
||||
it("Should withdraw all PrizePool, get back Uniswap LP, claim POOL, deposit claimed POOL into Pool PrizePool", async function () {
|
||||
let ptUniswapPoolEthToken = await ethers.getContractAt(abis.basic.erc20, PT_UNISWAP_POOLETHLP_TICKET_ADDR)
|
||||
const ptUniswapPoolEthBalance = await ptUniswapPoolEthToken.balanceOf(dsaWallet0.address)
|
||||
const setId = "83478237"
|
||||
|
||||
let uniswapPrizePoolContract = new ethers.Contract(UNISWAP_POOLETHLP_PRIZE_POOL_ADDR, prizePoolABI, ethers.provider);
|
||||
let earlyExitFee = await uniswapPrizePoolContract.callStatic["calculateEarlyExitFee"](dsaWallet0.address, PT_UNISWAP_POOLETHLP_TICKET_ADDR, ptUniswapPoolEthBalance);
|
||||
expect(earlyExitFee.exitFee, "Exit Fee equals 0 because no early exit fee for this prize pool").to.be.eq(0);
|
||||
|
||||
const spells = [
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "withdrawInstantlyFrom",
|
||||
args: [UNISWAP_POOLETHLP_PRIZE_POOL_ADDR, ptUniswapPoolEthBalance, PT_UNISWAP_POOLETHLP_TICKET_ADDR, earlyExitFee.exitFee, 0, 0]
|
||||
},
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "claim",
|
||||
args: [UNISWAP_POOLETHLP_FAUCET_ADDR , setId]
|
||||
},
|
||||
{
|
||||
connector: ptConnectorName,
|
||||
method: "depositTo",
|
||||
args: [POOL_PRIZE_POOL_ADDR, 0, PT_POOL_TICKET_ADDR, setId, 0]
|
||||
}
|
||||
]
|
||||
|
||||
// Before spell
|
||||
let poolToken = await ethers.getContractAt(abis.basic.erc20, POOL_TOKEN_ADDRESS)
|
||||
const poolBalance = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalance, `POOL Token greater than 0`).to.be.gt(0);
|
||||
|
||||
// Uniswap POOL/ETH LP is 0
|
||||
let uniswapLPToken = await ethers.getContractAt(abis.basic.erc20, UNISWAP_POOLETHLP_TOKEN_ADDR)
|
||||
const uniswapPoolEthBalance = await uniswapLPToken.balanceOf(dsaWallet0.address)
|
||||
expect(uniswapPoolEthBalance, `Uniswap POOL/ETH LP equals 0`).to.be.eq(0);
|
||||
|
||||
expect(ptUniswapPoolEthBalance, `PT Uniswap POOL/ETH LP greater than 0`).to.be.gt(0);
|
||||
|
||||
let poolPoolTicket = await ethers.getContractAt(abis.basic.erc20, PT_POOL_TICKET_ADDR)
|
||||
const poolPoolTicketBalance = await poolPoolTicket.balanceOf(dsaWallet0.address)
|
||||
expect(poolPoolTicketBalance, `PoolTogether POOL Ticket equals 0`).to.be.eq(0);
|
||||
|
||||
// Run spell transaction
|
||||
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
|
||||
const receipt = await tx.wait()
|
||||
|
||||
// After spell
|
||||
const poolBalanceAfter = await poolToken.balanceOf(dsaWallet0.address)
|
||||
expect(poolBalanceAfter, `Pool Token Balance equal to balance before spell`).to.be.eq(poolBalance);
|
||||
|
||||
const uniswapPoolEthBalanceAfter = await uniswapLPToken.balanceOf(dsaWallet0.address)
|
||||
expect(uniswapPoolEthBalanceAfter, `Uniswap POOL/ETH LP to greater than 0`).to.be.gt(0);
|
||||
|
||||
const ptUniswapPoolEthBalanceAfter = await ptUniswapPoolEthToken.balanceOf(dsaWallet0.address)
|
||||
expect(ptUniswapPoolEthBalanceAfter, `PT Uniswap POOL/ETH LP equal 0`).to.be.eq(0);
|
||||
|
||||
const poolPoolTicketBalanceAfter = await poolPoolTicket.balanceOf(dsaWallet0.address)
|
||||
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