This contract's source code is verified! Compiler
0.5.16+commit.9c3226ce
File 1 of 16: BAllowance.sol
pragma solidity =0.5.16;
import "./BStorage.sol" ;
import "./PoolToken.sol" ;
contract BAllowance is PoolToken , BStorage {
event BorrowApproval (
address indexed owner,
address indexed spender,
uint256 value
) ;
function _borrowApprove (
address owner,
address spender,
uint256 value
) private {
borrowAllowance[owner][spender] = value;
emit BorrowApproval(owner, spender, value);
}
function borrowApprove (address spender, uint256 value )
external
returns (bool )
{
_borrowApprove(msg .sender , spender, value);
return true ;
}
function _checkBorrowAllowance (
address owner,
address spender,
uint256 value
) internal {
uint256 _borrowAllowance = borrowAllowance[owner][spender];
if (spender ! = owner & & _borrowAllowance ! = uint256 (-1 )) {
require (_borrowAllowance > = value, "Tarot: BORROW_NOT_ALLOWED" );
borrowAllowance[owner][spender] = _borrowAllowance - value;
}
}
bytes32 public constant BORROW_PERMIT_TYPEHASH =
0xf6d86ed606f871fa1a557ac0ba607adce07767acf53f492fb215a1a4db4aea6f ;
function borrowPermit (
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external {
_checkSignature(
owner,
spender,
value,
deadline,
v,
r,
s,
BORROW_PERMIT_TYPEHASH
);
_borrowApprove(owner, spender, value);
}
}
File 2 of 16: BInterestRateModel.sol
pragma solidity =0.5.16;
import "./BStorage.sol" ;
import "./PoolToken.sol" ;
contract BInterestRateModel is PoolToken , BStorage {
uint public constant KINK_MULTIPLIER = 3 ;
uint public constant KINK_BORROW_RATE_MAX = 281.582952e9 ;
uint public constant KINK_BORROW_RATE_MIN = 0 .31709792e9 ;
event AccrueInterest (uint interestAccumulated, uint borrowIndex, uint totalBorrows ) ;
event CalculateKinkBorrowRate (uint kinkBorrowRate ) ;
event CalculateBorrowRate (uint borrowRate ) ;
function _calculateBorrowRate ( ) internal {
uint _kinkUtilizationRate = kinkUtilizationRate;
uint _adjustSpeed = adjustSpeed;
uint _borrowRate = borrowRate;
uint _kinkBorrowRate = kinkBorrowRate;
uint32 _rateUpdateTimestamp = rateUpdateTimestamp;
uint32 timeElapsed = getBlockTimestamp() - _rateUpdateTimestamp;
if (timeElapsed > 0 ) {
rateUpdateTimestamp = getBlockTimestamp();
uint adjustFactor;
if (_borrowRate < _kinkBorrowRate) {
uint tmp = (_kinkBorrowRate - _borrowRate) * 1e18 / _kinkBorrowRate * _adjustSpeed * timeElapsed / 1e18 ;
adjustFactor = tmp > 1e18 ? 0 : 1e18 - tmp;
} else {
uint tmp = (_borrowRate - _kinkBorrowRate) * 1e18 / _kinkBorrowRate * _adjustSpeed * timeElapsed / 1e18 ;
adjustFactor = tmp + 1e18 ;
}
_kinkBorrowRate = _kinkBorrowRate * adjustFactor / 1e18 ;
if (_kinkBorrowRate > KINK_BORROW_RATE_MAX) _kinkBorrowRate = KINK_BORROW_RATE_MAX;
if (_kinkBorrowRate < KINK_BORROW_RATE_MIN) _kinkBorrowRate = KINK_BORROW_RATE_MIN;
kinkBorrowRate = uint48 (_kinkBorrowRate);
emit CalculateKinkBorrowRate(_kinkBorrowRate);
}
uint _utilizationRate;
{
uint _totalBorrows = totalBorrows;
uint _actualBalance = totalBalance.add(_totalBorrows);
_utilizationRate = (_actualBalance = = 0 ) ? 0 : _totalBorrows * 1e18 / _actualBalance;
}
if (_utilizationRate < = _kinkUtilizationRate) {
_borrowRate = _kinkBorrowRate * _utilizationRate / _kinkUtilizationRate;
} else {
uint overUtilization = (_utilizationRate - _kinkUtilizationRate) * 1e18 / (1e18 - _kinkUtilizationRate);
_borrowRate = ((KINK_MULTIPLIER - 1 ) * overUtilization + 1e18 ) * _kinkBorrowRate / 1e18 ;
}
borrowRate = uint48 (_borrowRate);
emit CalculateBorrowRate(_borrowRate);
}
function accrueInterest ( ) public {
uint _borrowIndex = borrowIndex;
uint _totalBorrows = totalBorrows;
uint32 _accrualTimestamp = accrualTimestamp;
uint32 blockTimestamp = getBlockTimestamp();
if (_accrualTimestamp = = blockTimestamp) return ;
uint32 timeElapsed = blockTimestamp - _accrualTimestamp;
accrualTimestamp = blockTimestamp;
uint interestFactor = uint (borrowRate).mul(timeElapsed);
uint interestAccumulated = interestFactor.mul(_totalBorrows).div(1e18 );
_totalBorrows = _totalBorrows.add( interestAccumulated );
_borrowIndex = _borrowIndex.add( interestFactor.mul(_borrowIndex).div(1e18 ) );
borrowIndex = safe112(_borrowIndex);
totalBorrows = safe112(_totalBorrows);
emit AccrueInterest(interestAccumulated, _borrowIndex, _totalBorrows);
}
function getBlockTimestamp ( ) public view returns (uint32 ) {
return uint32 (block .timestamp % 2 * * 32 );
}
}File 3 of 16: BSetter.sol
pragma solidity =0.5.16;
import "./BStorage.sol" ;
import "./PoolToken.sol" ;
import "./interfaces/IFactory.sol" ;
contract BSetter is PoolToken , BStorage {
uint256 public constant RESERVE_FACTOR_MAX = 0 .20e18 ;
uint256 public constant KINK_UR_MIN = 0 .50e18 ;
uint256 public constant KINK_UR_MAX = 0 .99e18 ;
uint256 public constant ADJUST_SPEED_MIN = 0 .05787037e12 ;
uint256 public constant ADJUST_SPEED_MAX = 115.74074e12 ;
event NewReserveFactor (uint256 newReserveFactor ) ;
event NewKinkUtilizationRate (uint256 newKinkUtilizationRate ) ;
event NewAdjustSpeed (uint256 newAdjustSpeed ) ;
event NewBorrowTracker (address newBorrowTracker ) ;
function _initialize (
string calldata _name,
string calldata _symbol,
address _underlying,
address _collateral
) external {
require (msg .sender = = factory, "Tarot: UNAUTHORIZED" );
_setName(_name, _symbol);
underlying = _underlying;
collateral = _collateral;
exchangeRateLast = initialExchangeRate;
}
function _setReserveFactor (uint256 newReserveFactor ) external nonReentrant {
_checkSetting(newReserveFactor, 0 , RESERVE_FACTOR_MAX);
reserveFactor = newReserveFactor;
emit NewReserveFactor(newReserveFactor);
}
function _setKinkUtilizationRate (uint256 newKinkUtilizationRate )
external
nonReentrant
{
_checkSetting(newKinkUtilizationRate, KINK_UR_MIN, KINK_UR_MAX);
kinkUtilizationRate = newKinkUtilizationRate;
emit NewKinkUtilizationRate(newKinkUtilizationRate);
}
function _setAdjustSpeed (uint256 newAdjustSpeed ) external nonReentrant {
_checkSetting(newAdjustSpeed, ADJUST_SPEED_MIN, ADJUST_SPEED_MAX);
adjustSpeed = newAdjustSpeed;
emit NewAdjustSpeed(newAdjustSpeed);
}
function _setBorrowTracker (address newBorrowTracker ) external nonReentrant {
_checkAdmin();
borrowTracker = newBorrowTracker;
emit NewBorrowTracker(newBorrowTracker);
}
function _checkSetting (
uint256 parameter,
uint256 min,
uint256 max
) internal view {
_checkAdmin();
require (parameter > = min, "Tarot: INVALID_SETTING" );
require (parameter < = max, "Tarot: INVALID_SETTING" );
}
function _checkAdmin ( ) internal view {
require (msg .sender = = IFactory(factory).admin(), "Tarot: UNAUTHORIZED" );
}
}
File 4 of 16: BStorage.sol
pragma solidity =0.5.16;
contract BStorage {
address public collateral;
mapping (address = > mapping (address = > uint256 )) public borrowAllowance;
struct BorrowSnapshot {
uint112 principal;
uint112 interestIndex;
}
mapping (address = > BorrowSnapshot) internal borrowBalances;
uint112 public borrowIndex = 1e18 ;
uint112 public totalBorrows;
uint32 public accrualTimestamp = uint32 (block .timestamp % 2 * * 32 );
uint256 public exchangeRateLast;
uint48 public borrowRate;
uint48 public kinkBorrowRate = 6.3419584e9 ;
uint32 public rateUpdateTimestamp = uint32 (block .timestamp % 2 * * 32 );
uint256 public reserveFactor = 0 .10e18 ;
uint256 public kinkUtilizationRate = 0 .75e18 ;
uint256 public adjustSpeed = 50e12 ;
address public borrowTracker;
function safe112 (uint256 n ) internal pure returns (uint112 ) {
require (n < 2 * * 112 , "Tarot: SAFE112" );
return uint112 (n);
}
}
File 5 of 16: Borrowable.sol
pragma solidity =0.5.16;
import "./PoolToken.sol" ;
import "./BAllowance.sol" ;
import "./BInterestRateModel.sol" ;
import "./BSetter.sol" ;
import "./BStorage.sol" ;
import "./interfaces/IBorrowable.sol" ;
import "./interfaces/ICollateral.sol" ;
import "./interfaces/ITarotCallee.sol" ;
import "./interfaces/IERC20.sol" ;
import "./interfaces/IFactory.sol" ;
import "./interfaces/IBorrowTracker.sol" ;
import "./libraries/Math.sol" ;
contract Borrowable is
IBorrowable ,
PoolToken ,
BStorage ,
BSetter ,
BInterestRateModel ,
BAllowance
{
uint256 public constant BORROW_FEE = 0 .0001e18 ;
event Borrow (
address indexed sender,
address indexed borrower,
address indexed receiver,
uint256 borrowAmount,
uint256 repayAmount,
uint256 accountBorrowsPrior,
uint256 accountBorrows,
uint256 totalBorrows
) ;
event Liquidate (
address indexed sender,
address indexed borrower,
address indexed liquidator,
uint256 seizeTokens,
uint256 repayAmount,
uint256 accountBorrowsPrior,
uint256 accountBorrows,
uint256 totalBorrows
) ;
constructor ( ) public {}
function _update ( ) internal {
super ._update();
_calculateBorrowRate();
}
function _mintReserves (uint256 _exchangeRate, uint256 _totalSupply )
internal
returns (uint256 )
{
uint256 _exchangeRateLast = exchangeRateLast;
if (_exchangeRate > _exchangeRateLast) {
uint256 _exchangeRateNew =
_exchangeRate.sub(
_exchangeRate.sub(_exchangeRateLast).mul(reserveFactor).div(
1e18
)
);
uint256 liquidity =
_totalSupply.mul(_exchangeRate).div(_exchangeRateNew).sub(
_totalSupply
);
if (liquidity > 0 ) {
address reservesManager = IFactory(factory).reservesManager();
_mint(reservesManager, liquidity);
}
exchangeRateLast = _exchangeRateNew;
return _exchangeRateNew;
} else return _exchangeRate;
}
function exchangeRate ( ) public accrue returns (uint256 ) {
uint256 _totalSupply = totalSupply;
uint256 _actualBalance = totalBalance.add(totalBorrows);
if (_totalSupply = = 0 | | _actualBalance = = 0 )
return initialExchangeRate;
uint256 _exchangeRate = _actualBalance.mul(1e18 ).div(_totalSupply);
return _mintReserves(_exchangeRate, _totalSupply);
}
function sync ( ) external nonReentrant update accrue {}
function borrowBalance (address borrower ) public view returns (uint256 ) {
BorrowSnapshot memory borrowSnapshot = borrowBalances[borrower];
if (borrowSnapshot.interestIndex = = 0 ) return 0 ;
return
uint256 (borrowSnapshot.principal).mul(borrowIndex).div(
borrowSnapshot.interestIndex
);
}
function _trackBorrow (
address borrower,
uint256 accountBorrows,
uint256 _borrowIndex
) internal {
address _borrowTracker = borrowTracker;
if (_borrowTracker = = address (0 )) return ;
IBorrowTracker(_borrowTracker).trackBorrow(
borrower,
accountBorrows,
_borrowIndex
);
}
function _updateBorrow (
address borrower,
uint256 borrowAmount,
uint256 repayAmount
)
private
returns (
uint256 accountBorrowsPrior,
uint256 accountBorrows,
uint256 _totalBorrows
)
{
accountBorrowsPrior = borrowBalance(borrower);
if (borrowAmount = = repayAmount)
return (accountBorrowsPrior, accountBorrowsPrior, totalBorrows);
uint112 _borrowIndex = borrowIndex;
if (borrowAmount > repayAmount) {
BorrowSnapshot storage borrowSnapshot = borrowBalances[borrower];
uint256 increaseAmount = borrowAmount - repayAmount;
accountBorrows = accountBorrowsPrior.add(increaseAmount);
borrowSnapshot.principal = safe112(accountBorrows);
borrowSnapshot.interestIndex = _borrowIndex;
_totalBorrows = uint256 (totalBorrows).add(increaseAmount);
totalBorrows = safe112(_totalBorrows);
} else {
BorrowSnapshot storage borrowSnapshot = borrowBalances[borrower];
uint256 decreaseAmount = repayAmount - borrowAmount;
accountBorrows = accountBorrowsPrior > decreaseAmount
? accountBorrowsPrior - decreaseAmount
: 0 ;
borrowSnapshot.principal = safe112(accountBorrows);
if (accountBorrows = = 0 ) {
borrowSnapshot.interestIndex = 0 ;
} else {
borrowSnapshot.interestIndex = _borrowIndex;
}
uint256 actualDecreaseAmount =
accountBorrowsPrior.sub(accountBorrows);
_totalBorrows = totalBorrows;
_totalBorrows = _totalBorrows > actualDecreaseAmount
? _totalBorrows - actualDecreaseAmount
: 0 ;
totalBorrows = safe112(_totalBorrows);
}
_trackBorrow(borrower, accountBorrows, _borrowIndex);
}
function borrow (
address borrower,
address receiver,
uint256 borrowAmount,
bytes calldata data
) external nonReentrant update accrue {
uint256 _totalBalance = totalBalance;
require (borrowAmount < = _totalBalance, "Tarot: INSUFFICIENT_CASH" );
_checkBorrowAllowance(borrower, msg .sender , borrowAmount);
if (borrowAmount > 0 ) _safeTransfer(receiver, borrowAmount);
if (data.length > 0 )
ITarotCallee(receiver).tarotBorrow(
msg .sender ,
borrower,
borrowAmount,
data
);
uint256 balance = IERC20(underlying).balanceOf(address (this ));
uint256 borrowFee = borrowAmount.mul(BORROW_FEE).div(1e18 );
uint256 adjustedBorrowAmount = borrowAmount.add(borrowFee);
uint256 repayAmount = balance.add(borrowAmount).sub(_totalBalance);
(
uint256 accountBorrowsPrior,
uint256 accountBorrows,
uint256 _totalBorrows
) = _updateBorrow(borrower, adjustedBorrowAmount, repayAmount);
if (adjustedBorrowAmount > repayAmount)
require (
ICollateral(collateral).canBorrow(
borrower,
address (this ),
accountBorrows
),
"Tarot: INSUFFICIENT_LIQUIDITY"
);
emit Borrow(
msg .sender ,
borrower,
receiver,
borrowAmount,
repayAmount,
accountBorrowsPrior,
accountBorrows,
_totalBorrows
);
}
function liquidate (address borrower, address liquidator )
external
nonReentrant
update
accrue
returns (uint256 seizeTokens )
{
uint256 balance = IERC20(underlying).balanceOf(address (this ));
uint256 repayAmount = balance.sub(totalBalance);
uint256 actualRepayAmount =
Math.min (borrowBalance(borrower), repayAmount);
seizeTokens = ICollateral(collateral).seize(
liquidator,
borrower,
actualRepayAmount
);
(
uint256 accountBorrowsPrior,
uint256 accountBorrows,
uint256 _totalBorrows
) = _updateBorrow(borrower, 0 , repayAmount);
emit Liquidate(
msg .sender ,
borrower,
liquidator,
seizeTokens,
repayAmount,
accountBorrowsPrior,
accountBorrows,
_totalBorrows
);
}
function trackBorrow (address borrower ) external {
_trackBorrow(borrower, borrowBalance(borrower), borrowIndex);
}
modifier accrue ( ) {
accrueInterest();
_ ;
}
}
File 6 of 16: IBorrowTracker.sol
pragma solidity >=0.5.0;
interface IBorrowTracker {
function trackBorrow (address borrower, uint borrowBalance, uint borrowIndex ) external ;
}File 7 of 16: IBorrowable.sol
pragma solidity >=0.5.0;
interface IBorrowable {
event Transfer (address indexed from , address indexed to, uint256 value ) ;
event Approval (
address indexed owner,
address indexed spender,
uint256 value
) ;
function name ( ) external pure returns (string memory ) ;
function symbol ( ) external pure returns (string memory ) ;
function decimals ( ) external pure returns (uint8 ) ;
function totalSupply ( ) external view returns (uint256 ) ;
function balanceOf (address owner ) external view returns (uint256 ) ;
function allowance (address owner, address spender )
external
view
returns (uint256 ) ;
function approve (address spender, uint256 value ) external returns (bool ) ;
function transfer (address to, uint256 value ) external returns (bool ) ;
function transferFrom (
address from ,
address to,
uint256 value
) external returns (bool ) ;
function DOMAIN_SEPARATOR ( ) external view returns (bytes32 ) ;
function PERMIT_TYPEHASH ( ) external pure returns (bytes32 ) ;
function nonces (address owner ) external view returns (uint256 ) ;
function permit (
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external ;
event Mint (
address indexed sender,
address indexed minter,
uint256 mintAmount,
uint256 mintTokens
) ;
event Redeem (
address indexed sender,
address indexed redeemer,
uint256 redeemAmount,
uint256 redeemTokens
) ;
event Sync (uint256 totalBalance ) ;
function underlying ( ) external view returns (address ) ;
function factory ( ) external view returns (address ) ;
function totalBalance ( ) external view returns (uint256 ) ;
function MINIMUM_LIQUIDITY ( ) external pure returns (uint256 ) ;
function exchangeRate ( ) external returns (uint256 ) ;
function mint (address minter ) external returns (uint256 mintTokens ) ;
function redeem (address redeemer ) external returns (uint256 redeemAmount ) ;
function skim (address to ) external ;
function sync ( ) external ;
function _setFactory ( ) external ;
event BorrowApproval (
address indexed owner,
address indexed spender,
uint256 value
) ;
event Borrow (
address indexed sender,
address indexed borrower,
address indexed receiver,
uint256 borrowAmount,
uint256 repayAmount,
uint256 accountBorrowsPrior,
uint256 accountBorrows,
uint256 totalBorrows
) ;
event Liquidate (
address indexed sender,
address indexed borrower,
address indexed liquidator,
uint256 seizeTokens,
uint256 repayAmount,
uint256 accountBorrowsPrior,
uint256 accountBorrows,
uint256 totalBorrows
) ;
function BORROW_FEE ( ) external pure returns (uint256 ) ;
function collateral ( ) external view returns (address ) ;
function reserveFactor ( ) external view returns (uint256 ) ;
function exchangeRateLast ( ) external view returns (uint256 ) ;
function borrowIndex ( ) external view returns (uint256 ) ;
function totalBorrows ( ) external view returns (uint256 ) ;
function borrowAllowance (address owner, address spender )
external
view
returns (uint256 ) ;
function borrowBalance (address borrower ) external view returns (uint256 ) ;
function borrowTracker ( ) external view returns (address ) ;
function BORROW_PERMIT_TYPEHASH ( ) external pure returns (bytes32 ) ;
function borrowApprove (address spender, uint256 value )
external
returns (bool ) ;
function borrowPermit (
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external ;
function borrow (
address borrower,
address receiver,
uint256 borrowAmount,
bytes calldata data
) external ;
function liquidate (address borrower, address liquidator )
external
returns (uint256 seizeTokens ) ;
function trackBorrow (address borrower ) external ;
event AccrueInterest (
uint256 interestAccumulated,
uint256 borrowIndex,
uint256 totalBorrows
) ;
event CalculateKink (uint256 kinkRate ) ;
event CalculateBorrowRate (uint256 borrowRate ) ;
function KINK_BORROW_RATE_MAX ( ) external pure returns (uint256 ) ;
function KINK_BORROW_RATE_MIN ( ) external pure returns (uint256 ) ;
function KINK_MULTIPLIER ( ) external pure returns (uint256 ) ;
function borrowRate ( ) external view returns (uint256 ) ;
function kinkBorrowRate ( ) external view returns (uint256 ) ;
function kinkUtilizationRate ( ) external view returns (uint256 ) ;
function adjustSpeed ( ) external view returns (uint256 ) ;
function rateUpdateTimestamp ( ) external view returns (uint32 ) ;
function accrualTimestamp ( ) external view returns (uint32 ) ;
function accrueInterest ( ) external ;
event NewReserveFactor (uint256 newReserveFactor ) ;
event NewKinkUtilizationRate (uint256 newKinkUtilizationRate ) ;
event NewAdjustSpeed (uint256 newAdjustSpeed ) ;
event NewBorrowTracker (address newBorrowTracker ) ;
function RESERVE_FACTOR_MAX ( ) external pure returns (uint256 ) ;
function KINK_UR_MIN ( ) external pure returns (uint256 ) ;
function KINK_UR_MAX ( ) external pure returns (uint256 ) ;
function ADJUST_SPEED_MIN ( ) external pure returns (uint256 ) ;
function ADJUST_SPEED_MAX ( ) external pure returns (uint256 ) ;
function _initialize (
string calldata _name,
string calldata _symbol,
address _underlying,
address _collateral
) external ;
function _setReserveFactor (uint256 newReserveFactor ) external ;
function _setKinkUtilizationRate (uint256 newKinkUtilizationRate ) external ;
function _setAdjustSpeed (uint256 newAdjustSpeed ) external ;
function _setBorrowTracker (address newBorrowTracker ) external ;
}
File 8 of 16: ICollateral.sol
pragma solidity >=0.5.0;
interface ICollateral {
event Transfer (address indexed from , address indexed to, uint256 value ) ;
event Approval (
address indexed owner,
address indexed spender,
uint256 value
) ;
function name ( ) external pure returns (string memory ) ;
function symbol ( ) external pure returns (string memory ) ;
function decimals ( ) external pure returns (uint8 ) ;
function totalSupply ( ) external view returns (uint256 ) ;
function balanceOf (address owner ) external view returns (uint256 ) ;
function allowance (address owner, address spender )
external
view
returns (uint256 ) ;
function approve (address spender, uint256 value ) external returns (bool ) ;
function transfer (address to, uint256 value ) external returns (bool ) ;
function transferFrom (
address from ,
address to,
uint256 value
) external returns (bool ) ;
function DOMAIN_SEPARATOR ( ) external view returns (bytes32 ) ;
function PERMIT_TYPEHASH ( ) external pure returns (bytes32 ) ;
function nonces (address owner ) external view returns (uint256 ) ;
function permit (
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external ;
event Mint (
address indexed sender,
address indexed minter,
uint256 mintAmount,
uint256 mintTokens
) ;
event Redeem (
address indexed sender,
address indexed redeemer,
uint256 redeemAmount,
uint256 redeemTokens
) ;
event Sync (uint256 totalBalance ) ;
function underlying ( ) external view returns (address ) ;
function factory ( ) external view returns (address ) ;
function totalBalance ( ) external view returns (uint256 ) ;
function MINIMUM_LIQUIDITY ( ) external pure returns (uint256 ) ;
function exchangeRate ( ) external returns (uint256 ) ;
function mint (address minter ) external returns (uint256 mintTokens ) ;
function redeem (address redeemer ) external returns (uint256 redeemAmount ) ;
function skim (address to ) external ;
function sync ( ) external ;
function _setFactory ( ) external ;
function borrowable0 ( ) external view returns (address ) ;
function borrowable1 ( ) external view returns (address ) ;
function tarotPriceOracle ( ) external view returns (address ) ;
function safetyMarginSqrt ( ) external view returns (uint256 ) ;
function liquidationIncentive ( ) external view returns (uint256 ) ;
function liquidationFee ( ) external view returns (uint256 ) ;
function liquidationPenalty ( ) external view returns (uint256 ) ;
function getPrices ( ) external returns (uint256 price0, uint256 price1 ) ;
function tokensUnlocked (address from , uint256 value )
external
returns (bool ) ;
function accountLiquidityAmounts (
address account,
uint256 amount0,
uint256 amount1
) external returns (uint256 liquidity, uint256 shortfall ) ;
function accountLiquidity (address account )
external
returns (uint256 liquidity, uint256 shortfall ) ;
function canBorrow (
address account,
address borrowable,
uint256 accountBorrows
) external returns (bool ) ;
function seize (
address liquidator,
address borrower,
uint256 repayAmount
) external returns (uint256 seizeTokens ) ;
function flashRedeem (
address redeemer,
uint256 redeemAmount,
bytes calldata data
) external ;
event NewSafetyMargin (uint256 newSafetyMarginSqrt ) ;
event NewLiquidationIncentive (uint256 newLiquidationIncentive ) ;
event NewLiquidationFee (uint256 newLiquidationFee ) ;
function SAFETY_MARGIN_SQRT_MIN ( ) external pure returns (uint256 ) ;
function SAFETY_MARGIN_SQRT_MAX ( ) external pure returns (uint256 ) ;
function LIQUIDATION_INCENTIVE_MIN ( ) external pure returns (uint256 ) ;
function LIQUIDATION_INCENTIVE_MAX ( ) external pure returns (uint256 ) ;
function LIQUIDATION_FEE_MAX ( ) external pure returns (uint256 ) ;
function _initialize (
string calldata _name,
string calldata _symbol,
address _underlying,
address _borrowable0,
address _borrowable1
) external ;
function _setSafetyMarginSqrt (uint256 newSafetyMarginSqrt ) external ;
function _setLiquidationIncentive (uint256 newLiquidationIncentive ) external ;
function _setLiquidationFee (uint256 newLiquidationFee ) external ;
}
File 9 of 16: IERC20.sol
pragma solidity >=0.5.0;
interface IERC20 {
event Approval (address indexed owner, address indexed spender, uint value ) ;
event Transfer (address indexed from , address indexed to, uint value ) ;
function name ( ) external view returns (string memory ) ;
function symbol ( ) external view returns (string memory ) ;
function decimals ( ) external view returns (uint8 ) ;
function totalSupply ( ) external view returns (uint ) ;
function balanceOf (address owner ) external view returns (uint ) ;
function allowance (address owner, address spender ) external view returns (uint ) ;
function approve (address spender, uint value ) external returns (bool ) ;
function transfer (address to, uint value ) external returns (bool ) ;
function transferFrom (address from , address to, uint value ) external returns (bool ) ;
}
File 10 of 16: IFactory.sol
pragma solidity >=0.5.0;
interface IFactory {
event LendingPoolInitialized (address indexed uniswapV2Pair, address indexed token0, address indexed token1,
address collateral, address borrowable0, address borrowable1, uint lendingPoolId ) ;
event NewPendingAdmin (address oldPendingAdmin, address newPendingAdmin ) ;
event NewAdmin (address oldAdmin, address newAdmin ) ;
event NewReservesPendingAdmin (address oldReservesPendingAdmin, address newReservesPendingAdmin ) ;
event NewReservesAdmin (address oldReservesAdmin, address newReservesAdmin ) ;
event NewReservesManager (address oldReservesManager, address newReservesManager ) ;
function admin ( ) external view returns (address ) ;
function pendingAdmin ( ) external view returns (address ) ;
function reservesAdmin ( ) external view returns (address ) ;
function reservesPendingAdmin ( ) external view returns (address ) ;
function reservesManager ( ) external view returns (address ) ;
function getLendingPool (address uniswapV2Pair ) external view returns (
bool initialized,
uint24 lendingPoolId,
address collateral,
address borrowable0,
address borrowable1
) ;
function allLendingPools (uint ) external view returns (address uniswapV2Pair ) ;
function allLendingPoolsLength ( ) external view returns (uint ) ;
function bDeployer ( ) external view returns (address ) ;
function cDeployer ( ) external view returns (address ) ;
function tarotPriceOracle ( ) external view returns (address ) ;
function createCollateral (address uniswapV2Pair ) external returns (address collateral ) ;
function createBorrowable0 (address uniswapV2Pair ) external returns (address borrowable0 ) ;
function createBorrowable1 (address uniswapV2Pair ) external returns (address borrowable1 ) ;
function initializeLendingPool (address uniswapV2Pair ) external ;
function _setPendingAdmin (address newPendingAdmin ) external ;
function _acceptAdmin ( ) external ;
function _setReservesPendingAdmin (address newPendingAdmin ) external ;
function _acceptReservesAdmin ( ) external ;
function _setReservesManager (address newReservesManager ) external ;
}
File 11 of 16: IPoolToken.sol
pragma solidity >=0.5.0;
interface IPoolToken {
event Transfer (address indexed from , address indexed to, uint256 value ) ;
event Approval (
address indexed owner,
address indexed spender,
uint256 value
) ;
function name ( ) external pure returns (string memory ) ;
function symbol ( ) external pure returns (string memory ) ;
function decimals ( ) external pure returns (uint8 ) ;
function totalSupply ( ) external view returns (uint256 ) ;
function balanceOf (address owner ) external view returns (uint256 ) ;
function allowance (address owner, address spender )
external
view
returns (uint256 ) ;
function approve (address spender, uint256 value ) external returns (bool ) ;
function transfer (address to, uint256 value ) external returns (bool ) ;
function transferFrom (
address from ,
address to,
uint256 value
) external returns (bool ) ;
function DOMAIN_SEPARATOR ( ) external view returns (bytes32 ) ;
function PERMIT_TYPEHASH ( ) external pure returns (bytes32 ) ;
function nonces (address owner ) external view returns (uint256 ) ;
function permit (
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external ;
event Mint (
address indexed sender,
address indexed minter,
uint256 mintAmount,
uint256 mintTokens
) ;
event Redeem (
address indexed sender,
address indexed redeemer,
uint256 redeemAmount,
uint256 redeemTokens
) ;
event Sync (uint256 totalBalance ) ;
function underlying ( ) external view returns (address ) ;
function factory ( ) external view returns (address ) ;
function totalBalance ( ) external view returns (uint256 ) ;
function MINIMUM_LIQUIDITY ( ) external pure returns (uint256 ) ;
function exchangeRate ( ) external returns (uint256 ) ;
function mint (address minter ) external returns (uint256 mintTokens ) ;
function redeem (address redeemer ) external returns (uint256 redeemAmount ) ;
function skim (address to ) external ;
function sync ( ) external ;
function _setFactory ( ) external ;
}
File 12 of 16: ITarotCallee.sol
pragma solidity >=0.5.0;
interface ITarotCallee {
function tarotBorrow (
address sender,
address borrower,
uint256 borrowAmount,
bytes calldata data
) external ;
function tarotRedeem (
address sender,
uint256 redeemAmount,
bytes calldata data
) external ;
}
File 13 of 16: Math.sol
pragma solidity =0.5.16;
library Math {
function min (uint x, uint y ) internal pure returns (uint z ) {
z = x < y ? x : y;
}
function sqrt (uint y ) internal pure returns (uint z ) {
if (y > 3 ) {
z = y;
uint x = y / 2 + 1 ;
while (x < z) {
z = x;
x = (y / x + x) / 2 ;
}
} else if (y ! = 0 ) {
z = 1 ;
}
}
}
File 14 of 16: PoolToken.sol
pragma solidity =0.5.16;
import "./TarotERC20.sol" ;
import "./interfaces/IERC20.sol" ;
import "./interfaces/IPoolToken.sol" ;
import "./libraries/SafeMath.sol" ;
contract PoolToken is IPoolToken , TarotERC20 {
uint256 internal constant initialExchangeRate = 1e18 ;
address public underlying;
address public factory;
uint256 public totalBalance;
uint256 public constant MINIMUM_LIQUIDITY = 1000 ;
event Mint (
address indexed sender,
address indexed minter,
uint256 mintAmount,
uint256 mintTokens
) ;
event Redeem (
address indexed sender,
address indexed redeemer,
uint256 redeemAmount,
uint256 redeemTokens
) ;
event Sync (uint256 totalBalance ) ;
function _setFactory ( ) external {
require (factory = = address (0 ), "Tarot: FACTORY_ALREADY_SET" );
factory = msg .sender ;
}
function _update ( ) internal {
totalBalance = IERC20(underlying).balanceOf(address (this ));
emit Sync(totalBalance);
}
function exchangeRate ( ) public returns (uint256 ) {
uint256 _totalSupply = totalSupply;
uint256 _totalBalance = totalBalance;
if (_totalSupply = = 0 | | _totalBalance = = 0 ) return initialExchangeRate;
return _totalBalance.mul(1e18 ).div(_totalSupply);
}
function mint (address minter )
external
nonReentrant
update
returns (uint256 mintTokens )
{
uint256 balance = IERC20(underlying).balanceOf(address (this ));
uint256 mintAmount = balance.sub(totalBalance);
mintTokens = mintAmount.mul(1e18 ).div(exchangeRate());
if (totalSupply = = 0 ) {
mintTokens = mintTokens.sub(MINIMUM_LIQUIDITY);
_mint(address (0 ), MINIMUM_LIQUIDITY);
}
require (mintTokens > 0 , "Tarot: MINT_AMOUNT_ZERO" );
_mint(minter, mintTokens);
emit Mint(msg .sender , minter, mintAmount, mintTokens);
}
function redeem (address redeemer )
external
nonReentrant
update
returns (uint256 redeemAmount )
{
uint256 redeemTokens = balanceOf[address (this )];
redeemAmount = redeemTokens.mul(exchangeRate()).div(1e18 );
require (redeemAmount > 0 , "Tarot: REDEEM_AMOUNT_ZERO" );
require (redeemAmount < = totalBalance, "Tarot: INSUFFICIENT_CASH" );
_burn(address (this ), redeemTokens);
_safeTransfer(redeemer, redeemAmount);
emit Redeem(msg .sender , redeemer, redeemAmount, redeemTokens);
}
function skim (address to ) external nonReentrant {
_safeTransfer(
to,
IERC20(underlying).balanceOf(address (this )).sub(totalBalance)
);
}
function sync ( ) external nonReentrant update {}
bytes4 private constant SELECTOR =
bytes4 (keccak256 (bytes ("transfer(address,uint256)" )));
function _safeTransfer (address to, uint256 amount ) internal {
(bool success, bytes memory data) =
underlying.call (abi .encodeWithSelector (SELECTOR, to, amount));
require (
success & & (data.length = = 0 | | abi .decode (data, (bool ))),
"Tarot: TRANSFER_FAILED"
);
}
bool internal _notEntered = true ;
modifier nonReentrant ( ) {
require (_notEntered, "Tarot: REENTERED" );
_notEntered = false ;
_ ;
_notEntered = true ;
}
modifier update ( ) {
_ ;
_update();
}
}
File 15 of 16: SafeMath.sol
pragma solidity =0.5.16;
library SafeMath {
function add (uint256 a, uint256 b ) internal pure returns (uint256 ) {
uint256 c = a + b;
require (c > = a, "SafeMath: addition overflow" );
return c;
}
function add (uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256 ) {
uint256 c = a + b;
require (c > = a, errorMessage);
return c;
}
function sub (uint256 a, uint256 b ) internal pure returns (uint256 ) {
return sub(a, b, "SafeMath: subtraction underflow" );
}
function sub (uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256 ) {
require (b < = a, errorMessage);
uint256 c = a - b;
return c;
}
function mul (uint256 a, uint256 b ) internal pure returns (uint256 ) {
if (a = = 0 ) {
return 0 ;
}
uint256 c = a * b;
require (c / a = = b, "SafeMath: multiplication overflow" );
return c;
}
function mul (uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256 ) {
if (a = = 0 ) {
return 0 ;
}
uint256 c = a * b;
require (c / a = = b, errorMessage);
return c;
}
function div (uint256 a, uint256 b ) internal pure returns (uint256 ) {
return div(a, b, "SafeMath: division by zero" );
}
function div (uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256 ) {
require (b > 0 , errorMessage);
uint256 c = a / b;
return c;
}
function mod (uint256 a, uint256 b ) internal pure returns (uint256 ) {
return mod(a, b, "SafeMath: modulo by zero" );
}
function mod (uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256 ) {
require (b ! = 0 , errorMessage);
return a % b;
}
}
File 16 of 16: TarotERC20.sol
pragma solidity =0.5.16;
import "./libraries/SafeMath.sol" ;
contract TarotERC20 {
using SafeMath for uint256 ;
string public name;
string public symbol;
uint8 public decimals = 18 ;
uint256 public totalSupply;
mapping (address = > uint256 ) public balanceOf;
mapping (address = > mapping (address = > uint256 )) public allowance;
bytes32 public DOMAIN_SEPARATOR;
mapping (address = > uint256 ) public nonces;
event Transfer (address indexed from , address indexed to, uint256 value ) ;
event Approval (
address indexed owner,
address indexed spender,
uint256 value
) ;
constructor ( ) public {}
function _setName (string memory _name, string memory _symbol ) internal {
name = _name;
symbol = _symbol;
uint256 chainId;
assembly {
chainId := chainid
}
DOMAIN_SEPARATOR = keccak256 (
abi .encode (
keccak256 (
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
),
keccak256 (bytes (_name)),
keccak256 (bytes ("1" )),
chainId,
address (this )
)
);
}
function _mint (address to, uint256 value ) internal {
totalSupply = totalSupply.add(value);
balanceOf[to] = balanceOf[to].add(value);
emit Transfer(address (0 ), to, value);
}
function _burn (address from , uint256 value ) internal {
balanceOf[from ] = balanceOf[from ].sub(value);
totalSupply = totalSupply.sub(value);
emit Transfer(from , address (0 ), value);
}
function _approve (
address owner,
address spender,
uint256 value
) private {
allowance[owner][spender] = value;
emit Approval(owner, spender, value);
}
function _transfer (
address from ,
address to,
uint256 value
) internal {
balanceOf[from ] = balanceOf[from ].sub(
value,
"Tarot: TRANSFER_TOO_HIGH"
);
balanceOf[to] = balanceOf[to].add(value);
emit Transfer(from , to, value);
}
function approve (address spender, uint256 value ) external returns (bool ) {
_approve(msg .sender , spender, value);
return true ;
}
function transfer (address to, uint256 value ) external returns (bool ) {
_transfer(msg .sender , to, value);
return true ;
}
function transferFrom (
address from ,
address to,
uint256 value
) external returns (bool ) {
if (allowance[from ][msg .sender ] ! = uint256 (-1 )) {
allowance[from ][msg .sender ] = allowance[from ][msg .sender ].sub(
value,
"Tarot: TRANSFER_NOT_ALLOWED"
);
}
_transfer(from , to, value);
return true ;
}
function _checkSignature (
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s,
bytes32 typehash
) internal {
require (deadline > = block .timestamp , "Tarot: EXPIRED" );
bytes32 digest =
keccak256 (
abi .encodePacked (
"\x19\x01" ,
DOMAIN_SEPARATOR,
keccak256 (
abi .encode (
typehash,
owner,
spender,
value,
nonces[owner]+ + ,
deadline
)
)
)
);
address recoveredAddress = ecrecover (digest, v, r, s);
require (
recoveredAddress ! = address (0 ) & & recoveredAddress = = owner,
"Tarot: INVALID_SIGNATURE"
);
}
bytes32 public constant PERMIT_TYPEHASH =
0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9 ;
function permit (
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external {
_checkSignature(
owner,
spender,
value,
deadline,
v,
r,
s,
PERMIT_TYPEHASH
);
_approve(owner, spender, value);
}
}
{
"compilationTarget" : {
"contracts/Borrowable.sol" : "Borrowable"
} ,
"evmVersion" : "istanbul" ,
"libraries" : { } ,
"optimizer" : {
"enabled" : true ,
"runs" : 200
} ,
"remappings" : [ ]
} [{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"interestAccumulated","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"borrowIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalBorrows","type":"uint256"}],"name":"AccrueInterest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"borrowAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"repayAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"accountBorrowsPrior","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"accountBorrows","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalBorrows","type":"uint256"}],"name":"Borrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"BorrowApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"borrowRate","type":"uint256"}],"name":"CalculateBorrowRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"kinkRate","type":"uint256"}],"name":"CalculateKink","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"kinkBorrowRate","type":"uint256"}],"name":"CalculateKinkBorrowRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":true,"internalType":"address","name":"liquidator","type":"address"},{"indexed":false,"internalType":"uint256","name":"seizeTokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"repayAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"accountBorrowsPrior","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"accountBorrows","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalBorrows","type":"uint256"}],"name":"Liquidate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"mintAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintTokens","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newAdjustSpeed","type":"uint256"}],"name":"NewAdjustSpeed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newBorrowTracker","type":"address"}],"name":"NewBorrowTracker","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newKinkUtilizationRate","type":"uint256"}],"name":"NewKinkUtilizationRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newReserveFactor","type":"uint256"}],"name":"NewReserveFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"redeemer","type":"address"},{"indexed":false,"internalType":"uint256","name":"redeemAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"redeemTokens","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalBalance","type":"uint256"}],"name":"Sync","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[],"name":"ADJUST_SPEED_MAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ADJUST_SPEED_MIN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BORROW_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BORROW_PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"KINK_BORROW_RATE_MAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"KINK_BORROW_RATE_MIN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"KINK_MULTIPLIER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"KINK_UR_MAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"KINK_UR_MIN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MINIMUM_LIQUIDITY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"RESERVE_FACTOR_MAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_underlying","type":"address"},{"internalType":"address","name":"_collateral","type":"address"}],"name":"_initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newAdjustSpeed","type":"uint256"}],"name":"_setAdjustSpeed","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newBorrowTracker","type":"address"}],"name":"_setBorrowTracker","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"_setFactory","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newKinkUtilizationRate","type":"uint256"}],"name":"_setKinkUtilizationRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newReserveFactor","type":"uint256"}],"name":"_setReserveFactor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"accrualTimestamp","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"accrueInterest","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"adjustSpeed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"borrower","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"borrowAmount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"borrow","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"borrowAllowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"borrowApprove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"borrower","type":"address"}],"name":"borrowBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"borrowIndex","outputs":[{"internalType":"uint112","name":"","type":"uint112"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"borrowPermit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"borrowRate","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"borrowTracker","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"collateral","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"exchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"exchangeRateLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBlockTimestamp","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kinkBorrowRate","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kinkUtilizationRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"borrower","type":"address"},{"internalType":"address","name":"liquidator","type":"address"}],"name":"liquidate","outputs":[{"internalType":"uint256","name":"seizeTokens","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"mintTokens","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"rateUpdateTimestamp","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"redeemer","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"redeemAmount","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"reserveFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"skim","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"sync","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalBorrows","outputs":[{"internalType":"uint112","name":"","type":"uint112"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"borrower","type":"address"}],"name":"trackBorrow","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"underlying","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]