mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
add liquity connector
This commit is contained in:
parent
ac3421fb61
commit
a1203c66ae
42
contracts/mainnet/connectors/liquity/events.sol
Normal file
42
contracts/mainnet/connectors/liquity/events.sol
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
contract Events {
|
||||||
|
|
||||||
|
/* Trove */
|
||||||
|
event LogOpen(
|
||||||
|
address indexed borrower,
|
||||||
|
uint maxFeePercentage,
|
||||||
|
uint depositAmount,
|
||||||
|
uint borrowAmount,
|
||||||
|
uint getId,
|
||||||
|
uint setId
|
||||||
|
);
|
||||||
|
event LogClose(address indexed borrower, uint setId);
|
||||||
|
event LogDeposit(address indexed borrower, uint amount, uint getId);
|
||||||
|
event LogWithdraw(address indexed borrower, uint amount, uint setId);
|
||||||
|
event LogBorrow(address indexed borrower, uint amount, uint setId);
|
||||||
|
event LogRepay(address indexed borrower, uint amount, uint getId);
|
||||||
|
event LogAdjust(
|
||||||
|
address indexed borrower,
|
||||||
|
uint maxFeePercentage,
|
||||||
|
uint depositAmount,
|
||||||
|
uint withdrawAmount,
|
||||||
|
uint borrowAmount,
|
||||||
|
uint repayAmount,
|
||||||
|
uint getDepositId,
|
||||||
|
uint setWithdrawId,
|
||||||
|
uint getRepayId,
|
||||||
|
uint setBorrowId
|
||||||
|
);
|
||||||
|
event LogClaimCollateralFromRedemption(address indexed borrower);
|
||||||
|
|
||||||
|
/* Stability Pool */
|
||||||
|
event LogStabilityDeposit(address indexed borrower, uint amount, address frontendTag, uint getId);
|
||||||
|
event LogStabilityWithdraw(address indexed borrower, uint amount, uint setId);
|
||||||
|
event LogStabilityMoveEthGainToTrove(address indexed borrower);
|
||||||
|
|
||||||
|
/* Staking */
|
||||||
|
event LogStake(address indexed borrower, uint amount, uint getId);
|
||||||
|
event LogUnstake(address indexed borrower, uint amount, uint setId);
|
||||||
|
event LogClaimGains(address indexed borrower);
|
||||||
|
}
|
6
contracts/mainnet/connectors/liquity/helpers.sol
Normal file
6
contracts/mainnet/connectors/liquity/helpers.sol
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
import { DSMath } from "../../common/math.sol";
|
||||||
|
import { Basic } from "../../common/basic.sol";
|
||||||
|
|
||||||
|
abstract contract Helpers is DSMath, Basic {}
|
60
contracts/mainnet/connectors/liquity/interface.sol
Normal file
60
contracts/mainnet/connectors/liquity/interface.sol
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
interface BorrowerOperationsLike {
|
||||||
|
function openTrove(
|
||||||
|
uint256 _maxFee,
|
||||||
|
uint256 _LUSDAmount,
|
||||||
|
address _upperHint,
|
||||||
|
address _lowerHint
|
||||||
|
) external payable;
|
||||||
|
|
||||||
|
function addColl(address _upperHint, address _lowerHint) external payable;
|
||||||
|
|
||||||
|
function withdrawColl(
|
||||||
|
uint256 _amount,
|
||||||
|
address _upperHint,
|
||||||
|
address _lowerHint
|
||||||
|
) external;
|
||||||
|
|
||||||
|
function withdrawLUSD(
|
||||||
|
uint256 _maxFee,
|
||||||
|
uint256 _amount,
|
||||||
|
address _upperHint,
|
||||||
|
address _lowerHint
|
||||||
|
) external;
|
||||||
|
|
||||||
|
function repayLUSD(
|
||||||
|
uint256 _amount,
|
||||||
|
address _upperHint,
|
||||||
|
address _lowerHint
|
||||||
|
) external;
|
||||||
|
|
||||||
|
function closeTrove() external;
|
||||||
|
|
||||||
|
function adjustTrove(
|
||||||
|
uint256 _maxFee,
|
||||||
|
uint256 _collWithdrawal,
|
||||||
|
uint256 _debtChange,
|
||||||
|
bool isDebtIncrease,
|
||||||
|
address _upperHint,
|
||||||
|
address _lowerHint
|
||||||
|
) external payable;
|
||||||
|
|
||||||
|
function claimCollateral() external;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TroveManagerLike {
|
||||||
|
function getTroveColl(address _borrower) external view returns (uint);
|
||||||
|
function getTroveDebt(address _borrower) external view returns (uint);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface StabilityPoolLike {
|
||||||
|
function provideToSP(uint _amount, address _frontEndTag) external;
|
||||||
|
function withdrawFromSP(uint _amount) external;
|
||||||
|
function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface StakingLike {
|
||||||
|
function stake(uint _LQTYamount) external;
|
||||||
|
function unstake(uint _LQTYamount) external;
|
||||||
|
}
|
347
contracts/mainnet/connectors/liquity/main.sol
Normal file
347
contracts/mainnet/connectors/liquity/main.sol
Normal file
|
@ -0,0 +1,347 @@
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title Liquity.
|
||||||
|
* @dev Lending & Borrowing.
|
||||||
|
*/
|
||||||
|
import "hardhat/console.sol";
|
||||||
|
|
||||||
|
import { BorrowerOperationsLike, TroveManagerLike, StabilityPoolLike, StakingLike } from "./interface.sol";
|
||||||
|
import { Stores } from "../../common/stores.sol";
|
||||||
|
import { Helpers } from "./helpers.sol";
|
||||||
|
import { Events } from "./events.sol";
|
||||||
|
|
||||||
|
abstract contract LiquityResolver is Events, Helpers {
|
||||||
|
BorrowerOperationsLike internal constant borrowerOperations =
|
||||||
|
BorrowerOperationsLike(0x24179CD81c9e782A4096035f7eC97fB8B783e007);
|
||||||
|
TroveManagerLike internal constant troveManager =
|
||||||
|
TroveManagerLike(0xA39739EF8b0231DbFA0DcdA07d7e29faAbCf4bb2);
|
||||||
|
StabilityPoolLike internal constant stabilityPool =
|
||||||
|
StabilityPoolLike(0x66017D22b0f8556afDd19FC67041899Eb65a21bb);
|
||||||
|
StakingLike internal constant staking =
|
||||||
|
StakingLike(0x4f9Fbb3f1E99B56e0Fe2892e623Ed36A76Fc605d);
|
||||||
|
|
||||||
|
struct AdjustTrove {
|
||||||
|
uint maxFeePercentage;
|
||||||
|
uint withdrawAmount;
|
||||||
|
uint depositAmount;
|
||||||
|
uint borrowAmount;
|
||||||
|
uint repayAmount;
|
||||||
|
bool isBorrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
console.log("Liquity Connector contract deployed at", address(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Begin: Trove */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Deposit native ETH and borrow LUSD
|
||||||
|
* @notice Opens a Trove by depositing ETH and borrowing LUSD
|
||||||
|
* @param depositAmount The amount of ETH to deposit
|
||||||
|
* @param maxFeePercentage The maximum borrow fee that this transaction should permit
|
||||||
|
* @param borrowAmount The amount of LUSD to borrow
|
||||||
|
* @param upperHint Address of the Trove near the upper bound of where the user's Trove will now sit in the ordered Trove list
|
||||||
|
* @param lowerHint Address of the Trove near the lower bound of where the user's Trove will now sit in the ordered Trove list
|
||||||
|
* @param getId Optional storage slot to retrieve ETH instead of receiving it from msg.value
|
||||||
|
* @param setId Optional storage slot to store the LUSD borrowed against
|
||||||
|
*/
|
||||||
|
function open(
|
||||||
|
uint depositAmount,
|
||||||
|
uint maxFeePercentage,
|
||||||
|
uint borrowAmount,
|
||||||
|
address upperHint,
|
||||||
|
address lowerHint,
|
||||||
|
uint getId,
|
||||||
|
uint setId
|
||||||
|
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||||
|
// User can either send ETH directly or have it collected from a previous spell
|
||||||
|
depositAmount = getUint(getId, depositAmount);
|
||||||
|
|
||||||
|
borrowerOperations.openTrove{value: depositAmount}(
|
||||||
|
maxFeePercentage,
|
||||||
|
borrowAmount,
|
||||||
|
upperHint,
|
||||||
|
lowerHint
|
||||||
|
);
|
||||||
|
|
||||||
|
// Allow other spells to use the borrowed amount
|
||||||
|
setUint(setId, borrowAmount);
|
||||||
|
_eventName = "LogOpen(address,uint,uint,uint,uint,uint)";
|
||||||
|
_eventParam = abi.encode(msg.sender, maxFeePercentage, depositAmount, borrowAmount, getId, setId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Repay LUSD debt from the DSA account's LUSD balance, and withdraw ETH to DSA
|
||||||
|
* @notice Closes a Trove by repaying LUSD debt
|
||||||
|
* @param setId Optional storage slot to store the ETH withdrawn from the Trove
|
||||||
|
*/
|
||||||
|
function close(uint setId) external returns (string memory _eventName, bytes memory _eventParam) {
|
||||||
|
uint collateral = troveManager.getTroveColl(address(this));
|
||||||
|
borrowerOperations.closeTrove();
|
||||||
|
|
||||||
|
// Allow other spells to use the collateral released from the Trove
|
||||||
|
setUint(setId, collateral);
|
||||||
|
_eventName = "LogClose(address,uint)";
|
||||||
|
_eventParam = abi.encode(msg.sender, setId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Deposit ETH to Trove
|
||||||
|
* @notice Increase Trove collateral (collateral Top up)
|
||||||
|
* @param amount Amount of ETH to deposit into Trove
|
||||||
|
* @param upperHint Address of the Trove near the upper bound of where the user's Trove will now sit in the ordered Trove list
|
||||||
|
* @param lowerHint Address of the Trove near the lower bound of where the user's Trove will now sit in the ordered Trove list
|
||||||
|
* @param getId Optional storage slot to retrieve the ETH from
|
||||||
|
*/
|
||||||
|
function deposit(
|
||||||
|
uint amount,
|
||||||
|
address upperHint,
|
||||||
|
address lowerHint,
|
||||||
|
uint getId
|
||||||
|
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||||
|
amount = getUint(getId, amount);
|
||||||
|
borrowerOperations.addColl{value: amount}(upperHint, lowerHint);
|
||||||
|
_eventName = "LogDeposit(address,uint,uint)";
|
||||||
|
_eventParam = abi.encode(msg.sender, amount, getId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Withdraw ETH from Trove
|
||||||
|
* @notice Move Trove collateral from Trove to DSA
|
||||||
|
* @param amount Amount of ETH to move from Trove to DSA
|
||||||
|
* @param upperHint Address of the Trove near the upper bound of where the user's Trove will now sit in the ordered Trove list
|
||||||
|
* @param lowerHint Address of the Trove near the lower bound of where the user's Trove will now sit in the ordered Trove list
|
||||||
|
* @param setId Optional storage slot to store the withdrawn ETH in
|
||||||
|
*/
|
||||||
|
function withdraw(
|
||||||
|
uint amount,
|
||||||
|
address upperHint,
|
||||||
|
address lowerHint,
|
||||||
|
uint setId
|
||||||
|
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||||
|
borrowerOperations.withdrawColl(amount, upperHint, lowerHint);
|
||||||
|
|
||||||
|
setUint(setId, amount);
|
||||||
|
_eventName = "LogWithdraw(address,uint,uint)";
|
||||||
|
_eventParam = abi.encode(msg.sender, amount, setId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Mints LUSD tokens
|
||||||
|
* @notice Borrow LUSD via an existing Trove
|
||||||
|
* @param maxFeePercentage The maximum borrow fee that this transaction should permit
|
||||||
|
* @param amount Amount of LUSD to borrow
|
||||||
|
* @param upperHint Address of the Trove near the upper bound of where the user's Trove will now sit in the ordered Trove list
|
||||||
|
* @param lowerHint Address of the Trove near the lower bound of where the user's Trove will now sit in the ordered Trove list
|
||||||
|
* @param setId Optional storage slot to store the borrowed LUSD in
|
||||||
|
*/
|
||||||
|
function borrow(
|
||||||
|
uint maxFeePercentage,
|
||||||
|
uint amount,
|
||||||
|
address upperHint,
|
||||||
|
address lowerHint,
|
||||||
|
uint setId
|
||||||
|
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||||
|
borrowerOperations.withdrawLUSD(maxFeePercentage, amount, upperHint, lowerHint);
|
||||||
|
|
||||||
|
setUint(setId, amount); // TODO: apply fee / get exact amount borrowed (with the fee applied)
|
||||||
|
_eventName = "LogBorrow(address,uint,uint)";
|
||||||
|
_eventParam = abi.encode(msg.sender, amount, setId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Send LUSD to repay debt
|
||||||
|
* @notice Repay LUSD Trove debt
|
||||||
|
* @param amount Amount of LUSD to repay
|
||||||
|
* @param upperHint Address of the Trove near the upper bound of where the user's Trove will now sit in the ordered Trove list
|
||||||
|
* @param lowerHint Address of the Trove near the lower bound of where the user's Trove will now sit in the ordered Trove list
|
||||||
|
* @param getId Optional storage slot to retrieve the LUSD from
|
||||||
|
*/
|
||||||
|
function repay(
|
||||||
|
uint amount,
|
||||||
|
address upperHint,
|
||||||
|
address lowerHint,
|
||||||
|
uint getId
|
||||||
|
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||||
|
amount = getUint(getId, amount);
|
||||||
|
borrowerOperations.repayLUSD(amount, upperHint, lowerHint);
|
||||||
|
_eventName = "LogRepay(address,uint,uint)";
|
||||||
|
_eventParam = abi.encode(msg.sender, amount, getId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Increase or decrease Trove ETH collateral and LUSD debt in one transaction
|
||||||
|
* @notice Adjust Trove debt and/or collateral
|
||||||
|
* @param maxFeePercentage The maximum borrow fee that this transaction should permit
|
||||||
|
* @param withdrawAmount Amount of ETH to withdraw
|
||||||
|
* @param depositAmount Amount of ETH to deposit
|
||||||
|
* @param borrowAmount Amount of LUSD to borrow
|
||||||
|
* @param repayAmount Amount of LUSD to repay
|
||||||
|
* @param upperHint Address of the Trove near the upper bound of where the user's Trove will now sit in the ordered Trove list
|
||||||
|
* @param lowerHint Address of the Trove near the lower bound of where the user's Trove will now sit in the ordered Trove list
|
||||||
|
* @param getDepositId Optional storage slot to retrieve the ETH to deposit
|
||||||
|
* @param setWithdrawId Optional storage slot to store the withdrawn ETH to
|
||||||
|
* @param getRepayId Optional storage slot to retrieve the LUSD to repay
|
||||||
|
* @param setBorrowId Optional storage slot to store the LUSD borrowed
|
||||||
|
*/
|
||||||
|
function adjust(
|
||||||
|
uint maxFeePercentage,
|
||||||
|
uint withdrawAmount,
|
||||||
|
uint depositAmount,
|
||||||
|
uint borrowAmount,
|
||||||
|
uint repayAmount,
|
||||||
|
address upperHint,
|
||||||
|
address lowerHint,
|
||||||
|
uint getDepositId,
|
||||||
|
uint setWithdrawId,
|
||||||
|
uint getRepayId,
|
||||||
|
uint setBorrowId
|
||||||
|
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||||
|
AdjustTrove memory adjustTrove;
|
||||||
|
|
||||||
|
adjustTrove.maxFeePercentage = maxFeePercentage;
|
||||||
|
adjustTrove.withdrawAmount = withdrawAmount;
|
||||||
|
adjustTrove.depositAmount = getUint(getDepositId, depositAmount);
|
||||||
|
adjustTrove.borrowAmount = borrowAmount;
|
||||||
|
adjustTrove.repayAmount = getUint(getRepayId, repayAmount);
|
||||||
|
adjustTrove.isBorrow = borrowAmount > 0;
|
||||||
|
|
||||||
|
borrowerOperations.adjustTrove{value: depositAmount}(
|
||||||
|
adjustTrove.maxFeePercentage,
|
||||||
|
adjustTrove.withdrawAmount,
|
||||||
|
adjustTrove.borrowAmount,
|
||||||
|
adjustTrove.isBorrow,
|
||||||
|
upperHint,
|
||||||
|
lowerHint
|
||||||
|
);
|
||||||
|
|
||||||
|
// Allow other spells to use the withdrawn collateral
|
||||||
|
setUint(setWithdrawId, withdrawAmount);
|
||||||
|
|
||||||
|
// Allow other spells to use the borrowed amount
|
||||||
|
setUint(setBorrowId, borrowAmount);
|
||||||
|
|
||||||
|
_eventName = "LogAdjust(address,uint,uint,uint,uint,uint,uint,uint,uint,uint)";
|
||||||
|
_eventParam = abi.encode(msg.sender, maxFeePercentage, depositAmount, borrowAmount, getDepositId, setWithdrawId, getRepayId, setBorrowId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Withdraw remaining ETH balance from user's redeemed Trove to their DSA
|
||||||
|
* @notice Claim remaining collateral from Trove
|
||||||
|
*/
|
||||||
|
function claimCollateralFromRedemption() external returns(string memory _eventName, bytes memory _eventParam) {
|
||||||
|
borrowerOperations.claimCollateral();
|
||||||
|
_eventName = "LogClaimCollateralFromRedemption(address)";
|
||||||
|
_eventParam = abi.encode(msg.sender);
|
||||||
|
}
|
||||||
|
/* End: Trove */
|
||||||
|
|
||||||
|
/* Begin: Stability Pool */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Deposit LUSD into Stability Pool
|
||||||
|
* @notice Deposit LUSD into Stability Pool
|
||||||
|
* @param amount Amount of LUSD to deposit into Stability Pool
|
||||||
|
* @param frontendTag Address of the frontend to make this deposit against (determines the kickback rate of rewards)
|
||||||
|
* @param getId Optional storage slot to retrieve the LUSD from
|
||||||
|
*/
|
||||||
|
function stabilityDeposit(
|
||||||
|
uint amount,
|
||||||
|
address frontendTag,
|
||||||
|
uint getId
|
||||||
|
) external returns (string memory _eventName, bytes memory _eventParam) {
|
||||||
|
amount = getUint(getId, amount);
|
||||||
|
|
||||||
|
stabilityPool.provideToSP(amount, frontendTag);
|
||||||
|
|
||||||
|
_eventName = "LogStabilityDeposit(address,uint,address,uint)";
|
||||||
|
_eventParam = abi.encode(msg.sender, amount, frontendTag, getId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Withdraw user deposited LUSD from Stability Pool
|
||||||
|
* @notice Withdraw LUSD from Stability Pool
|
||||||
|
* @param amount Amount of LUSD to withdraw from Stability Pool
|
||||||
|
* @param setId Optional storage slot to store the withdrawn LUSD
|
||||||
|
*/
|
||||||
|
function stabilityWithdraw(
|
||||||
|
uint amount,
|
||||||
|
uint setId
|
||||||
|
) external returns (string memory _eventName, bytes memory _eventParam) {
|
||||||
|
stabilityPool.withdrawFromSP(amount);
|
||||||
|
setUint(setId, amount);
|
||||||
|
|
||||||
|
_eventName = "LogStabilityWithdraw(address,uint,uint)";
|
||||||
|
_eventParam = abi.encode(msg.sender, amount, setId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Increase Trove collateral by sending Stability Pool ETH gain to user's Trove
|
||||||
|
* @notice Moves user's ETH gain from the Stability Pool into their Trove
|
||||||
|
* @param upperHint Address of the Trove near the upper bound of where the user's Trove will now sit in the ordered Trove list
|
||||||
|
* @param lowerHint Address of the Trove near the lower bound of where the user's Trove will now sit in the ordered Trove list
|
||||||
|
*/
|
||||||
|
function stabilityMoveEthGainToTrove(
|
||||||
|
address upperHint,
|
||||||
|
address lowerHint
|
||||||
|
) external returns (string memory _eventName, bytes memory _eventParam) {
|
||||||
|
stabilityPool.withdrawETHGainToTrove(upperHint, lowerHint);
|
||||||
|
|
||||||
|
_eventName = "LogStabilityMoveEthGainToTrove(address)";
|
||||||
|
_eventParam = abi.encode(msg.sender);
|
||||||
|
}
|
||||||
|
/* End: Stability Pool */
|
||||||
|
|
||||||
|
/* Begin: Staking */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Sends LQTY tokens from user to Staking Pool
|
||||||
|
* @notice Stake LQTY in Staking Pool
|
||||||
|
* @param amount Amount of LQTY to stake
|
||||||
|
* @param getId Optional storage slot to retrieve the LQTY from
|
||||||
|
*/
|
||||||
|
function stake(
|
||||||
|
uint amount,
|
||||||
|
uint getId
|
||||||
|
) external returns (string memory _eventName, bytes memory _eventParam) {
|
||||||
|
amount = getUint(getId, amount);
|
||||||
|
staking.stake(amount);
|
||||||
|
_eventName = "LogStake(address,uint,uint)";
|
||||||
|
_eventParam = abi.encode(msg.sender, amount, getId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Sends LQTY tokens from Staking Pool to user
|
||||||
|
* @notice Unstake LQTY in Staking Pool
|
||||||
|
* @param amount Amount of LQTY to unstake
|
||||||
|
* @param setId Optional storage slot to store the unstaked LQTY
|
||||||
|
*/
|
||||||
|
function unstake(
|
||||||
|
uint amount,
|
||||||
|
uint setId
|
||||||
|
) external returns (string memory _eventName, bytes memory _eventParam) {
|
||||||
|
staking.unstake(amount);
|
||||||
|
setUint(setId, amount);
|
||||||
|
_eventName = "LogUnstake(address,uint,uint)";
|
||||||
|
_eventParam = abi.encode(msg.sender, amount, setId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Sends ETH and LUSD gains from Staking to user
|
||||||
|
* @notice Claim ETH and LUSD gains from Staking
|
||||||
|
*/
|
||||||
|
function claimGains() external returns (string memory _eventName, bytes memory _eventParam) {
|
||||||
|
// claims are gained when a user's stake is adjusted, so we unstake 0 to trigger the claim
|
||||||
|
staking.unstake(0);
|
||||||
|
_eventName = "LogClaimGains(address)";
|
||||||
|
_eventParam = abi.encode(msg.sender);
|
||||||
|
}
|
||||||
|
/* End: Staking */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
contract ConnectV2Liquity is LiquityResolver {
|
||||||
|
string public name = "Liquity-v1";
|
||||||
|
}
|
|
@ -1,12 +1,11 @@
|
||||||
|
|
||||||
require("@nomiclabs/hardhat-waffle");
|
require("@nomiclabs/hardhat-waffle");
|
||||||
require("@nomiclabs/hardhat-ethers");
|
require("@nomiclabs/hardhat-ethers");
|
||||||
require("@tenderly/hardhat-tenderly");
|
require("@tenderly/hardhat-tenderly");
|
||||||
require("@nomiclabs/hardhat-etherscan");
|
require("@nomiclabs/hardhat-etherscan");
|
||||||
require("@nomiclabs/hardhat-web3")
|
require("@nomiclabs/hardhat-web3");
|
||||||
require("hardhat-deploy");
|
require("hardhat-deploy");
|
||||||
require("hardhat-deploy-ethers");
|
require("hardhat-deploy-ethers");
|
||||||
require('dotenv').config();
|
require("dotenv").config();
|
||||||
|
|
||||||
const { utils } = require("ethers");
|
const { utils } = require("ethers");
|
||||||
|
|
||||||
|
@ -20,30 +19,30 @@ module.exports = {
|
||||||
solidity: {
|
solidity: {
|
||||||
compilers: [
|
compilers: [
|
||||||
{
|
{
|
||||||
version: "0.7.6"
|
version: "0.7.6",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
version: "0.6.0"
|
version: "0.6.0",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
version: "0.6.2"
|
version: "0.6.2",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
version: "0.6.5"
|
version: "0.6.5",
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
networks: {
|
networks: {
|
||||||
// defaultNetwork: "hardhat",
|
// defaultNetwork: "hardhat",
|
||||||
kovan: {
|
kovan: {
|
||||||
url: `https://eth-kovan.alchemyapi.io/v2/${ALCHEMY_ID}`,
|
url: `https://eth-kovan.alchemyapi.io/v2/${ALCHEMY_ID}`,
|
||||||
accounts: [`0x${PRIVATE_KEY}`]
|
accounts: [`0x${PRIVATE_KEY}`],
|
||||||
},
|
},
|
||||||
mainnet: {
|
mainnet: {
|
||||||
url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_ID}`,
|
url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_ID}`,
|
||||||
accounts: [`0x${PRIVATE_KEY}`],
|
accounts: [`0x${PRIVATE_KEY}`],
|
||||||
timeout: 150000,
|
timeout: 150000,
|
||||||
gasPrice: parseInt(utils.parseUnits("132", "gwei"))
|
gasPrice: parseInt(utils.parseUnits("132", "gwei")),
|
||||||
},
|
},
|
||||||
hardhat: {
|
hardhat: {
|
||||||
forking: {
|
forking: {
|
||||||
|
@ -56,14 +55,14 @@ module.exports = {
|
||||||
url: "https://rpc-mainnet.maticvigil.com/",
|
url: "https://rpc-mainnet.maticvigil.com/",
|
||||||
accounts: [`0x${PRIVATE_KEY}`],
|
accounts: [`0x${PRIVATE_KEY}`],
|
||||||
timeout: 150000,
|
timeout: 150000,
|
||||||
gasPrice: parseInt(utils.parseUnits("1", "gwei"))
|
gasPrice: parseInt(utils.parseUnits("1", "gwei")),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
etherscan: {
|
etherscan: {
|
||||||
apiKey: process.env.ETHERSCAN_API_KEY
|
apiKey: process.env.ETHERSCAN_API_KEY,
|
||||||
},
|
},
|
||||||
tenderly: {
|
tenderly: {
|
||||||
project: process.env.TENDERLY_PROJECT,
|
project: process.env.TENDERLY_PROJECT,
|
||||||
username: process.env.TENDERLY_USERNAME,
|
username: process.env.TENDERLY_USERNAME,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
core: {
|
core: {
|
||||||
connectorsV2: require("./abi/core/connectorsV2.json"),
|
connectorsV2: require("./abi/core/connectorsV2.json"),
|
||||||
instaIndex: require("./abi/core/instaIndex.json"),
|
instaIndex: require("./abi/core/instaIndex.json"),
|
||||||
},
|
},
|
||||||
connectors: {
|
connectors: {
|
||||||
basic: require("./abi/connectors/basic.json"),
|
"Basic-v1": require("./abi/connectors/basic.json"),
|
||||||
auth: require("./abi/connectors/auth.json"),
|
basic: require("./abi/connectors/basic.json"),
|
||||||
},
|
auth: require("./abi/connectors/auth.json"),
|
||||||
basic: {
|
},
|
||||||
erc20: require("./abi/basics/erc20.json"),
|
basic: {
|
||||||
},
|
erc20: require("./abi/basics/erc20.json"),
|
||||||
};
|
},
|
||||||
|
};
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
connectors: {
|
connectors: {
|
||||||
basic: "0xe5398f279175962E56fE4c5E0b62dc7208EF36c6",
|
basic: "0xe5398f279175962E56fE4c5E0b62dc7208EF36c6",
|
||||||
auth: "0xd1aff9f2acf800c876c409100d6f39aea93fc3d9",
|
auth: "0xd1aff9f2acf800c876c409100d6f39aea93fc3d9",
|
||||||
},
|
},
|
||||||
core: {
|
core: {
|
||||||
connectorsV2: "0xFE2390DAD597594439f218190fC2De40f9Cf1179",
|
connectorsV2: "0x97b0B3A8bDeFE8cB9563a3c610019Ad10DB8aD11",
|
||||||
instaIndex: "0x2971AdFa57b20E5a416aE5a708A8655A9c74f723"
|
instaIndex: "0x2971AdFa57b20E5a416aE5a708A8655A9c74f723",
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
84
test/liquity/liquity.abi.js
Normal file
84
test/liquity/liquity.abi.js
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
const TROVE_MANAGER_ADDRESS = "0xA39739EF8b0231DbFA0DcdA07d7e29faAbCf4bb2";
|
||||||
|
const TROVE_MANAGER_ABI = [
|
||||||
|
"function getTroveColl(address _borrower) external view returns (uint)",
|
||||||
|
"function getTroveDebt(address _borrower) external view returns (uint)",
|
||||||
|
"function getTroveStatus(address _borrower) external view returns (uint)",
|
||||||
|
"function redeemCollateral(uint _LUSDAmount, address _firstRedemptionHint, address _upperPartialRedemptionHint, address _lowerPartialRedemptionHint, uint _partialRedemptionHintNICR, uint _maxIterations, uint _maxFee) external returns (uint)",
|
||||||
|
"function getNominalICR(address _borrower) external view returns (uint)",
|
||||||
|
"function liquidate(address _borrower) external",
|
||||||
|
"function liquidateTroves(uint _n) external",
|
||||||
|
];
|
||||||
|
|
||||||
|
const BORROWER_OPERATIONS_ADDRESS =
|
||||||
|
"0x24179CD81c9e782A4096035f7eC97fB8B783e007";
|
||||||
|
const BORROWER_OPERATIONS_ABI = [
|
||||||
|
"function openTrove(uint256 _maxFee, uint256 _LUSDAmount, address _upperHint, address _lowerHint) external payable",
|
||||||
|
"function closeTrove() external",
|
||||||
|
];
|
||||||
|
|
||||||
|
const LUSD_TOKEN_ADDRESS = "0x5f98805A4E8be255a32880FDeC7F6728C6568bA0";
|
||||||
|
const LUSD_TOKEN_ABI = [
|
||||||
|
"function transfer(address _to, uint256 _value) public returns (bool success)",
|
||||||
|
"function balanceOf(address account) external view returns (uint256)",
|
||||||
|
"function approve(address spender, uint256 amount) external returns (bool)",
|
||||||
|
];
|
||||||
|
|
||||||
|
const ACTIVE_POOL_ADDRESS = "0xDf9Eb223bAFBE5c5271415C75aeCD68C21fE3D7F";
|
||||||
|
const ACTIVE_POOL_ABI = ["function getLUSDDebt() external view returns (uint)"];
|
||||||
|
|
||||||
|
const PRICE_FEED_ADDRESS = "0x4c517D4e2C851CA76d7eC94B805269Df0f2201De";
|
||||||
|
const PRICE_FEED_ABI = ["function fetchPrice() external returns (uint)"];
|
||||||
|
|
||||||
|
const HINT_HELPERS_ADDRESS = "0xE84251b93D9524E0d2e621Ba7dc7cb3579F997C0";
|
||||||
|
const HINT_HELPERS_ABI = [
|
||||||
|
"function getRedemptionHints(uint _LUSDamount, uint _price, uint _maxIterations) external view returns (address firstRedemptionHint, uint partialRedemptionHintNICR, uint truncatedLUSDamount)",
|
||||||
|
"function getApproxHint(uint _CR, uint _numTrials, uint _inputRandomSeed) view returns (address hintAddress, uint diff, uint latestRandomSeed)",
|
||||||
|
"function computeNominalCR(uint _coll, uint _debt) external pure returns (uint)",
|
||||||
|
];
|
||||||
|
|
||||||
|
const SORTED_TROVES_ADDRESS = "0x8FdD3fbFEb32b28fb73555518f8b361bCeA741A6";
|
||||||
|
const SORTED_TROVES_ABI = [
|
||||||
|
"function findInsertPosition(uint256 _ICR, address _prevId, address _nextId) external view returns (address, address)",
|
||||||
|
"function getLast() external view returns (address)",
|
||||||
|
];
|
||||||
|
|
||||||
|
const STABILITY_POOL_ADDRESS = "0x66017D22b0f8556afDd19FC67041899Eb65a21bb";
|
||||||
|
const STABILITY_POOL_ABI = [
|
||||||
|
"function getCompoundedLUSDDeposit(address _depositor) external view returns (uint)",
|
||||||
|
"function getDepositorETHGain(address _depositor) external view returns (uint)",
|
||||||
|
];
|
||||||
|
|
||||||
|
const STAKING_ADDRESS = "0x4f9Fbb3f1E99B56e0Fe2892e623Ed36A76Fc605d";
|
||||||
|
const STAKING_ABI = [
|
||||||
|
"function stake(uint _LQTYamount) external",
|
||||||
|
"function unstake(uint _LQTYamount) external",
|
||||||
|
];
|
||||||
|
|
||||||
|
const LQTY_TOKEN_ADDRESS = "0x6DEA81C8171D0bA574754EF6F8b412F2Ed88c54D";
|
||||||
|
const LQTY_TOKEN_ABI = [
|
||||||
|
"function balanceOf(address account) external view returns (uint256)",
|
||||||
|
"function transfer(address _to, uint256 _value) public returns (bool success)",
|
||||||
|
];
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
TROVE_MANAGER_ADDRESS,
|
||||||
|
TROVE_MANAGER_ABI,
|
||||||
|
BORROWER_OPERATIONS_ADDRESS,
|
||||||
|
BORROWER_OPERATIONS_ABI,
|
||||||
|
LUSD_TOKEN_ADDRESS,
|
||||||
|
LUSD_TOKEN_ABI,
|
||||||
|
STABILITY_POOL_ADDRESS,
|
||||||
|
STABILITY_POOL_ABI,
|
||||||
|
ACTIVE_POOL_ADDRESS,
|
||||||
|
ACTIVE_POOL_ABI,
|
||||||
|
PRICE_FEED_ADDRESS,
|
||||||
|
PRICE_FEED_ABI,
|
||||||
|
HINT_HELPERS_ADDRESS,
|
||||||
|
HINT_HELPERS_ABI,
|
||||||
|
SORTED_TROVES_ADDRESS,
|
||||||
|
SORTED_TROVES_ABI,
|
||||||
|
STAKING_ADDRESS,
|
||||||
|
STAKING_ABI,
|
||||||
|
LQTY_TOKEN_ADDRESS,
|
||||||
|
LQTY_TOKEN_ABI,
|
||||||
|
};
|
327
test/liquity/liquity.helpers.js
Normal file
327
test/liquity/liquity.helpers.js
Normal file
|
@ -0,0 +1,327 @@
|
||||||
|
const hre = require("hardhat");
|
||||||
|
const hardhatConfig = require("../../hardhat.config");
|
||||||
|
|
||||||
|
// Instadapp deployment and testing helpers
|
||||||
|
const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js");
|
||||||
|
const encodeSpells = require("../../scripts/encodeSpells.js");
|
||||||
|
const getMasterSigner = require("../../scripts/getMasterSigner");
|
||||||
|
|
||||||
|
// Instadapp instadappAddresses/ABIs
|
||||||
|
const instadappAddresses = require("../../scripts/constant/addresses");
|
||||||
|
const instadappAbi = require("../../scripts/constant/abis");
|
||||||
|
|
||||||
|
// Instadapp Liquity Connector artifacts
|
||||||
|
const connectV2LiquityArtifacts = require("../../artifacts/contracts/mainnet/connectors/liquity/main.sol/ConnectV2Liquity.json");
|
||||||
|
const connectV2BasicV1Artifacts = require("../../artifacts/contracts/mainnet/connectors/basic/main.sol/ConnectV2Basic.json");
|
||||||
|
|
||||||
|
const CONNECTOR_NAME = "LIQUITY-v1-TEST";
|
||||||
|
const LUSD_GAS_COMPENSATION = hre.ethers.utils.parseUnits("200", 18); // 200 LUSD gas compensation repaid after loan repayment
|
||||||
|
const BLOCK_NUMBER = 12478159; // Deterministic block number for tests to run against, if you change this, tests will break.
|
||||||
|
const JUSTIN_SUN_ADDRESS = "0x903d12bf2c57a29f32365917c706ce0e1a84cce3"; // LQTY whale address
|
||||||
|
const LIQUIDATABLE_TROVE_ADDRESS = "0xafbeb4cb97f3b08ec2fe07ef0dac15d37013a347"; // Trove which is liquidatable at blockNumber: BLOCK_NUMBER
|
||||||
|
const MAX_GAS = hardhatConfig.networks.hardhat.blockGasLimit; // Maximum gas limit (12000000)
|
||||||
|
|
||||||
|
const openTroveSpell = async (
|
||||||
|
dsa,
|
||||||
|
signer,
|
||||||
|
depositAmount,
|
||||||
|
borrowAmount,
|
||||||
|
upperHint,
|
||||||
|
lowerHint,
|
||||||
|
maxFeePercentage
|
||||||
|
) => {
|
||||||
|
let address = signer.address;
|
||||||
|
if (signer.address === undefined) {
|
||||||
|
address = await signer.getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
const openTroveSpell = {
|
||||||
|
connector: CONNECTOR_NAME,
|
||||||
|
method: "open",
|
||||||
|
args: [
|
||||||
|
depositAmount,
|
||||||
|
maxFeePercentage,
|
||||||
|
borrowAmount,
|
||||||
|
upperHint,
|
||||||
|
lowerHint,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const openTx = await dsa
|
||||||
|
.connect(signer)
|
||||||
|
.cast(...encodeSpells([openTroveSpell]), address, {
|
||||||
|
value: depositAmount,
|
||||||
|
});
|
||||||
|
return await openTx.wait();
|
||||||
|
};
|
||||||
|
|
||||||
|
const createDsaTrove = async (
|
||||||
|
dsa,
|
||||||
|
signer,
|
||||||
|
hintHelpers,
|
||||||
|
sortedTroves,
|
||||||
|
depositAmount = hre.ethers.utils.parseEther("5"),
|
||||||
|
borrowAmount = hre.ethers.utils.parseUnits("2000", 18)
|
||||||
|
) => {
|
||||||
|
const maxFeePercentage = hre.ethers.utils.parseUnits("0.5", 18); // 0.5% max fee
|
||||||
|
const { upperHint, lowerHint } = await getTroveInsertionHints(
|
||||||
|
depositAmount,
|
||||||
|
borrowAmount,
|
||||||
|
hintHelpers,
|
||||||
|
sortedTroves
|
||||||
|
);
|
||||||
|
return await openTroveSpell(
|
||||||
|
dsa,
|
||||||
|
signer,
|
||||||
|
depositAmount,
|
||||||
|
borrowAmount,
|
||||||
|
upperHint,
|
||||||
|
lowerHint,
|
||||||
|
maxFeePercentage
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const sendToken = async (token, amount, from, to) => {
|
||||||
|
await hre.network.provider.request({
|
||||||
|
method: "hardhat_impersonateAccount",
|
||||||
|
params: [from],
|
||||||
|
});
|
||||||
|
const signer = await hre.ethers.provider.getSigner(from);
|
||||||
|
|
||||||
|
return await token.connect(signer).transfer(to, amount);
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetHardhatBlockNumber = async (blockNumber) => {
|
||||||
|
return await hre.network.provider.request({
|
||||||
|
method: "hardhat_reset",
|
||||||
|
params: [
|
||||||
|
{
|
||||||
|
forking: {
|
||||||
|
jsonRpcUrl: hardhatConfig.networks.hardhat.forking.url,
|
||||||
|
blockNumber,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const deployAndConnect = async (contracts, isDebug = false) => {
|
||||||
|
// Pin Liquity tests to a particular block number to create deterministic state (Ether price etc.)
|
||||||
|
await resetHardhatBlockNumber(BLOCK_NUMBER);
|
||||||
|
|
||||||
|
const liquity = {
|
||||||
|
troveManager: null,
|
||||||
|
borrowerOperations: null,
|
||||||
|
stabilityPool: null,
|
||||||
|
lusdToken: null,
|
||||||
|
lqtyToken: null,
|
||||||
|
activePool: null,
|
||||||
|
priceFeed: null,
|
||||||
|
hintHelpers: null,
|
||||||
|
sortedTroves: null,
|
||||||
|
staking: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const masterSigner = await getMasterSigner();
|
||||||
|
const instaConnectorsV2 = await ethers.getContractAt(
|
||||||
|
instadappAbi.core.connectorsV2,
|
||||||
|
instadappAddresses.core.connectorsV2
|
||||||
|
);
|
||||||
|
const connector = await deployAndEnableConnector({
|
||||||
|
connectorName: CONNECTOR_NAME,
|
||||||
|
contractArtifact: connectV2LiquityArtifacts,
|
||||||
|
signer: masterSigner,
|
||||||
|
connectors: instaConnectorsV2,
|
||||||
|
});
|
||||||
|
isDebug &&
|
||||||
|
console.log(`${CONNECTOR_NAME} Connector address`, connector.address);
|
||||||
|
|
||||||
|
const basicConnector = await deployAndEnableConnector({
|
||||||
|
connectorName: "Basic-v1",
|
||||||
|
contractArtifact: connectV2BasicV1Artifacts,
|
||||||
|
signer: masterSigner,
|
||||||
|
connectors: instaConnectorsV2,
|
||||||
|
});
|
||||||
|
isDebug && console.log("Basic-v1 Connector address", basicConnector.address);
|
||||||
|
|
||||||
|
liquity.troveManager = new ethers.Contract(
|
||||||
|
contracts.TROVE_MANAGER_ADDRESS,
|
||||||
|
contracts.TROVE_MANAGER_ABI,
|
||||||
|
ethers.provider
|
||||||
|
);
|
||||||
|
isDebug &&
|
||||||
|
console.log("TroveManager contract address", liquity.troveManager.address);
|
||||||
|
|
||||||
|
liquity.borrowerOperations = new ethers.Contract(
|
||||||
|
contracts.BORROWER_OPERATIONS_ADDRESS,
|
||||||
|
contracts.BORROWER_OPERATIONS_ABI,
|
||||||
|
ethers.provider
|
||||||
|
);
|
||||||
|
isDebug &&
|
||||||
|
console.log(
|
||||||
|
"BorrowerOperations contract address",
|
||||||
|
liquity.borrowerOperations.address
|
||||||
|
);
|
||||||
|
|
||||||
|
liquity.stabilityPool = new ethers.Contract(
|
||||||
|
contracts.STABILITY_POOL_ADDRESS,
|
||||||
|
contracts.STABILITY_POOL_ABI,
|
||||||
|
ethers.provider
|
||||||
|
);
|
||||||
|
isDebug &&
|
||||||
|
console.log(
|
||||||
|
"StabilityPool contract address",
|
||||||
|
liquity.stabilityPool.address
|
||||||
|
);
|
||||||
|
|
||||||
|
liquity.lusdToken = new ethers.Contract(
|
||||||
|
contracts.LUSD_TOKEN_ADDRESS,
|
||||||
|
contracts.LUSD_TOKEN_ABI,
|
||||||
|
ethers.provider
|
||||||
|
);
|
||||||
|
isDebug &&
|
||||||
|
console.log("LusdToken contract address", liquity.lusdToken.address);
|
||||||
|
|
||||||
|
liquity.lqtyToken = new ethers.Contract(
|
||||||
|
contracts.LQTY_TOKEN_ADDRESS,
|
||||||
|
contracts.LQTY_TOKEN_ABI,
|
||||||
|
ethers.provider
|
||||||
|
);
|
||||||
|
isDebug &&
|
||||||
|
console.log("LqtyToken contract address", liquity.lqtyToken.address);
|
||||||
|
|
||||||
|
liquity.activePool = new ethers.Contract(
|
||||||
|
contracts.ACTIVE_POOL_ADDRESS,
|
||||||
|
contracts.ACTIVE_POOL_ABI,
|
||||||
|
ethers.provider
|
||||||
|
);
|
||||||
|
isDebug &&
|
||||||
|
console.log("ActivePool contract address", liquity.activePool.address);
|
||||||
|
|
||||||
|
liquity.priceFeed = new ethers.Contract(
|
||||||
|
contracts.PRICE_FEED_ADDRESS,
|
||||||
|
contracts.PRICE_FEED_ABI,
|
||||||
|
ethers.provider
|
||||||
|
);
|
||||||
|
isDebug &&
|
||||||
|
console.log("PriceFeed contract address", liquity.priceFeed.address);
|
||||||
|
|
||||||
|
liquity.hintHelpers = new ethers.Contract(
|
||||||
|
contracts.HINT_HELPERS_ADDRESS,
|
||||||
|
contracts.HINT_HELPERS_ABI,
|
||||||
|
ethers.provider
|
||||||
|
);
|
||||||
|
isDebug &&
|
||||||
|
console.log("HintHelpers contract address", liquity.hintHelpers.address);
|
||||||
|
|
||||||
|
liquity.sortedTroves = new ethers.Contract(
|
||||||
|
contracts.SORTED_TROVES_ADDRESS,
|
||||||
|
contracts.SORTED_TROVES_ABI,
|
||||||
|
ethers.provider
|
||||||
|
);
|
||||||
|
isDebug &&
|
||||||
|
console.log("SortedTroves contract address", liquity.sortedTroves.address);
|
||||||
|
|
||||||
|
liquity.staking = new ethers.Contract(
|
||||||
|
contracts.STAKING_ADDRESS,
|
||||||
|
contracts.STAKING_ABI,
|
||||||
|
ethers.provider
|
||||||
|
);
|
||||||
|
isDebug && console.log("Staking contract address", liquity.staking.address);
|
||||||
|
|
||||||
|
return liquity;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTroveInsertionHints = async (
|
||||||
|
depositAmount,
|
||||||
|
borrowAmount,
|
||||||
|
hintHelpers,
|
||||||
|
sortedTroves
|
||||||
|
) => {
|
||||||
|
const nominalCR = await hintHelpers.computeNominalCR(
|
||||||
|
depositAmount,
|
||||||
|
borrowAmount
|
||||||
|
);
|
||||||
|
|
||||||
|
const { hintAddress, latestRandomSeed } = await hintHelpers.getApproxHint(
|
||||||
|
nominalCR,
|
||||||
|
50,
|
||||||
|
1298379,
|
||||||
|
{
|
||||||
|
gasLimit: MAX_GAS,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
randomSeed = latestRandomSeed;
|
||||||
|
|
||||||
|
const { 0: upperHint, 1: lowerHint } = await sortedTroves.findInsertPosition(
|
||||||
|
nominalCR,
|
||||||
|
hintAddress,
|
||||||
|
hintAddress,
|
||||||
|
{
|
||||||
|
gasLimit: MAX_GAS,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
upperHint,
|
||||||
|
lowerHint,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
let randomSeed = 4223;
|
||||||
|
|
||||||
|
const getRedemptionHints = async (
|
||||||
|
amount,
|
||||||
|
hintHelpers,
|
||||||
|
sortedTroves,
|
||||||
|
priceFeed
|
||||||
|
) => {
|
||||||
|
const ethPrice = await priceFeed.callStatic.fetchPrice();
|
||||||
|
const [
|
||||||
|
firstRedemptionHint,
|
||||||
|
partialRedemptionHintNicr,
|
||||||
|
] = await hintHelpers.getRedemptionHints(amount, ethPrice, 0);
|
||||||
|
|
||||||
|
const { hintAddress, latestRandomSeed } = await hintHelpers.getApproxHint(
|
||||||
|
partialRedemptionHintNicr,
|
||||||
|
50,
|
||||||
|
randomSeed,
|
||||||
|
{
|
||||||
|
gasLimit: MAX_GAS,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
randomSeed = latestRandomSeed;
|
||||||
|
|
||||||
|
const { 0: upperHint, 1: lowerHint } = await sortedTroves.findInsertPosition(
|
||||||
|
partialRedemptionHintNicr,
|
||||||
|
hintAddress,
|
||||||
|
hintAddress,
|
||||||
|
{
|
||||||
|
gasLimit: MAX_GAS,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
partialRedemptionHintNicr,
|
||||||
|
firstRedemptionHint,
|
||||||
|
upperHint,
|
||||||
|
lowerHint,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
deployAndConnect,
|
||||||
|
createDsaTrove,
|
||||||
|
openTroveSpell,
|
||||||
|
sendToken,
|
||||||
|
CONNECTOR_NAME,
|
||||||
|
LUSD_GAS_COMPENSATION,
|
||||||
|
BLOCK_NUMBER,
|
||||||
|
JUSTIN_SUN_ADDRESS,
|
||||||
|
LIQUIDATABLE_TROVE_ADDRESS,
|
||||||
|
MAX_GAS,
|
||||||
|
resetHardhatBlockNumber,
|
||||||
|
getTroveInsertionHints,
|
||||||
|
getRedemptionHints,
|
||||||
|
};
|
1133
test/liquity/liquity.test.js
Normal file
1133
test/liquity/liquity.test.js
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user