Skip to content

Commit

Permalink
fix(contract): explicity pass token to initialize
Browse files Browse the repository at this point in the history
  • Loading branch information
PierrickGT committed Jul 15, 2021
1 parent 32b130d commit 85d05ca
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 107 deletions.
5 changes: 1 addition & 4 deletions Constant.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
export const USDC_VAULT_ADDRESS_MAINNET = '0x5f18C75AbDAe578b483E5F43f12a39cF75b973a9';
export const USDC_ADDRESS_MAINNET = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';

export const DAI_VAULT_ADDRESS_MAINNET = '0x19D3364A399d251E894aC732651be8B0E4e85001';
export const DAI_VAULT_ADDRESS_MAINNET = '0xdA816459F1AB5631232FE5e97a05BBBb94970c95'; // yvDAI vault on Yearn API version 0.4.3
export const DAI_ADDRESS_MAINNET = '0x6B175474E89094C44Da98b954EedeAC495271d0F';

export const BINANCE_ADDRESS = '0x564286362092D8e7936f0549571a803B203aAceD';
Expand Down
17 changes: 10 additions & 7 deletions contracts/yield-source/YearnV2YieldSource.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import "@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";


/// @title Yield source for a PoolTogether prize pool that generates yield by depositing into Yearn Vaults.
/// @dev This contract inherits from the ERC20 implementation to keep track of users deposits
/// @dev This is a generic contract that will work with main Yearn Vaults. Vaults using v0.3.2 to v0.3.4 included
Expand Down Expand Up @@ -73,11 +72,13 @@ contract YearnV2YieldSource is IYieldSource, ERC20Upgradeable, OwnableUpgradeabl

