mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
Fixing build errors
This commit is contained in:
parent
45a85c09aa
commit
6bbfa348f0
|
@ -1,13 +1,111 @@
|
|||
pragma solidity ^0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
contract Helpers {
|
||||
import {Token, NotionalInterface} from "./interface.sol";
|
||||
import {Basic} from "../../common/basic.sol";
|
||||
|
||||
// function getUnderlyingToken(uint16 currencyId);
|
||||
// function getAssetToken(uint16 currencyId);
|
||||
// function getCashBalance(uint16 currencyId);
|
||||
// function getNTokenBalance(uint16 currencyId);
|
||||
// function convertToInternal(uint16 currencyId);
|
||||
contract Helpers is Basic {
|
||||
uint8 internal constant LEND_TRADE = 0;
|
||||
uint8 internal constant BORROW_TRADE = 1;
|
||||
int256 internal constant INTERNAL_TOKEN_PRECISION = 1e8;
|
||||
uint256 internal constant ETH_CURRENCY_ID = 1;
|
||||
int256 private constant _INT256_MIN = type(int256).min;
|
||||
|
||||
function getDepositAmountAndSetApproval(uint16 currencyId)
|
||||
function executeActionWithBalanceChange(uint16 currencyId)
|
||||
NotionalInterface internal constant notional =
|
||||
NotionalInterface(0xE592427A0AEce92De3Edee1F18E0157C05861564);
|
||||
|
||||
function getUnderlyingToken(uint16 currencyId) internal returns (address) {
|
||||
(, Token memory underlyingToken) = notional.getCurrency(currencyId);
|
||||
return underlyingToken.tokenAddress;
|
||||
}
|
||||
|
||||
function getAssetToken(uint16 currencyId) internal returns (address) {
|
||||
(Token memory assetToken, ) = notional.getCurrency(currencyId);
|
||||
return assetToken.tokenAddress;
|
||||
}
|
||||
|
||||
function getCashBalance(uint16 currencyId)
|
||||
internal
|
||||
returns (int256 cashBalance)
|
||||
{
|
||||
(cashBalance, , ) = notional.getAccountBalance(
|
||||
currencyId,
|
||||
address(this)
|
||||
);
|
||||
}
|
||||
|
||||
function getNTokenBalance(uint16 currencyId)
|
||||
internal
|
||||
returns (int256 nTokenBalance)
|
||||
{
|
||||
(, nTokenBalance, ) = notional.getAccountBalance(
|
||||
currencyId,
|
||||
address(this)
|
||||
);
|
||||
}
|
||||
|
||||
function convertToInternal(uint16 currencyId, int256 amount)
|
||||
internal
|
||||
pure
|
||||
returns (int256)
|
||||
{
|
||||
// If token decimals is greater than INTERNAL_TOKEN_PRECISION then this will truncate
|
||||
// down to the internal precision. Resulting dust will accumulate to the protocol.
|
||||
// If token decimals is less than INTERNAL_TOKEN_PRECISION then this will add zeros to the
|
||||
// end of amount and will not result in dust.
|
||||
(Token memory assetToken, ) = notional.getCurrency(currencyId);
|
||||
if (assetToken.decimals == INTERNAL_TOKEN_PRECISION) return amount;
|
||||
return div(mul(amount, INTERNAL_TOKEN_PRECISION), assetToken.decimals);
|
||||
}
|
||||
|
||||
function encodeLendTrade(
|
||||
uint8 marketIndex,
|
||||
uint88 fCashAmount,
|
||||
uint32 minLendRate
|
||||
) internal returns (bytes32) {
|
||||
return
|
||||
abi.encodePacked(
|
||||
LEND_TRADE,
|
||||
marketIndex,
|
||||
fCashAmount,
|
||||
minLendRate,
|
||||
uint120(0)
|
||||
);
|
||||
}
|
||||
|
||||
function encodeBorrowTrade(
|
||||
uint8 marketIndex,
|
||||
uint88 fCashAmount,
|
||||
uint32 maxBorrowRate
|
||||
) internal returns (bytes32) {
|
||||
return
|
||||
abi.encodePacked(
|
||||
BORROW_TRADE,
|
||||
marketIndex,
|
||||
fCashAmount,
|
||||
maxBorrowRate,
|
||||
uint120(0)
|
||||
);
|
||||
}
|
||||
|
||||
function mul(int256 a, int256 b) internal pure returns (int256 c) {
|
||||
c = a * b;
|
||||
if (a == -1) require(b == 0 || c / b == a);
|
||||
else require(a == 0 || c / a == b);
|
||||
}
|
||||
|
||||
function div(int256 a, int256 b) internal pure returns (int256 c) {
|
||||
require(!(b == -1 && a == _INT256_MIN)); // dev: int256 div overflow
|
||||
// NOTE: solidity will automatically revert on divide by zero
|
||||
c = a / b;
|
||||
}
|
||||
|
||||
function sub(int256 x, int256 y) internal pure returns (int256 z) {
|
||||
// taken from uniswap v3
|
||||
require((z = x - y) <= x == (y >= 0));
|
||||
}
|
||||
|
||||
//function getDepositAmountAndSetApproval(uint16 currencyId) internal;
|
||||
|
||||
//function executeActionWithBalanceChange(uint16 currencyId) internal;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
pragma solidity ^0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
/// @notice Different types of internal tokens
|
||||
/// - UnderlyingToken: underlying asset for a cToken (except for Ether)
|
||||
/// - cToken: Compound interest bearing token
|
||||
/// - cETH: Special handling for cETH tokens
|
||||
/// - Ether: the one and only
|
||||
/// - NonMintable: tokens that do not have an underlying (therefore not cTokens)
|
||||
enum TokenType {
|
||||
UnderlyingToken,
|
||||
cToken,
|
||||
cETH,
|
||||
Ether,
|
||||
NonMintable
|
||||
}
|
||||
|
||||
/// @notice Specifies different deposit actions that can occur during BalanceAction or BalanceActionWithTrades
|
||||
enum DepositActionType {
|
||||
// No deposit action
|
||||
None,
|
||||
// Deposit asset cash, depositActionAmount is specified in asset cash external precision
|
||||
DepositAsset,
|
||||
// Deposit underlying tokens that are mintable to asset cash, depositActionAmount is specified in underlying token
|
||||
// external precision
|
||||
DepositUnderlying,
|
||||
// Deposits specified asset cash external precision amount into an nToken and mints the corresponding amount of
|
||||
// nTokens into the account
|
||||
DepositAssetAndMintNToken,
|
||||
// Deposits specified underlying in external precision, mints asset cash, and uses that asset cash to mint nTokens
|
||||
DepositUnderlyingAndMintNToken,
|
||||
// Redeems an nToken balance to asset cash. depositActionAmount is specified in nToken precision. Considered a deposit action
|
||||
// because it deposits asset cash into an account. If there are fCash residuals that cannot be sold off, will revert.
|
||||
RedeemNToken,
|
||||
// Converts specified amount of asset cash balance already in Notional to nTokens. depositActionAmount is specified in
|
||||
// Notional internal 8 decimal precision.
|
||||
ConvertCashToNToken
|
||||
}
|
||||
|
||||
/// @notice Defines a balance action with a set of trades to do as well
|
||||
struct BalanceActionWithTrades {
|
||||
DepositActionType actionType;
|
||||
uint16 currencyId;
|
||||
uint256 depositActionAmount;
|
||||
uint256 withdrawAmountInternalPrecision;
|
||||
bool withdrawEntireCashBalance;
|
||||
bool redeemToUnderlying;
|
||||
// Array of tightly packed 32 byte objects that represent trades. See TradeActionType documentation
|
||||
bytes32[] trades;
|
||||
}
|
||||
|
||||
/// @notice Defines a balance action for batchAction
|
||||
struct BalanceAction {
|
||||
// Deposit action to take (if any)
|
||||
DepositActionType actionType;
|
||||
uint16 currencyId;
|
||||
// Deposit action amount must correspond to the depositActionType, see documentation above.
|
||||
uint256 depositActionAmount;
|
||||
// Withdraw an amount of asset cash specified in Notional internal 8 decimal precision
|
||||
uint256 withdrawAmountInternalPrecision;
|
||||
// If set to true, will withdraw entire cash balance. Useful if there may be an unknown amount of asset cash
|
||||
// residual left from trading.
|
||||
bool withdrawEntireCashBalance;
|
||||
// If set to true, will redeem asset cash to the underlying token on withdraw.
|
||||
bool redeemToUnderlying;
|
||||
}
|
||||
|
||||
struct Token {
|
||||
address tokenAddress;
|
||||
bool hasTransferFee;
|
||||
int256 decimals;
|
||||
TokenType tokenType;
|
||||
uint256 maxCollateralBalance;
|
||||
}
|
||||
|
||||
interface NotionalInterface {
|
||||
function getCurrency(uint16 currencyId)
|
||||
external
|
||||
view
|
||||
returns (Token memory assetToken, Token memory underlyingToken);
|
||||
|
||||
function getAccountBalance(uint16 currencyId, address account)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
int256 cashBalance,
|
||||
int256 nTokenBalance,
|
||||
uint256 lastClaimTime
|
||||
);
|
||||
|
||||
function depositUnderlyingToken(
|
||||
address account,
|
||||
uint16 currencyId,
|
||||
uint256 amountExternalPrecision
|
||||
) external payable returns (uint256);
|
||||
|
||||
function depositAssetToken(
|
||||
address account,
|
||||
uint16 currencyId,
|
||||
uint256 amountExternalPrecision
|
||||
) external returns (uint256);
|
||||
|
||||
function withdraw(
|
||||
uint16 currencyId,
|
||||
uint88 amountInternalPrecision,
|
||||
bool redeemToUnderlying
|
||||
) external returns (uint256);
|
||||
|
||||
function nTokenClaimIncentives() external returns (uint256);
|
||||
|
||||
function nTokenRedeem(
|
||||
address redeemer,
|
||||
uint16 currencyId,
|
||||
uint96 tokensToRedeem_,
|
||||
bool sellTokenAssets
|
||||
) external returns (int256);
|
||||
|
||||
function batchBalanceAction(
|
||||
address account,
|
||||
BalanceAction[] calldata actions
|
||||
) external payable;
|
||||
|
||||
function batchBalanceAndTradeAction(address account, BalanceActionWithTrades[] calldata actions)
|
||||
external
|
||||
payable;
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
pragma solidity ^0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
import { TokenInterface } from "../common/interfaces.sol";
|
||||
import { DepositActionType, BalanceActionWithTrades, BalanceAction } from "./interface.sol";
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
/**
|
||||
* @title Notional
|
||||
|
@ -29,14 +32,14 @@ abstract contract NotionalResolver is Events, Helpers {
|
|||
uint assetCashDeposited;
|
||||
address tokenAddress = useUnderlying ? getUnderlyingToken(currencyId) : getAssetToken(currencyId);
|
||||
depositAmount = getUint(getId, depositAmount);
|
||||
if (depositAmount == uint(-1)) depositAmount = ERC20(tokenAddress).balanceOf(address(this));
|
||||
if (depositAmount == uint(-1)) depositAmount = IERC20(tokenAddress).balanceOf(address(this));
|
||||
|
||||
approve(tokenAddress, address(notional), depositAmount);
|
||||
|
||||
if (useUnderlying && currencyId == ETH_CURRENCY_ID) {
|
||||
assetCashDeposited = notional.depositUnderlying{value: depositAmount}(address(this), currencyId, depositAmount);
|
||||
assetCashDeposited = notional.depositUnderlyingToken{value: depositAmount}(address(this), currencyId, depositAmount);
|
||||
} else if (useUnderlying) {
|
||||
assetCashDeposited = notional.depositUnderlying{value: depositAmount}(address(this), currencyId, depositAmount);
|
||||
assetCashDeposited = notional.depositUnderlyingToken{value: depositAmount}(address(this), currencyId, depositAmount);
|
||||
} else {
|
||||
assetCashDeposited = notional.depositAssetToken(address(this), currencyId, depositAmount);
|
||||
}
|
||||
|
@ -166,14 +169,14 @@ abstract contract NotionalResolver is Events, Helpers {
|
|||
getAssetToken(currencyId);
|
||||
|
||||
// TODO: handle ETH
|
||||
balanceBefore = ERC20(tokenAddress).balanceOf(address(this));
|
||||
balanceBefore = IERC20(tokenAddress).balanceOf(address(this));
|
||||
}
|
||||
|
||||
notional.batchBalanceAction(address(this), action);
|
||||
|
||||
if (setId != 0) {
|
||||
// TODO: handle ETH
|
||||
uint netBalance = balanceBefore.sub(ERC20(tokenAddress).balanceOf(address(this)));
|
||||
uint netBalance = sub(balanceBefore, IERC20(tokenAddress).balanceOf(address(this)));
|
||||
// This can be used to determine the exact amount withdrawn
|
||||
setUint(setId, netBalance);
|
||||
}
|
||||
|
@ -205,7 +208,7 @@ abstract contract NotionalResolver is Events, Helpers {
|
|||
) external returns (string memory _eventName, bytes memory _eventParam) {
|
||||
tokensToRedeem = getUint(getId, tokensToRedeem);
|
||||
if (tokensToRedeem == uint(-1)) tokensToRedeem = getNTokenBalance(currencyId);
|
||||
notional.nTokenRedeem(currencyId, tokensToRedeem, sellTokenAssets);
|
||||
notional.nTokenRedeem(currencyId, tokensToRedeem, true);
|
||||
|
||||
BalanceActionWithTrades[] memory action = new BalanceActionWithTrades[1];
|
||||
action[0].actionType = DepositActionType.RedeemNToken;
|
||||
|
@ -217,7 +220,7 @@ abstract contract NotionalResolver is Events, Helpers {
|
|||
trades[0] = encodeLendTrade(marketIndex, fCashAmount, minLendRate);
|
||||
action[0].trades = trades;
|
||||
|
||||
notional.batchBalanceActionWithTrades(address(this), action);
|
||||
notional.batchBalanceAndTradeAction(address(this), action);
|
||||
|
||||
_eventName = "LogRedeemNTokenAndDeleverage(address,uint16,uint,uint8,uint)";
|
||||
_eventParam = abi.encode(address(this), currencyId, tokensToRedeem, marketIndex, fCashAmount);
|
||||
|
@ -242,7 +245,7 @@ abstract contract NotionalResolver is Events, Helpers {
|
|||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
address tokenAddress = useUnderlying ? getUnderlyingToken(currencyId) : getAssetToken(currencyId);
|
||||
depositAmount = getUint(getId, depositAmount);
|
||||
if (depositAmount == uint(-1)) depositAmount = ERC20(tokenAddress).balanceOf(address(this));
|
||||
if (depositAmount == uint(-1)) depositAmount = IERC20(tokenAddress).balanceOf(address(this));
|
||||
|
||||
approve(tokenAddress, address(notional), depositAmount);
|
||||
BalanceAction[] memory action = new BalanceAction[1];
|
||||
|
@ -251,17 +254,17 @@ abstract contract NotionalResolver is Events, Helpers {
|
|||
action[0].depositActionAmount = depositAmount;
|
||||
// withdraw amount, withdraw cash and redeem to underlying are all 0 and false
|
||||
|
||||
uint nTokenBefore
|
||||
uint nTokenBefore;
|
||||
if (setId != 0) {
|
||||
nTokenBefore = getNTokenBalance(currencyId);
|
||||
}
|
||||
|
||||
uint msgValue = currencyId == ETH_CURRENCY_ID ? depositAmount : 0;
|
||||
notional.batchBalanceActionWithTrades{value: msgValue}(address(this), action);
|
||||
notional.batchBalanceAndTradeAction{value: msgValue}(address(this), action);
|
||||
|
||||
if (setId != 0) {
|
||||
// Set the amount of nTokens minted
|
||||
setUint(setId, getNTokenBalance(currencyId).sub(nTokenBefore));
|
||||
setUint(setId, sub(getNTokenBalance(currencyId), nTokenBefore));
|
||||
}
|
||||
|
||||
// todo: events
|
||||
|
@ -274,7 +277,7 @@ abstract contract NotionalResolver is Events, Helpers {
|
|||
uint setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
cashBalanceToMint = getUint(getId, cashBalanceToMint);
|
||||
if (cashBalanceToMint == uint(-1)) = cashBalanceToMint = getCashBalance(currencyId);
|
||||
if (cashBalanceToMint == uint(-1)) cashBalanceToMint = getCashBalance(currencyId);
|
||||
|
||||
BalanceAction[] memory action = new BalanceAction[1];
|
||||
action[0].actionType = DepositActionType.ConvertCashToNToken;
|
||||
|
@ -282,7 +285,7 @@ abstract contract NotionalResolver is Events, Helpers {
|
|||
action[0].depositActionAmount = cashBalanceToMint;
|
||||
// NOTE: withdraw amount, withdraw cash and redeem to underlying are all 0 and false
|
||||
|
||||
uint nTokenBefore
|
||||
uint nTokenBefore;
|
||||
if (setId != 0) {
|
||||
nTokenBefore = getNTokenBalance(currencyId);
|
||||
}
|
||||
|
@ -308,7 +311,7 @@ abstract contract NotionalResolver is Events, Helpers {
|
|||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
address tokenAddress = useUnderlying ? getUnderlyingToken(currencyId) : getAssetToken(currencyId);
|
||||
depositAmount = getUint(getId, depositAmount);
|
||||
if (depositAmount == uint(-1)) depositAmount = ERC20(tokenAddress).balanceOf(address(this));
|
||||
if (depositAmount == uint(-1)) depositAmount = IERC20(tokenAddress).balanceOf(address(this));
|
||||
|
||||
approve(tokenAddress, address(notional), depositAmount);
|
||||
BalanceAction[] memory action = new BalanceAction[1];
|
||||
|
@ -345,7 +348,7 @@ abstract contract NotionalResolver is Events, Helpers {
|
|||
require(depositCurrencyId != borrowCurrencyId);
|
||||
address tokenAddress = useUnderlying ? getUnderlyingToken(depositCurrencyId) : getAssetToken(depositCurrencyId);
|
||||
depositAmount = getUint(getId, depositAmount);
|
||||
if (depositAmount == uint(-1)) depositAmount = ERC20(tokenAddress).balanceOf(address(this));
|
||||
if (depositAmount == uint(-1)) depositAmount = IERC20(tokenAddress).balanceOf(address(this));
|
||||
|
||||
approve(tokenAddress, address(notional), depositAmount);
|
||||
BalanceActionWithTrades[] memory action = new BalanceActionWithTrades[](2);
|
||||
|
@ -373,20 +376,20 @@ abstract contract NotionalResolver is Events, Helpers {
|
|||
action[borrowIndex].redeemToUnderlying = useUnderlying;
|
||||
|
||||
bytes32[] memory trades = new bytes32[](1);
|
||||
trades[borrowIndex] = encodeBorrowTrade(marketIndex, fCashAmount, minLendRate);
|
||||
trades[borrowIndex] = encodeBorrowTrade(marketIndex, fCashAmount, maxBorrowRate);
|
||||
action[borrowIndex].trades = trades;
|
||||
|
||||
address borrowToken;
|
||||
uint balanceBefore;
|
||||
if (setId != 0) {
|
||||
address borrowToken = useUnderlying ? getUnderlyingToken(borrowCurrencyId) : getAssetToken(borrowCurrencyId);
|
||||
balanceBefore = ERC20(borrowToken).balanceOf(address(this));
|
||||
balanceBefore = IERC20(borrowToken).balanceOf(address(this));
|
||||
}
|
||||
|
||||
notional.batchBalanceActionWithTrades{value: msgValue}(address(this), action);
|
||||
|
||||
if (setId != 0) {
|
||||
setUint(setId, ERC20(borrowToken).balanceOf(address(this)).sub(balanceBefore));
|
||||
setUint(setId, IERC20(borrowToken).balanceOf(address(this)).sub(balanceBefore));
|
||||
}
|
||||
|
||||
// todo: events
|
||||
|
@ -400,6 +403,7 @@ abstract contract NotionalResolver is Events, Helpers {
|
|||
uint getId,
|
||||
uint setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
bool useUnderlying = currencyId != ETH_CURRENCY_ID;
|
||||
BalanceActionWithTrades[] memory action = new BalanceActionWithTrades[]();
|
||||
action[0].actionType = DepositActionType.None;
|
||||
action[0].currencyId = currencyId;
|
||||
|
@ -416,13 +420,13 @@ abstract contract NotionalResolver is Events, Helpers {
|
|||
uint balanceBefore;
|
||||
if (setId != 0) {
|
||||
address tokenAddress = useUnderlying ? getUnderlyingToken(currencyId) : getAssetToken(currencyId);
|
||||
balanceBefore = ERC20(borrowToken).balanceOf(address(this));
|
||||
balanceBefore = IERC20(tokenAddress).balanceOf(address(this));
|
||||
}
|
||||
|
||||
notional.batchBalanceActionWithTrades{value: msgValue}(address(this), action);
|
||||
notional.batchBalanceActionWithTrades{value: msg.value}(address(this), action);
|
||||
|
||||
if (setId != 0) {
|
||||
setUint(setId, ERC20(borrowToken).balanceOf(address(this)).sub(balanceBefore));
|
||||
setUint(setId, IERC20(tokenAddress).balanceOf(address(this)).sub(balanceBefore));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -444,9 +448,9 @@ abstract contract NotionalResolver is Events, Helpers {
|
|||
* @param actions a set of BatchActionWithTrades that will be executed for this account
|
||||
*/
|
||||
function batchActionRaw(
|
||||
BatchActionWithTrades[] memory actions
|
||||
BalanceActionWithTrades[] memory actions
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
notional.batchBalanceActionWithTrades(address(this), actions);
|
||||
notional.batchBalanceAndTradeAction(address(this), actions);
|
||||
|
||||
// todo: events
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user