mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
Adding staking to Notional DSA connector (#4)
* Adding staking * Adding tests * Formatting * Reformat events * Addressing PR comments
This commit is contained in:
parent
74a7effdb4
commit
b7d60ca8ae
|
@ -88,4 +88,32 @@ contract Events {
|
||||||
);
|
);
|
||||||
|
|
||||||
event LogBatchActionRaw(address indexed account);
|
event LogBatchActionRaw(address indexed account);
|
||||||
|
|
||||||
|
event LogMintSNoteFromBPT(address indexed account, uint256 bptAmount);
|
||||||
|
|
||||||
|
event LogMintSNoteFromETH(
|
||||||
|
address indexed account,
|
||||||
|
uint256 noteAmount,
|
||||||
|
uint256 ethAmount,
|
||||||
|
uint256 minBPT
|
||||||
|
);
|
||||||
|
|
||||||
|
event LogMintSNoteFromWETH(
|
||||||
|
address indexed account,
|
||||||
|
uint256 noteAmount,
|
||||||
|
uint256 wethAmount,
|
||||||
|
uint256 minBPT
|
||||||
|
);
|
||||||
|
|
||||||
|
event LogStartCoolDown(address indexed account);
|
||||||
|
|
||||||
|
event LogStopCoolDown(address indexed account);
|
||||||
|
|
||||||
|
event LogRedeemSNote(
|
||||||
|
address indexed account,
|
||||||
|
uint256 sNOTEAmount,
|
||||||
|
uint256 minWETH,
|
||||||
|
uint256 minNOTE,
|
||||||
|
bool redeemWETH
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
pragma solidity ^0.7.6;
|
pragma solidity ^0.7.6;
|
||||||
pragma abicoder v2;
|
pragma abicoder v2;
|
||||||
|
|
||||||
import { Token, NotionalInterface, BalanceAction, BalanceActionWithTrades, DepositActionType } from "./interface.sol";
|
import { Token, NotionalInterface, StakingInterface, BalanceAction, BalanceActionWithTrades, DepositActionType } from "./interface.sol";
|
||||||
import { Basic } from "../../common/basic.sol";
|
import { Basic } from "../../common/basic.sol";
|
||||||
import { DSMath } from "../../common/math.sol";
|
import { DSMath } from "../../common/math.sol";
|
||||||
import { TokenInterface } from "../../common/interfaces.sol";
|
import { TokenInterface } from "../../common/interfaces.sol";
|
||||||
|
@ -18,6 +18,22 @@ abstract contract Helpers is DSMath, Basic {
|
||||||
NotionalInterface internal constant notional =
|
NotionalInterface internal constant notional =
|
||||||
NotionalInterface(0x1344A36A1B56144C3Bc62E7757377D288fDE0369);
|
NotionalInterface(0x1344A36A1B56144C3Bc62E7757377D288fDE0369);
|
||||||
|
|
||||||
|
/// @dev sNOTE contract address
|
||||||
|
StakingInterface internal constant staking =
|
||||||
|
StakingInterface(0x38DE42F4BA8a35056b33A746A6b45bE9B1c3B9d2);
|
||||||
|
|
||||||
|
/// @dev sNOTE balancer pool token address
|
||||||
|
TokenInterface internal constant bpt =
|
||||||
|
TokenInterface(0x5122E01D819E58BB2E22528c0D68D310f0AA6FD7);
|
||||||
|
|
||||||
|
/// @dev NOTE token address
|
||||||
|
TokenInterface internal constant note =
|
||||||
|
TokenInterface(0xCFEAead4947f0705A14ec42aC3D44129E1Ef3eD5);
|
||||||
|
|
||||||
|
/// @dev WETH token address
|
||||||
|
TokenInterface internal constant weth =
|
||||||
|
TokenInterface(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
|
||||||
|
|
||||||
/// @notice Returns the address of the underlying token for a given currency id,
|
/// @notice Returns the address of the underlying token for a given currency id,
|
||||||
function getAssetOrUnderlyingToken(uint16 currencyId, bool underlying)
|
function getAssetOrUnderlyingToken(uint16 currencyId, bool underlying)
|
||||||
internal
|
internal
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
pragma solidity ^0.7.6;
|
pragma solidity ^0.7.6;
|
||||||
pragma abicoder v2;
|
pragma abicoder v2;
|
||||||
|
|
||||||
|
import { TokenInterface } from "../../common/interfaces.sol";
|
||||||
|
|
||||||
/// @notice Different types of internal tokens
|
/// @notice Different types of internal tokens
|
||||||
/// - UnderlyingToken: underlying asset for a cToken (except for Ether)
|
/// - UnderlyingToken: underlying asset for a cToken (except for Ether)
|
||||||
/// - cToken: Compound interest bearing token
|
/// - cToken: Compound interest bearing token
|
||||||
|
@ -133,3 +135,26 @@ interface NotionalInterface {
|
||||||
BalanceActionWithTrades[] calldata actions
|
BalanceActionWithTrades[] calldata actions
|
||||||
) external payable;
|
) external payable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface StakingInterface is TokenInterface {
|
||||||
|
function mintFromETH(uint256 noteAmount, uint256 minBPT) external payable;
|
||||||
|
|
||||||
|
function mintFromWETH(
|
||||||
|
uint256 noteAmount,
|
||||||
|
uint256 wethAmount,
|
||||||
|
uint256 minBPT
|
||||||
|
) external;
|
||||||
|
|
||||||
|
function mintFromBPT(uint256 bptAmount) external;
|
||||||
|
|
||||||
|
function startCoolDown() external;
|
||||||
|
|
||||||
|
function stopCoolDown() external;
|
||||||
|
|
||||||
|
function redeem(
|
||||||
|
uint256 sNOTEAmount,
|
||||||
|
uint256 minWETH,
|
||||||
|
uint256 minNOTE,
|
||||||
|
bool redeemWETH
|
||||||
|
) external;
|
||||||
|
}
|
||||||
|
|
|
@ -655,6 +655,137 @@ abstract contract NotionalResolver is Events, Helpers {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @notice Mints sNOTE from the underlying BPT token.
|
||||||
|
/// @dev Mints sNOTE from the underlying BPT token.
|
||||||
|
/// @param bptAmount is the amount of BPT to transfer from the msg.sender.
|
||||||
|
function mintSNoteFromBPT(uint256 bptAmount)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
returns (string memory _eventName, bytes memory _eventParam)
|
||||||
|
{
|
||||||
|
if (bptAmount == type(uint256).max)
|
||||||
|
bptAmount = bpt.balanceOf(address(this));
|
||||||
|
|
||||||
|
approve(bpt, address(staking), bptAmount);
|
||||||
|
|
||||||
|
staking.mintFromBPT(bptAmount);
|
||||||
|
|
||||||
|
_eventName = "LogMintSNoteFromBPT(address,uint256)";
|
||||||
|
_eventParam = abi.encode(address(this), bptAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice Mints sNOTE from some amount of NOTE and ETH
|
||||||
|
/// @dev Mints sNOTE from some amount of NOTE and ETH
|
||||||
|
/// @param noteAmount amount of NOTE to transfer into the sNOTE contract
|
||||||
|
/// @param minBPT slippage parameter to prevent front running
|
||||||
|
function mintSNoteFromETH(
|
||||||
|
uint256 noteAmount,
|
||||||
|
uint256 ethAmount,
|
||||||
|
uint256 minBPT
|
||||||
|
)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
returns (string memory _eventName, bytes memory _eventParam)
|
||||||
|
{
|
||||||
|
if (noteAmount == type(uint256).max)
|
||||||
|
noteAmount = note.balanceOf(address(this));
|
||||||
|
|
||||||
|
if (ethAmount == type(uint256).max) ethAmount = address(this).balance;
|
||||||
|
|
||||||
|
approve(note, address(staking), noteAmount);
|
||||||
|
|
||||||
|
staking.mintFromETH{ value: ethAmount }(noteAmount, minBPT);
|
||||||
|
|
||||||
|
_eventName = "LogMintSNoteFromETH(address,uint256,uint256,uint256)";
|
||||||
|
_eventParam = abi.encode(address(this), ethAmount, noteAmount, minBPT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice Mints sNOTE from some amount of NOTE and WETH
|
||||||
|
/// @dev Mints sNOTE from some amount of NOTE and WETH
|
||||||
|
/// @param noteAmount amount of NOTE to transfer into the sNOTE contract
|
||||||
|
/// @param wethAmount amount of WETH to transfer into the sNOTE contract
|
||||||
|
/// @param minBPT slippage parameter to prevent front running
|
||||||
|
function mintSNoteFromWETH(
|
||||||
|
uint256 noteAmount,
|
||||||
|
uint256 wethAmount,
|
||||||
|
uint256 minBPT
|
||||||
|
)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
returns (string memory _eventName, bytes memory _eventParam)
|
||||||
|
{
|
||||||
|
if (noteAmount == type(uint256).max)
|
||||||
|
noteAmount = note.balanceOf(address(this));
|
||||||
|
|
||||||
|
if (wethAmount == type(uint256).max)
|
||||||
|
wethAmount = weth.balanceOf(address(this));
|
||||||
|
|
||||||
|
approve(note, address(staking), noteAmount);
|
||||||
|
approve(weth, address(staking), wethAmount);
|
||||||
|
|
||||||
|
staking.mintFromWETH(noteAmount, wethAmount, minBPT);
|
||||||
|
|
||||||
|
_eventName = "LogMintSNoteFromWETH(address,uint256,uint256,uint256)";
|
||||||
|
_eventParam = abi.encode(address(this), noteAmount, wethAmount, minBPT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice Begins a cool down period for the sender
|
||||||
|
/// @dev This is required to redeem tokens
|
||||||
|
function startCoolDown()
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
returns (string memory _eventName, bytes memory _eventParam)
|
||||||
|
{
|
||||||
|
staking.startCoolDown();
|
||||||
|
|
||||||
|
_eventName = "LogStartCoolDown(address)";
|
||||||
|
_eventParam = abi.encode(address(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice Stops a cool down for the sender
|
||||||
|
/// @dev User must start another cool down period in order to call redeemSNote
|
||||||
|
function stopCoolDown()
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
returns (string memory _eventName, bytes memory _eventParam)
|
||||||
|
{
|
||||||
|
staking.stopCoolDown();
|
||||||
|
|
||||||
|
_eventName = "LogStopCoolDown(address)";
|
||||||
|
_eventParam = abi.encode(address(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice Redeems some amount of sNOTE to underlying constituent tokens (ETH and NOTE).
|
||||||
|
/// @dev An account must have passed its cool down expiration before they can redeem
|
||||||
|
/// @param sNOTEAmount amount of sNOTE to redeem
|
||||||
|
/// @param minWETH slippage protection for ETH/WETH amount
|
||||||
|
/// @param minNOTE slippage protection for NOTE amount
|
||||||
|
/// @param redeemWETH true if redeeming to WETH to ETH
|
||||||
|
function redeemSNote(
|
||||||
|
uint256 sNOTEAmount,
|
||||||
|
uint256 minWETH,
|
||||||
|
uint256 minNOTE,
|
||||||
|
bool redeemWETH
|
||||||
|
)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
returns (string memory _eventName, bytes memory _eventParam)
|
||||||
|
{
|
||||||
|
if (sNOTEAmount == type(uint256).max)
|
||||||
|
sNOTEAmount = staking.balanceOf(address(this));
|
||||||
|
|
||||||
|
staking.redeem(sNOTEAmount, minWETH, minNOTE, redeemWETH);
|
||||||
|
|
||||||
|
_eventName = "LogRedeemSNote(address,uint256,uint256,uint256,bool)";
|
||||||
|
_eventParam = abi.encode(
|
||||||
|
address(this),
|
||||||
|
sNOTEAmount,
|
||||||
|
minWETH,
|
||||||
|
minNOTE,
|
||||||
|
redeemWETH
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @notice Executes a number of batch actions on the account without getId or setId integration
|
* @notice Executes a number of batch actions on the account without getId or setId integration
|
||||||
* @dev This method will allow the user to take almost any action on Notional but does not have any
|
* @dev This method will allow the user to take almost any action on Notional but does not have any
|
||||||
|
|
|
@ -88,10 +88,14 @@ const NOTIONAL_CONTRACT_ABI = [
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const SNOTE_CONTRACT_ADDRESS = '0x38de42f4ba8a35056b33a746a6b45be9b1c3b9d2';
|
||||||
|
|
||||||
const WETH_TOKEN_ADDRESS = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
|
const WETH_TOKEN_ADDRESS = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
|
||||||
const DAI_TOKEN_ADDRESS = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
|
const DAI_TOKEN_ADDRESS = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
|
||||||
const CDAI_TOKEN_ADDRESS = "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643";
|
const CDAI_TOKEN_ADDRESS = "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643";
|
||||||
const CETH_TOKEN_ADDRESS = "0x4ddc2d193948926d02f9b1fe9e1daa0718270ed5";
|
const CETH_TOKEN_ADDRESS = "0x4ddc2d193948926d02f9b1fe9e1daa0718270ed5";
|
||||||
|
const BPT_TOKEN_ADDRESS = "0x5122E01D819E58BB2E22528c0D68D310f0AA6FD7";
|
||||||
|
const NOTE_TOKEN_ADDRESS = "0xCFEAead4947f0705A14ec42aC3D44129E1Ef3eD5";
|
||||||
const ERC20_TOKEN_ABI = [
|
const ERC20_TOKEN_ABI = [
|
||||||
"function transfer(address _to, uint256 _value) public returns (bool success)",
|
"function transfer(address _to, uint256 _value) public returns (bool success)",
|
||||||
"function balanceOf(address account) external view returns (uint256)",
|
"function balanceOf(address account) external view returns (uint256)",
|
||||||
|
@ -101,9 +105,12 @@ const ERC20_TOKEN_ABI = [
|
||||||
export default {
|
export default {
|
||||||
NOTIONAL_CONTRACT_ADDRESS,
|
NOTIONAL_CONTRACT_ADDRESS,
|
||||||
NOTIONAL_CONTRACT_ABI,
|
NOTIONAL_CONTRACT_ABI,
|
||||||
|
SNOTE_CONTRACT_ADDRESS,
|
||||||
WETH_TOKEN_ADDRESS,
|
WETH_TOKEN_ADDRESS,
|
||||||
|
BPT_TOKEN_ADDRESS,
|
||||||
DAI_TOKEN_ADDRESS,
|
DAI_TOKEN_ADDRESS,
|
||||||
CDAI_TOKEN_ADDRESS,
|
CDAI_TOKEN_ADDRESS,
|
||||||
CETH_TOKEN_ADDRESS,
|
CETH_TOKEN_ADDRESS,
|
||||||
|
NOTE_TOKEN_ADDRESS,
|
||||||
ERC20_TOKEN_ABI
|
ERC20_TOKEN_ABI
|
||||||
};
|
};
|
||||||
|
|
|
@ -200,6 +200,119 @@ const withdrawLend = async (
|
||||||
await tx.wait()
|
await tx.wait()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mintSNoteFromETH = async (
|
||||||
|
dsa: any,
|
||||||
|
authority: any,
|
||||||
|
referrer: any,
|
||||||
|
noteAmount: BigNumber,
|
||||||
|
ethAmount: BigNumber,
|
||||||
|
minBPT: BigNumber
|
||||||
|
) => {
|
||||||
|
const spells = [
|
||||||
|
{
|
||||||
|
connector: "NOTIONAL-TEST-A",
|
||||||
|
method: "mintSNoteFromETH",
|
||||||
|
args: [noteAmount, ethAmount, minBPT]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
|
||||||
|
await tx.wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
const mintSNoteFromWETH = async (
|
||||||
|
dsa: any,
|
||||||
|
authority: any,
|
||||||
|
referrer: any,
|
||||||
|
noteAmount: BigNumber,
|
||||||
|
wethAmount: BigNumber,
|
||||||
|
minBPT: BigNumber
|
||||||
|
) => {
|
||||||
|
const spells = [
|
||||||
|
{
|
||||||
|
connector: "NOTIONAL-TEST-A",
|
||||||
|
method: "mintSNoteFromWETH",
|
||||||
|
args: [noteAmount, wethAmount, minBPT]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
|
||||||
|
await tx.wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
const mintSNoteFromBPT = async (
|
||||||
|
dsa: any,
|
||||||
|
authority: any,
|
||||||
|
referrer: any,
|
||||||
|
bptAmount: BigNumber
|
||||||
|
) => {
|
||||||
|
const spells = [
|
||||||
|
{
|
||||||
|
connector: "NOTIONAL-TEST-A",
|
||||||
|
method: "mintSNoteFromBPT",
|
||||||
|
args: [bptAmount]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
|
||||||
|
await tx.wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
const startCoolDown = async (
|
||||||
|
dsa: any,
|
||||||
|
authority: any,
|
||||||
|
referrer: any
|
||||||
|
) => {
|
||||||
|
const spells = [
|
||||||
|
{
|
||||||
|
connector: "NOTIONAL-TEST-A",
|
||||||
|
method: "startCoolDown",
|
||||||
|
args: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
|
||||||
|
await tx.wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
const stopCoolDown = async (
|
||||||
|
dsa: any,
|
||||||
|
authority: any,
|
||||||
|
referrer: any
|
||||||
|
) => {
|
||||||
|
const spells = [
|
||||||
|
{
|
||||||
|
connector: "NOTIONAL-TEST-A",
|
||||||
|
method: "stopCoolDown",
|
||||||
|
args: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
|
||||||
|
await tx.wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
const redeemSNote = async (
|
||||||
|
dsa: any,
|
||||||
|
authority: any,
|
||||||
|
referrer: any,
|
||||||
|
sNOTEAmount: BigNumber,
|
||||||
|
minWETH: BigNumber,
|
||||||
|
minNOTE: BigNumber,
|
||||||
|
redeemWETH: boolean
|
||||||
|
) => {
|
||||||
|
const spells = [
|
||||||
|
{
|
||||||
|
connector: "NOTIONAL-TEST-A",
|
||||||
|
method: "redeemSNote",
|
||||||
|
args: [sNOTEAmount, minWETH, minNOTE, redeemWETH]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const tx = await dsa.connect(authority).cast(...encodeSpells(spells), referrer.address);
|
||||||
|
await tx.wait()
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
depositCollteral,
|
depositCollteral,
|
||||||
depositAndMintNToken,
|
depositAndMintNToken,
|
||||||
|
@ -209,5 +322,11 @@ export default {
|
||||||
redeemNTokenRaw,
|
redeemNTokenRaw,
|
||||||
redeemNTokenAndWithdraw,
|
redeemNTokenAndWithdraw,
|
||||||
redeemNTokenAndDeleverage,
|
redeemNTokenAndDeleverage,
|
||||||
depositCollateralBorrowAndWithdraw
|
depositCollateralBorrowAndWithdraw,
|
||||||
|
mintSNoteFromETH,
|
||||||
|
mintSNoteFromWETH,
|
||||||
|
mintSNoteFromBPT,
|
||||||
|
startCoolDown,
|
||||||
|
stopCoolDown,
|
||||||
|
redeemSNote
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,8 @@ const DAI_WHALE = "0x6dfaf865a93d3b0b5cfd1b4db192d1505676645b";
|
||||||
const CDAI_WHALE = "0x33b890d6574172e93e58528cd99123a88c0756e9";
|
const CDAI_WHALE = "0x33b890d6574172e93e58528cd99123a88c0756e9";
|
||||||
const ETH_WHALE = "0x7D24796f7dDB17d73e8B1d0A3bbD103FBA2cb2FE";
|
const ETH_WHALE = "0x7D24796f7dDB17d73e8B1d0A3bbD103FBA2cb2FE";
|
||||||
const CETH_WHALE = "0x1a1cd9c606727a7400bb2da6e4d5c70db5b4cade";
|
const CETH_WHALE = "0x1a1cd9c606727a7400bb2da6e4d5c70db5b4cade";
|
||||||
|
const WETH_WHALE = "0x6555e1cc97d3cba6eaddebbcd7ca51d75771e0b8";
|
||||||
|
const BPT_WHALE = "0x38de42f4ba8a35056b33a746a6b45be9b1c3b9d2";
|
||||||
const MaxUint96 = BigNumber.from("0xffffffffffffffffffffffff");
|
const MaxUint96 = BigNumber.from("0xffffffffffffffffffffffff");
|
||||||
const DEPOSIT_ASSET = 1;
|
const DEPOSIT_ASSET = 1;
|
||||||
const DEPOSIT_UNDERLYING = 2;
|
const DEPOSIT_UNDERLYING = 2;
|
||||||
|
@ -35,12 +37,18 @@ describe("Notional", function () {
|
||||||
let instaConnectorsV2: any;
|
let instaConnectorsV2: any;
|
||||||
let connector: any;
|
let connector: any;
|
||||||
let notional: any;
|
let notional: any;
|
||||||
|
let snote: any;
|
||||||
let daiToken: any;
|
let daiToken: any;
|
||||||
let cdaiToken: any;
|
let cdaiToken: any;
|
||||||
let cethToken: any;
|
let cethToken: any;
|
||||||
|
let wethToken: any;
|
||||||
|
let bptToken: any;
|
||||||
|
let noteToken: any;
|
||||||
let daiWhale: any;
|
let daiWhale: any;
|
||||||
let cdaiWhale: any;
|
let cdaiWhale: any;
|
||||||
let cethWhale: any;
|
let cethWhale: any;
|
||||||
|
let wethWhale: any;
|
||||||
|
let bptWhale: any;
|
||||||
|
|
||||||
const wallets = provider.getWallets()
|
const wallets = provider.getWallets()
|
||||||
const [wallet0, wallet1, wallet2, wallet3] = wallets
|
const [wallet0, wallet1, wallet2, wallet3] = wallets
|
||||||
|
@ -73,6 +81,14 @@ describe("Notional", function () {
|
||||||
method: "hardhat_impersonateAccount",
|
method: "hardhat_impersonateAccount",
|
||||||
params: [CETH_WHALE]
|
params: [CETH_WHALE]
|
||||||
})
|
})
|
||||||
|
await hre.network.provider.request({
|
||||||
|
method: "hardhat_impersonateAccount",
|
||||||
|
params: [WETH_WHALE]
|
||||||
|
})
|
||||||
|
await hre.network.provider.request({
|
||||||
|
method: "hardhat_impersonateAccount",
|
||||||
|
params: [BPT_WHALE]
|
||||||
|
})
|
||||||
|
|
||||||
masterSigner = await getMasterSigner()
|
masterSigner = await getMasterSigner()
|
||||||
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
|
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
|
||||||
|
@ -87,6 +103,11 @@ describe("Notional", function () {
|
||||||
contracts.NOTIONAL_CONTRACT_ABI,
|
contracts.NOTIONAL_CONTRACT_ABI,
|
||||||
ethers.provider
|
ethers.provider
|
||||||
);
|
);
|
||||||
|
snote = new ethers.Contract(
|
||||||
|
contracts.SNOTE_CONTRACT_ADDRESS,
|
||||||
|
contracts.ERC20_TOKEN_ABI,
|
||||||
|
ethers.provider
|
||||||
|
)
|
||||||
daiToken = new ethers.Contract(
|
daiToken = new ethers.Contract(
|
||||||
contracts.DAI_TOKEN_ADDRESS,
|
contracts.DAI_TOKEN_ADDRESS,
|
||||||
contracts.ERC20_TOKEN_ABI,
|
contracts.ERC20_TOKEN_ABI,
|
||||||
|
@ -105,7 +126,24 @@ describe("Notional", function () {
|
||||||
ethers.provider
|
ethers.provider
|
||||||
);
|
);
|
||||||
cethWhale = await ethers.getSigner(CETH_WHALE);
|
cethWhale = await ethers.getSigner(CETH_WHALE);
|
||||||
dsaWallet0 = await buildDSAv2(wallet0.address)
|
wethToken = new ethers.Contract(
|
||||||
|
contracts.WETH_TOKEN_ADDRESS,
|
||||||
|
contracts.ERC20_TOKEN_ABI,
|
||||||
|
ethers.provider
|
||||||
|
);
|
||||||
|
wethWhale = await ethers.getSigner(WETH_WHALE);
|
||||||
|
bptToken = new ethers.Contract(
|
||||||
|
contracts.BPT_TOKEN_ADDRESS,
|
||||||
|
contracts.ERC20_TOKEN_ABI,
|
||||||
|
ethers.provider
|
||||||
|
);
|
||||||
|
bptWhale = await ethers.getSigner(BPT_WHALE);
|
||||||
|
noteToken = new ethers.Contract(
|
||||||
|
contracts.NOTE_TOKEN_ADDRESS,
|
||||||
|
contracts.ERC20_TOKEN_ABI,
|
||||||
|
ethers.provider
|
||||||
|
)
|
||||||
|
dsaWallet0 = await buildDSAv2(wallet0.address);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Deposit Tests", function () {
|
describe("Deposit Tests", function () {
|
||||||
|
@ -395,4 +433,81 @@ describe("Notional", function () {
|
||||||
expect(after[0][3], "expect fDAI debt balance to go down after deleverage").to.be.lte(ethers.utils.parseUnits("-2000000", 0));
|
expect(after[0][3], "expect fDAI debt balance to go down after deleverage").to.be.lte(ethers.utils.parseUnits("-2000000", 0));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Staking Tests", function () {
|
||||||
|
it("test_stake_ETH", async function () {
|
||||||
|
const depositAmount = ethers.utils.parseEther("1");
|
||||||
|
await wallet0.sendTransaction({
|
||||||
|
to: dsaWallet0.address,
|
||||||
|
value: depositAmount
|
||||||
|
});
|
||||||
|
expect(await snote.balanceOf(dsaWallet0.address), "expect 0 initial sNOTE balance").to.be.equal(0);
|
||||||
|
await helpers.mintSNoteFromETH(dsaWallet0, wallet0, wallet1, BigNumber.from(0), depositAmount, BigNumber.from(0));
|
||||||
|
expect(await snote.balanceOf(dsaWallet0.address), "expect sNOTE balance to increase").to.be.gte(ethers.utils.parseEther("297"))
|
||||||
|
});
|
||||||
|
|
||||||
|
it("test_stake_WETH", async function () {
|
||||||
|
const depositAmount = ethers.utils.parseEther("1");
|
||||||
|
await wethToken.connect(wethWhale).transfer(dsaWallet0.address, depositAmount);
|
||||||
|
expect(await snote.balanceOf(dsaWallet0.address), "expect 0 initial sNOTE balance").to.be.equal(0);
|
||||||
|
await helpers.mintSNoteFromWETH(dsaWallet0, wallet0, wallet1, BigNumber.from(0), depositAmount, BigNumber.from(0));
|
||||||
|
expect(await snote.balanceOf(dsaWallet0.address), "expect sNOTE balance to increase").to.be.gte(ethers.utils.parseEther("297"))
|
||||||
|
});
|
||||||
|
|
||||||
|
it("test_stake_BPT", async function () {
|
||||||
|
const depositAmount = ethers.utils.parseEther("1");
|
||||||
|
await wallet0.sendTransaction({
|
||||||
|
to: bptWhale.address,
|
||||||
|
value: depositAmount
|
||||||
|
});
|
||||||
|
await bptToken.connect(bptWhale).transfer(dsaWallet0.address, depositAmount);
|
||||||
|
expect(await snote.balanceOf(dsaWallet0.address), "expect 0 initial sNOTE balance").to.be.equal(0);
|
||||||
|
await helpers.mintSNoteFromBPT(dsaWallet0, wallet0, wallet1, depositAmount);
|
||||||
|
expect(await snote.balanceOf(dsaWallet0.address), "expect sNOTE balance to increase").to.be.eq(depositAmount)
|
||||||
|
});
|
||||||
|
|
||||||
|
it("test_unstake_success", async function () {
|
||||||
|
const depositAmount = ethers.utils.parseEther("1");
|
||||||
|
await wallet0.sendTransaction({
|
||||||
|
to: bptWhale.address,
|
||||||
|
value: depositAmount
|
||||||
|
});
|
||||||
|
await bptToken.connect(bptWhale).transfer(dsaWallet0.address, depositAmount);
|
||||||
|
await helpers.mintSNoteFromBPT(dsaWallet0, wallet0, wallet1, depositAmount);
|
||||||
|
await helpers.startCoolDown(dsaWallet0, wallet0, wallet1);
|
||||||
|
// Skip ahead 16 days
|
||||||
|
await hre.network.provider.send("evm_increaseTime", [1382400])
|
||||||
|
await hre.network.provider.send("evm_mine")
|
||||||
|
await helpers.redeemSNote(
|
||||||
|
dsaWallet0,
|
||||||
|
wallet0,
|
||||||
|
wallet1,
|
||||||
|
ethers.constants.MaxUint256,
|
||||||
|
BigNumber.from(0),
|
||||||
|
BigNumber.from(0),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
expect(await noteToken.balanceOf(dsaWallet0.address)).to.be.gte(ethers.utils.parseUnits("50000000000", 0));
|
||||||
|
expect(await provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseUnits("32500000000000000", 0))
|
||||||
|
});
|
||||||
|
|
||||||
|
it("test_unstable_failure", async function () {
|
||||||
|
const depositAmount = ethers.utils.parseEther("1");
|
||||||
|
await wallet0.sendTransaction({
|
||||||
|
to: bptWhale.address,
|
||||||
|
value: depositAmount
|
||||||
|
});
|
||||||
|
await bptToken.connect(bptWhale).transfer(dsaWallet0.address, depositAmount);
|
||||||
|
await helpers.mintSNoteFromBPT(dsaWallet0, wallet0, wallet1, depositAmount);
|
||||||
|
await expect(helpers.redeemSNote(
|
||||||
|
dsaWallet0,
|
||||||
|
wallet0,
|
||||||
|
wallet1,
|
||||||
|
ethers.constants.MaxUint256,
|
||||||
|
BigNumber.from(0),
|
||||||
|
BigNumber.from(0),
|
||||||
|
true
|
||||||
|
)).to.be.revertedWith("Not in Redemption Window");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user