/// @notice Initializes the yield source with
/// @param _vault Yearn V2 Vault in which the Yield Source will deposit `token` to generate Yield
/// @param _token Underlying token address (eg: DAI)
/// @param _decimals Number of decimals the shares (inherited ERC20) will have. Same as underlying asset to ensure same ExchangeRates.
/// @param _symbol Token symbol for the underlying ERC20 shares (eg: yvysDAI).
/// @param _name Token name for the underlying ERC20 shares (eg: PoolTogether Yearn V2 Vault DAI Yield Source).
function initialize(
IYVaultV2 _vault,
IERC20Upgradeable _token,
uint8 _decimals,
string calldata _symbol,
string calldata _name
Expand All @@ -97,7 +98,9 @@ contract YearnV2YieldSource is IYieldSource, ERC20Upgradeable, OwnableUpgradeabl
require(!_areEqualStrings(_vaultAPIVersion, "0.3.4"), "YearnV2YieldSource/vault-not-compatible");

vault = _vault;
token = IERC20Upgradeable(_vault.token());

require(address(_token) != address(0), "YearnV2YieldSource/token-not-zero-address");
token = _token;

__Ownable_init();
__ReentrancyGuard_init();
Expand All @@ -106,7 +109,7 @@ contract YearnV2YieldSource is IYieldSource, ERC20Upgradeable, OwnableUpgradeabl
require(_decimals > 0, "YearnV2YieldSource/decimals-not-greater-than-zero");
_setupDecimals(_decimals);

token.safeApprove(address(_vault), type(uint256).max);
_token.safeApprove(address(_vault), type(uint256).max);

emit YearnV2YieldSourceInitialized(
_vault,
Expand Down Expand Up @@ -160,18 +163,18 @@ contract YearnV2YieldSource is IYieldSource, ERC20Upgradeable, OwnableUpgradeabl
/// @dev Shares corresponding to the number of tokens supplied are mint to the user's balance
/// @dev Asset tokens are supplied to the yield source, then deposited into Aave
/// @param _amount The amount of asset tokens to be supplied
/// @param to The user whose balance will receive the tokens
function supplyTokenTo(uint256 _amount, address to) external override nonReentrant {
/// @param _to The user whose balance will receive the tokens
function supplyTokenTo(uint256 _amount, address _to) external override nonReentrant {
uint256 shares = _tokenToShares(_amount);

_mint(to, shares);
_mint(_to, shares);

// NOTE: we have to deposit after calculating shares to mint
token.safeTransferFrom(msg.sender, address(this), _amount);

_depositInVault();

emit SuppliedTokenTo(msg.sender, shares, _amount, to);
emit SuppliedTokenTo(msg.sender, shares, _amount, _to);
}

/// @notice Redeems asset tokens from the yield source
Expand Down
3 changes: 2 additions & 1 deletion deploy/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { writeFileSync } from 'fs';
import { HardhatRuntimeEnvironment } from 'hardhat/types';
import { DeployFunction, DeploymentSubmission, DeployResult } from 'hardhat-deploy/types';

import { DAI_VAULT_ADDRESS_MAINNET } from '../Constant';
import { DAI_ADDRESS_MAINNET, DAI_VAULT_ADDRESS_MAINNET } from '../Constant';
import {
action,
alert,
Expand Down Expand Up @@ -107,6 +107,7 @@ const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnviro
yearnV2YieldSourceInterface.getFunction('initialize'),
[
DAI_VAULT_ADDRESS_MAINNET,
DAI_ADDRESS_MAINNET,
18,
'yvysDAI',
'PoolTogether Yearn V2 Vault DAI Yield Source',
Expand Down
2 changes: 0 additions & 2 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import 'solidity-coverage';

import { HardhatUserConfig } from 'hardhat/config';

import * as verifyTask from './scripts/verify';
import * as forkTasks from './scripts/fork';
import networks from './hardhat.network';

Expand Down Expand Up @@ -71,7 +70,6 @@ const config: HardhatUserConfig = {
},
};

verifyTask;
forkTasks;

export default config;
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"coverage": "HIDE_DEPLOY_LOG=true OPTIMIZER_DISABLED=true hardhat coverage",
"deploy": "hardhat deploy --write true --network",
"deploy-fork": "FORK_ENABLED=true; rm -rf deployments/localhost && yarn deploy localhost",
"etherscan-verify": "hardhat etherscan:verify --network",
"etherscan-verify": "hardhat etherscan-verify --license GPL-3.0 --solc-input --network",
"format": "prettier --config .prettierrc --write **/*.ts",
"format:file": "prettier --config .prettierrc --write",
"hint": "solhint \"contracts/**/*.sol\"",
Expand All @@ -37,7 +37,7 @@
"@nomiclabs/hardhat-etherscan": "2.1.1",
"@nomiclabs/hardhat-waffle": "2.0.1",
"@openzeppelin/hardhat-upgrades": "1.6.0",
"@pooltogether/pooltogether-contracts": "3.3.6",
"@pooltogether/pooltogether-contracts": "3.3.9",
"@pooltogether/pooltogether-proxy-factory": "1.0.0-beta.3",
"@pooltogether/pooltogether-rng-contracts": "1.1.1",
"@studydefi/money-legos": "2.4.1",
Expand All @@ -51,7 +51,7 @@
"chalk": "4.1.0",
"debug": "4.3.1",
"ethereum-waffle": "3.3.0",
"ethers": "5.4.0",
"ethers": "5.4.1",
"evm-chains": "0.2.0",
"hardhat": "2.1.1",
"hardhat-abi-exporter": "2.2.1",
Expand Down
49 changes: 26 additions & 23 deletions scripts/fork/createYearnV2PrizePool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import ControlledToken from '@pooltogether/pooltogether-contracts/abis/Controlle
import MultipleWinners from '@pooltogether/pooltogether-contracts/abis/MultipleWinners.json';
import YieldSourcePrizePool from '@pooltogether/pooltogether-contracts/abis/YieldSourcePrizePool.json';

import { dai, usdc } from '@studydefi/money-legos/erc20';
import { dai } from '@studydefi/money-legos/erc20';

import { task } from 'hardhat/config';

import { USDC_VAULT_ADDRESS_MAINNET } from '../../Constant';
import { DAI_ADDRESS_MAINNET, DAI_VAULT_ADDRESS_MAINNET } from '../../Constant';

import { action, info, success } from '../../helpers';

Expand Down Expand Up @@ -47,11 +47,11 @@ export default task('fork:create-yearnV2-prize-pool', 'Create YearnV2 Prize Pool
const yearnV2YieldSourceConstructorArgs = yearnV2YieldSourceInterface.encodeFunctionData(
yearnV2YieldSourceInterface.getFunction('initialize'),
[
USDC_VAULT_ADDRESS_MAINNET,
DAI_VAULT_ADDRESS_MAINNET,
DAI_ADDRESS_MAINNET,
18,
'yvysDAI',
'PoolTogether Yearn V2 Vault DAI Yield Source',
contractsOwner._address,
],
);

Expand Down Expand Up @@ -111,7 +111,7 @@ export default task('fork:create-yearnV2-prize-pool', 'Create YearnV2 Prize Pool
yieldSourceMultipleWinnersTx.hash,
);

const yieldSourcePrizePoolInitializedEvent = yieldSourceMultipleWinnersReceipt.logs.map(
const yieldSourcePrizePoolInitializedEvents = yieldSourceMultipleWinnersReceipt.logs.map(
(log) => {
try {
return poolBuilder.interface.parseLog(log);
Expand All @@ -121,11 +121,13 @@ export default task('fork:create-yearnV2-prize-pool', 'Create YearnV2 Prize Pool
},
);

const yieldSourcePrizePoolInitializedEvent = yieldSourcePrizePoolInitializedEvents.find(
(event: any) => event && event.name === 'YieldSourcePrizePoolWithMultipleWinnersCreated',
);

const prizePool = await getContractAt(
YieldSourcePrizePool,
yieldSourcePrizePoolInitializedEvent[yieldSourcePrizePoolInitializedEvent.length - 1]?.args[
'prizePool'
],
yieldSourcePrizePoolInitializedEvent?.args.prizePool,
contractsOwner,
);

Expand All @@ -136,30 +138,31 @@ export default task('fork:create-yearnV2-prize-pool', 'Create YearnV2 Prize Pool
await prizePool.prizeStrategy(),
contractsOwner,
);
await prizeStrategy.addExternalErc20Award(dai.address);

const usdcAmount = ethers.utils.parseUnits('1000', 6);
const usdcContract = await getContractAt(usdc.abi, usdc.address, contractsOwner);
await usdcContract.approve(prizePool.address, usdcAmount);
const daiContract = await getContractAt(dai.abi, dai.address, contractsOwner);
const daiDecimals = await daiContract.decimals();
const daiAmount = ethers.utils.parseUnits('1000', daiDecimals);

await daiContract.approve(prizePool.address, daiAmount);

info(`Depositing ${ethers.utils.formatUnits(usdcAmount, 6)} USDC...`);
info(`Depositing ${ethers.utils.formatUnits(daiAmount, daiDecimals)} DAI...`);

await prizePool.depositTo(
contractsOwner._address,
usdcAmount,
daiAmount,
await prizeStrategy.ticket(),
AddressZero,
);

success('Deposited USDC!');
success('Deposited DAI!');

info(`Prize strategy owner: ${await prizeStrategy.owner()}`);
await increaseTime(30);

// simulating returns in the vault during the prizePeriod
const usdcProfits = ethers.utils.parseUnits('10000', 6);
info(`yVault generated ${ethers.utils.formatUnits(usdcProfits, 6)} USDC`);
await usdcContract.transfer(USDC_VAULT_ADDRESS_MAINNET, usdcProfits);
const daiProfits = ethers.utils.parseUnits('10000', daiDecimals);
info(`yVault generated ${ethers.utils.formatUnits(daiProfits, daiDecimals)} DAI`);
await daiContract.transfer(DAI_VAULT_ADDRESS_MAINNET, daiProfits);

await increaseTime(30);

Expand All @@ -181,12 +184,12 @@ export default task('fork:create-yearnV2-prize-pool', 'Create YearnV2 Prize Pool

const awarded = awardLogs.find((event) => event && event.name === 'Awarded');

success(`Awarded ${ethers.utils.formatUnits(awarded?.args?.amount, 6)} USDC!`);
success(`Awarded ${ethers.utils.formatUnits(awarded?.args?.amount, daiDecimals)} DAI!`);

info('Withdrawing...');
const ticketAddress = await prizeStrategy.ticket();
const ticket = await getContractAt(ControlledToken, ticketAddress, contractsOwner);
const withdrawalAmount = ethers.utils.parseUnits('100', 6);
const withdrawalAmount = ethers.utils.parseUnits('100', daiDecimals);
const earlyExitFee = await prizePool.callStatic.calculateEarlyExitFee(
contractsOwner._address,
ticket.address,
Expand All @@ -210,11 +213,11 @@ export default task('fork:create-yearnV2-prize-pool', 'Create YearnV2 Prize Pool
});

const withdrawn = withdrawLogs.find((event) => event && event.name === 'InstantWithdrawal');
success(`Withdrawn ${ethers.utils.formatUnits(withdrawn?.args?.redeemed, 6)} USDC!`);
success(`Exit fee was ${ethers.utils.formatUnits(withdrawn?.args?.exitFee, 6)} USDC`);
success(`Withdrawn ${ethers.utils.formatUnits(withdrawn?.args?.redeemed, daiDecimals)} DAI!`);
success(`Exit fee was ${ethers.utils.formatUnits(withdrawn?.args?.exitFee, daiDecimals)} DAI`);

await prizePool.captureAwardBalance();
const awardBalance = await prizePool.callStatic.awardBalance();
success(`Current awardable balance is ${ethers.utils.formatUnits(awardBalance, 6)} USDC`);
success(`Current awardable balance is ${ethers.utils.formatUnits(awardBalance, daiDecimals)} DAI`);
},
);
8 changes: 4 additions & 4 deletions scripts/fork/distributeEtherFromBinance.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { usdc } from '@studydefi/money-legos/erc20';
import { dai } from '@studydefi/money-legos/erc20';
import { task } from 'hardhat/config';

import { BINANCE7_ADDRESS, DAI_RICH_ADDRESS } from '../../Constant';
Expand All @@ -18,7 +18,7 @@ export default task(
const binance = provider.getUncheckedSigner(BINANCE7_ADDRESS);
const daiRichSigner = provider.getUncheckedSigner(DAI_RICH_ADDRESS);

const usdcContract = await getContractAt(usdc.abi, usdc.address, daiRichSigner);
const daiContract = await getContractAt(dai.abi, dai.address, daiRichSigner);

const recipients: { [key: string]: string } = {
['Deployer']: deployer,
Expand All @@ -32,8 +32,8 @@ export default task(
const name = keys[i];
const address = recipients[name];

info(`Sending 20,000 USDC to ${name}...`);
await usdcContract.transfer(address, ethers.utils.parseUnits('20000', 6));
info(`Sending 20,000 DAI to ${name}...`);
await daiContract.transfer(address, ethers.utils.parseUnits('20000', 18));

info(`Sending 1000 Ether to ${name}...`);
await binance.sendTransaction({ to: address, value: ethers.utils.parseEther('1000') });
Expand Down
45 changes: 0 additions & 45 deletions scripts/verify.ts

This file was deleted.

Loading

0 comments on commit 85d05ca

Please sign in to comment.