mirror of
https://github.com/Instadapp/Gelato-automations.git
synced 2024-07-29 22:28:07 +00:00
feat: Debt Bridge v1 with Refinancing Algo
This commit is contained in:
parent
c15e756fae
commit
e6a37987b8
|
@ -11,17 +11,21 @@ const GelatoCoreLib = require("@gelatonetwork/core");
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
const INFURA_ID = process.env.INFURA_ID;
|
const INFURA_ID = process.env.INFURA_ID;
|
||||||
assert.ok(INFURA_ID, "no Infura ID in process.env");
|
assert.ok(INFURA_ID, "no Infura ID in process.env");
|
||||||
|
const INSTA_MASTER = "0xb1DC62EC38E6E3857a887210C38418E4A17Da5B2";
|
||||||
|
|
||||||
// ================================= CONFIG =========================================
|
// ================================= CONFIG =========================================
|
||||||
module.exports = {
|
module.exports = {
|
||||||
defaultNetwork: "ganache",
|
defaultNetwork: "ganache",
|
||||||
networks: {
|
networks: {
|
||||||
ganache: {
|
ganache: {
|
||||||
|
timeout: 150000,
|
||||||
// Standard config
|
// Standard config
|
||||||
url: "http://localhost:8545",
|
url: "http://localhost:8545",
|
||||||
fork: `https://mainnet.infura.io/v3/${INFURA_ID}`,
|
fork: `https://mainnet.infura.io/v3/${INFURA_ID}`,
|
||||||
|
unlocked_accounts: [INSTA_MASTER],
|
||||||
// Custom
|
// Custom
|
||||||
GelatoCore: "0x1d681d76ce96E4d70a88A00EBbcfc1E47808d0b8",
|
GelatoCore: "0x1d681d76ce96E4d70a88A00EBbcfc1E47808d0b8",
|
||||||
|
InstaMaster: INSTA_MASTER,
|
||||||
InstaIndex: "0x2971AdFa57b20E5a416aE5a708A8655A9c74f723",
|
InstaIndex: "0x2971AdFa57b20E5a416aE5a708A8655A9c74f723",
|
||||||
InstaList: "0x4c8a1BEb8a87765788946D6B19C6C6355194AbEb",
|
InstaList: "0x4c8a1BEb8a87765788946D6B19C6C6355194AbEb",
|
||||||
InstaConnectors: "0xD6A602C01a023B98Ecfb29Df02FBA380d3B21E0c",
|
InstaConnectors: "0xD6A602C01a023B98Ecfb29Df02FBA380d3B21E0c",
|
||||||
|
@ -31,9 +35,13 @@ module.exports = {
|
||||||
ConnectGelato: "0x37A7009d424951dd5D5F155fA588D9a03C455163",
|
ConnectGelato: "0x37A7009d424951dd5D5F155fA588D9a03C455163",
|
||||||
ConnectMaker: "0xac02030d8a8F49eD04b2f52C394D3F901A10F8A9",
|
ConnectMaker: "0xac02030d8a8F49eD04b2f52C394D3F901A10F8A9",
|
||||||
ConnectCompound: "0x07F81230d73a78f63F0c2A3403AD281b067d28F8",
|
ConnectCompound: "0x07F81230d73a78f63F0c2A3403AD281b067d28F8",
|
||||||
|
ConnectInstaPool: "0xCeF5f3c402d4fef76A038e89a4357176963e1464",
|
||||||
|
MakerResolver: "0x0A7008B38E7015F8C36A49eEbc32513ECA8801E5",
|
||||||
DAI: "0x6b175474e89094c44da98b954eedeac495271d0f",
|
DAI: "0x6b175474e89094c44da98b954eedeac495271d0f",
|
||||||
DAI_UNISWAP: "0x2a1530C4C41db0B0b2bB646CB5Eb1A67b7158667",
|
DAI_UNISWAP: "0x2a1530C4C41db0B0b2bB646CB5Eb1A67b7158667",
|
||||||
CDAI: "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643",
|
CDAI: "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643",
|
||||||
|
DssCdpManager: "0x5ef30b9986345249bc32d8928B7ee64DE9435E39",
|
||||||
|
GetCdps: "0x36a724Bd100c39f0Ea4D3A20F7097eE01A8Ff573",
|
||||||
ProviderModuleDSA: "0x0C25452d20cdFeEd2983fa9b9b9Cf4E81D6f2fE2",
|
ProviderModuleDSA: "0x0C25452d20cdFeEd2983fa9b9b9Cf4E81D6f2fE2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
106
contracts/ConditionMakerVaultIsSafe.sol
Normal file
106
contracts/ConditionMakerVaultIsSafe.sol
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
// "SPDX-License-Identifier: UNLICENSED"
|
||||||
|
pragma solidity 0.6.12;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import {
|
||||||
|
GelatoConditionsStandard
|
||||||
|
} from "@gelatonetwork/core/contracts/conditions/GelatoConditionsStandard.sol";
|
||||||
|
import {GelatoBytes} from "./GelatoBytes.sol";
|
||||||
|
import "./DSMath.sol";
|
||||||
|
|
||||||
|
interface IOracleAggregator {
|
||||||
|
function getMakerTokenPrice(string memory _pair)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (uint256);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IVaultResolver {
|
||||||
|
struct VaultData {
|
||||||
|
uint256 id;
|
||||||
|
address owner;
|
||||||
|
string colType;
|
||||||
|
uint256 collateral;
|
||||||
|
uint256 art;
|
||||||
|
uint256 debt;
|
||||||
|
uint256 liquidatedCol;
|
||||||
|
uint256 borrowRate;
|
||||||
|
uint256 colPrice;
|
||||||
|
uint256 liquidationRatio;
|
||||||
|
address vaultAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVaultById(uint256 id) external view returns (VaultData memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
contract ConditionMakerVaultIsSafe is GelatoConditionsStandard, DSMath {
|
||||||
|
using GelatoBytes for bytes;
|
||||||
|
|
||||||
|
address public oracleAggregator;
|
||||||
|
|
||||||
|
constructor(address _oracleAggregator) public {
|
||||||
|
oracleAggregator = _oracleAggregator;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getConditionData(
|
||||||
|
uint256 _vaultID,
|
||||||
|
string memory _pair,
|
||||||
|
uint256 _unSafeLimit
|
||||||
|
) public pure virtual returns (bytes memory) {
|
||||||
|
return abi.encode(_vaultID, _pair, _unSafeLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ok(
|
||||||
|
uint256,
|
||||||
|
bytes calldata _conditionData,
|
||||||
|
uint256
|
||||||
|
) public view virtual override returns (string memory) {
|
||||||
|
(uint256 vaultID, string memory pair, uint256 unSafeLimit) = abi.decode(
|
||||||
|
_conditionData,
|
||||||
|
(uint256, string, uint256)
|
||||||
|
);
|
||||||
|
|
||||||
|
return _isVaultUnSafe(vaultID, pair, unSafeLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _isVaultUnSafe(
|
||||||
|
uint256 _vaultID,
|
||||||
|
string memory _pair,
|
||||||
|
uint256 _unSafeLimit
|
||||||
|
) internal view returns (string memory) {
|
||||||
|
uint256 latestPriceInRay = _getLatestPrice(_pair);
|
||||||
|
|
||||||
|
IVaultResolver.VaultData memory vault = IVaultResolver(
|
||||||
|
_getVaultResolverAddress()
|
||||||
|
)
|
||||||
|
.getVaultById(_vaultID);
|
||||||
|
uint256 colRatio = _vaultCollaterizationRatio(
|
||||||
|
_wmul(vault.collateral, latestPriceInRay),
|
||||||
|
vault.debt
|
||||||
|
);
|
||||||
|
if (_unSafeLimit > colRatio) {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
return "NotOKMakerVaultIsSafe";
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getVaultResolverAddress() internal pure returns (address) {
|
||||||
|
return 0x0A7008B38E7015F8C36A49eEbc32513ECA8801E5;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _vaultCollaterizationRatio(uint256 _col, uint256 _debt)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
return _wdiv(_col, _debt);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getLatestPrice(string memory _pair)
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
return IOracleAggregator(oracleAggregator).getMakerTokenPrice(_pair);
|
||||||
|
}
|
||||||
|
}
|
506
contracts/ConnectGelatoDebtBridge.sol
Normal file
506
contracts/ConnectGelatoDebtBridge.sol
Normal file
|
@ -0,0 +1,506 @@
|
||||||
|
// "SPDX-License-Identifier: UNLICENSED"
|
||||||
|
pragma solidity 0.6.12;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "./IMemoryInterface.sol";
|
||||||
|
import "./DSMath.sol";
|
||||||
|
|
||||||
|
interface ConnectorInterface {
|
||||||
|
function connectorID() external view returns (uint256 _type, uint256 _id);
|
||||||
|
|
||||||
|
function name() external view returns (string memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OracleAggregator {
|
||||||
|
function getMakerTokenPrice(string memory _pair)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (uint256);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GelatoGasPriceOracle {
|
||||||
|
function latestAnswer() external view returns (int256);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IMakerResolver {
|
||||||
|
struct VaultData {
|
||||||
|
uint256 id;
|
||||||
|
address owner;
|
||||||
|
string colType;
|
||||||
|
uint256 collateral;
|
||||||
|
uint256 art;
|
||||||
|
uint256 debt;
|
||||||
|
uint256 liquidatedCol;
|
||||||
|
uint256 borrowRate;
|
||||||
|
uint256 colPrice;
|
||||||
|
uint256 liquidationRatio;
|
||||||
|
address vaultAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVaultById(uint256 id) external view returns (VaultData memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICompoundResolver {
|
||||||
|
struct CompData {
|
||||||
|
uint256 tokenPriceInEth;
|
||||||
|
uint256 tokenPriceInUsd;
|
||||||
|
uint256 exchangeRateStored;
|
||||||
|
uint256 balanceOfUser;
|
||||||
|
uint256 borrowBalanceStoredUser;
|
||||||
|
uint256 supplyRatePerBlock;
|
||||||
|
uint256 borrowRatePerBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCompoundData(address owner, address[] memory cAddress)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (CompData[] memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IAaveResolver {
|
||||||
|
struct AaveTokenData {
|
||||||
|
uint256 ltv;
|
||||||
|
uint256 threshold;
|
||||||
|
bool usageAsCollEnabled;
|
||||||
|
bool borrowEnabled;
|
||||||
|
bool stableBorrowEnabled;
|
||||||
|
bool isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AaveUserTokenData {
|
||||||
|
uint256 tokenPriceInEth;
|
||||||
|
uint256 tokenPriceInUsd;
|
||||||
|
uint256 supplyBalance;
|
||||||
|
uint256 borrowBalance;
|
||||||
|
uint256 borrowFee;
|
||||||
|
uint256 supplyRate;
|
||||||
|
uint256 borrowRate;
|
||||||
|
uint256 borrowModal;
|
||||||
|
AaveTokenData aaveTokenData;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AaveUserData {
|
||||||
|
uint256 totalSupplyETH;
|
||||||
|
uint256 totalCollateralETH;
|
||||||
|
uint256 totalBorrowsETH;
|
||||||
|
uint256 totalFeesETH;
|
||||||
|
uint256 availableBorrowsETH;
|
||||||
|
uint256 currentLiquidationThreshold;
|
||||||
|
uint256 ltv;
|
||||||
|
uint256 healthFactor;
|
||||||
|
uint256 ethPriceInUsd;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPosition(address user, address[] memory tokens)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (AaveUserTokenData[] memory, AaveUserData memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract contract Helpers is ConnectorInterface, DSMath {
|
||||||
|
uint256 internal _id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Return ethereum address
|
||||||
|
*/
|
||||||
|
function _getAddressETH() internal pure returns (address) {
|
||||||
|
return 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; // ETH Address
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Return Memory Variable Address
|
||||||
|
*/
|
||||||
|
function _getMemoryAddr() internal pure returns (address) {
|
||||||
|
return 0x8a5419CfC711B2343c17a6ABf4B2bAFaBb06957F; // InstaMemory Address
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Set Uint value in InstaMemory Contract.
|
||||||
|
*/
|
||||||
|
function _setUint(uint256 setId, uint256 val) internal {
|
||||||
|
if (setId != 0) IMemoryInterface(_getMemoryAddr()).setUint(setId, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Get Uint value from InstaMemory Contract.
|
||||||
|
*/
|
||||||
|
function _getUint(uint256 getId, uint256 val)
|
||||||
|
internal
|
||||||
|
returns (uint256 returnVal)
|
||||||
|
{
|
||||||
|
returnVal = getId == 0
|
||||||
|
? val
|
||||||
|
: IMemoryInterface(_getMemoryAddr()).getUint(getId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Connector Details
|
||||||
|
*/
|
||||||
|
function connectorID()
|
||||||
|
public
|
||||||
|
view
|
||||||
|
override
|
||||||
|
returns (uint256 _type, uint256 _iD)
|
||||||
|
{
|
||||||
|
(_type, _iD) = (1, _id); // Should put specific value.
|
||||||
|
}
|
||||||
|
|
||||||
|
function _stringToBytes32(string memory str)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes32 result)
|
||||||
|
{
|
||||||
|
require(bytes(str).length != 0, "String-Empty");
|
||||||
|
// solium-disable-next-line security/no-inline-assembly
|
||||||
|
assembly {
|
||||||
|
result := mload(add(str, 32))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract contract ConnectGelatoDebtBridgeHelpers is Helpers {
|
||||||
|
function _getMakerResolver() internal pure returns (address) {
|
||||||
|
return 0x0A7008B38E7015F8C36A49eEbc32513ECA8801E5;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getCompoundResolver() internal pure returns (address) {
|
||||||
|
return 0x1f22D77365d8BFE3b901C33C83C01B584F946617;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getAaveResolver() internal pure returns (address) {
|
||||||
|
return 0xe04Cd009fF68628BC663058dDAA7E5Bf7979BEaF;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getGelatoGasPriceOracle() internal pure returns (address) {
|
||||||
|
return 0x169E633A2D1E6c10dD91238Ba11c4A708dfEF37C;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getGasPrice() internal view returns (uint256) {
|
||||||
|
return
|
||||||
|
uint256(
|
||||||
|
GelatoGasPriceOracle(_getGelatoGasPriceOracle()).latestAnswer()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract contract ConnectGelatoDebtBridgeResolver is
|
||||||
|
ConnectGelatoDebtBridgeHelpers
|
||||||
|
{
|
||||||
|
mapping(address => address) internal _priceFeeds;
|
||||||
|
|
||||||
|
function getMakerVault(uint256 _vaultID)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (IMakerResolver.VaultData memory)
|
||||||
|
{
|
||||||
|
// call maker resolver.
|
||||||
|
return IMakerResolver(_getMakerResolver()).getVaultById(_vaultID);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMakerVaultDebt(uint256 _vaultID) public view returns (uint256) {
|
||||||
|
return getMakerVault(_vaultID).debt;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMakerVaultCollateralBalance(uint256 _vaultID)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
return getMakerVault(_vaultID).collateral;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMakerVaultCollateralType(uint256 _vaultID)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (string memory)
|
||||||
|
{
|
||||||
|
return getMakerVault(_vaultID).colType;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCompoundData(address _owner, address _cAddress)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (ICompoundResolver.CompData memory)
|
||||||
|
{
|
||||||
|
address[] memory cAddressArray;
|
||||||
|
cAddressArray[0] = _cAddress;
|
||||||
|
return
|
||||||
|
ICompoundResolver(_getCompoundResolver()).getCompoundData(
|
||||||
|
_owner,
|
||||||
|
cAddressArray
|
||||||
|
)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCompoundDebt(address _owner, address _cAddress)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
return getCompoundData(_owner, _cAddress).borrowBalanceStoredUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCompoundCollateralBalance(address _owner, address _cAddress)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
return getCompoundData(_owner, _cAddress).balanceOfUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAaveTokenData(address _owner, address _atoken)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (
|
||||||
|
IAaveResolver.AaveUserTokenData memory,
|
||||||
|
IAaveResolver.AaveUserData memory
|
||||||
|
)
|
||||||
|
{
|
||||||
|
address[] memory aTokenArray;
|
||||||
|
aTokenArray[0] = _atoken;
|
||||||
|
(
|
||||||
|
IAaveResolver.AaveUserTokenData[] memory tokensData,
|
||||||
|
IAaveResolver.AaveUserData memory etherUserData
|
||||||
|
) = IAaveResolver(_getAaveResolver()).getPosition(_owner, aTokenArray);
|
||||||
|
return (tokensData[0], etherUserData);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAaveTokenDebt(address _owner, address _atoken)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
(IAaveResolver.AaveUserTokenData memory tokenData, ) = getAaveTokenData(
|
||||||
|
_owner,
|
||||||
|
_atoken
|
||||||
|
);
|
||||||
|
return tokenData.supplyBalance;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAaveTokenCollateralBalance(address _owner, address _atoken)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
(IAaveResolver.AaveUserTokenData memory tokenData, ) = getAaveTokenData(
|
||||||
|
_owner,
|
||||||
|
_atoken
|
||||||
|
);
|
||||||
|
return tokenData.borrowBalance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract ConnectGelatoDebtBridge is ConnectGelatoDebtBridgeResolver {
|
||||||
|
// Constant name must be in capitalized SNAKE_CASE
|
||||||
|
// solhint-disable-next-line
|
||||||
|
string public constant override name = "GelatoDebtBridge-v1.0";
|
||||||
|
uint256 public constant GASLIMIT = 2000000; // To Define
|
||||||
|
address public immutable oracleAggregator;
|
||||||
|
|
||||||
|
constructor(uint256 _iD, address _oracleAggregator) public {
|
||||||
|
_id = _iD;
|
||||||
|
oracleAggregator = _oracleAggregator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice Write in instaMemory the needed values for doing the refinancing between makerDAO and Compound.
|
||||||
|
/// @param _vaultID is the id of the makerDAO vault.
|
||||||
|
/// @param _vaultCollateralizationRatio is the collateralization ratio wanted by the client.
|
||||||
|
/// @param _compPosCollateralizationRatio is the collateralization ratio wanted by the client.
|
||||||
|
/// @param _pair crypto currency pair used (collateral token/ borrowed token).
|
||||||
|
/// @param _getID Id for writting in instaMemory.
|
||||||
|
/// @param _setID Id for loading from instaMemory.
|
||||||
|
function debtBridgeMakerToCompound(
|
||||||
|
uint256 _vaultID,
|
||||||
|
uint256 _vaultCollateralizationRatio, // should be in ray because maker use ray standard
|
||||||
|
uint256 _compPosCollateralizationRatio, // should be in wad because compound use wad standard
|
||||||
|
string memory _pair,
|
||||||
|
uint256 _getID,
|
||||||
|
uint256 _setID
|
||||||
|
) external {
|
||||||
|
(
|
||||||
|
uint256 paybackAmount,
|
||||||
|
uint256 collateralToWithdraw,
|
||||||
|
uint256 fees
|
||||||
|
) = debtBridgeCompute(
|
||||||
|
_vaultID,
|
||||||
|
_vaultCollateralizationRatio,
|
||||||
|
_compPosCollateralizationRatio,
|
||||||
|
_pair
|
||||||
|
);
|
||||||
|
|
||||||
|
_setUint(100, paybackAmount);
|
||||||
|
_setUint(101, paybackAmount); // payback maker
|
||||||
|
_setUint(102, _add(collateralToWithdraw, fees)); // withdraw maker
|
||||||
|
_setUint(103, collateralToWithdraw); // deposit compound
|
||||||
|
_setUint(104, paybackAmount); // borrow compound
|
||||||
|
_setUint(105, fees); // pay the provider
|
||||||
|
}
|
||||||
|
|
||||||
|
// Price Oracle
|
||||||
|
|
||||||
|
function debtBridgeCompute(
|
||||||
|
uint256 _vaultID,
|
||||||
|
uint256 _vaultLiquidationRatio, // should be in ray because maker use ray standard
|
||||||
|
uint256 _compPosLiquidationRatio, // should be in wad because compound use wad standard
|
||||||
|
string memory _pair
|
||||||
|
)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (
|
||||||
|
uint256 paybackAmount,
|
||||||
|
uint256 collateralToWithdraw,
|
||||||
|
uint256 fees
|
||||||
|
)
|
||||||
|
{
|
||||||
|
uint256 latestPrice = _getLatestPrice(_pair);
|
||||||
|
// uint256 fees = mul(GASLIMIT, wmul(_getGasPrice(), latestPrice));
|
||||||
|
fees = _mul(GASLIMIT, _getGasPrice());
|
||||||
|
|
||||||
|
uint256 debt = getMakerVaultDebt(_vaultID);
|
||||||
|
uint256 collateral = _sub(
|
||||||
|
_wmul(getMakerVaultCollateralBalance(_vaultID), latestPrice),
|
||||||
|
fees
|
||||||
|
);
|
||||||
|
|
||||||
|
collateralToWithdraw = _wcollateralToWithdraw(
|
||||||
|
_vaultLiquidationRatio,
|
||||||
|
_compPosLiquidationRatio,
|
||||||
|
collateral,
|
||||||
|
debt,
|
||||||
|
latestPrice
|
||||||
|
);
|
||||||
|
paybackAmount = _wborrowedTokenToPayback(
|
||||||
|
_vaultLiquidationRatio,
|
||||||
|
_compPosLiquidationRatio,
|
||||||
|
collateral,
|
||||||
|
debt
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getLatestPrice(string memory _pair)
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
return OracleAggregator(oracleAggregator).getMakerTokenPrice(_pair);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computation in ray
|
||||||
|
/// @notice return the amount of collateral we need to withdraw during the debt refinancing in ray standard.
|
||||||
|
/// @param _p1LiqRatio the liquidation ratio of protocol 1.
|
||||||
|
/// @param _p2LiqRatio the liquidation ratio of protocol 2.
|
||||||
|
/// @param _col token1 collateral to put on protocol 1.
|
||||||
|
/// @param _bor amount of borrowed token2 on protocol 1.
|
||||||
|
/// @param _colPrice price of the collateral.
|
||||||
|
/// @return collateral to withdraw in ray standard
|
||||||
|
function _rcollateralToWithdraw(
|
||||||
|
uint256 _p1LiqRatio,
|
||||||
|
uint256 _p2LiqRatio,
|
||||||
|
uint256 _col,
|
||||||
|
uint256 _bor,
|
||||||
|
uint256 _colPrice
|
||||||
|
) internal pure returns (uint256) {
|
||||||
|
return
|
||||||
|
_rdiv(
|
||||||
|
_sub(
|
||||||
|
_col,
|
||||||
|
_rdiv(
|
||||||
|
_sub(
|
||||||
|
_rmul(_p1LiqRatio, _col),
|
||||||
|
_rmul(_p1LiqRatio, _rmul(_p2LiqRatio, _bor))
|
||||||
|
),
|
||||||
|
_sub(_p1LiqRatio, _p2LiqRatio)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
_colPrice
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computation in ray
|
||||||
|
/// @notice return the amount of borrowed token we need to payback during the debt refinancing in ray standard.
|
||||||
|
/// @param _p1LiqRatio the liquidation ratio of protocol 1.
|
||||||
|
/// @param _p2LiqRatio the liquidation ratio of protocol 2.
|
||||||
|
/// @param _col token1 collateral to put on protocol 1.
|
||||||
|
/// @param _bor amount of borrowed token2 on protocol 1.
|
||||||
|
/// @return amount of borrowed token to pay back in ray standard
|
||||||
|
function _rborrowedTokenToPayback(
|
||||||
|
uint256 _p1LiqRatio,
|
||||||
|
uint256 _p2LiqRatio,
|
||||||
|
uint256 _col,
|
||||||
|
uint256 _bor
|
||||||
|
) internal pure returns (uint256) {
|
||||||
|
return
|
||||||
|
_sub(
|
||||||
|
_bor,
|
||||||
|
_rmul(
|
||||||
|
_rdiv(1e18, _p1LiqRatio),
|
||||||
|
_rdiv(
|
||||||
|
_sub(
|
||||||
|
_rmul(_p1LiqRatio, _col),
|
||||||
|
_rmul(_p1LiqRatio, _rmul(_p2LiqRatio, _bor))
|
||||||
|
),
|
||||||
|
_sub(_p1LiqRatio, _p2LiqRatio)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computation in wad
|
||||||
|
/// @notice return the amount of collateral we need to withdraw during the debt refinancing in wad standard.
|
||||||
|
/// @param _p1LiqRatio the liquidation ratio of protocol 1.
|
||||||
|
/// @param _p2LiqRatio the liquidation ratio of protocol 2.
|
||||||
|
/// @param _col token1 collateral to put on protocol 1.
|
||||||
|
/// @param _bor amount of borrowed token2 on protocol 1.
|
||||||
|
/// @param _colPrice price of the collateral.
|
||||||
|
/// @return collateral to withdraw in wad standard
|
||||||
|
function _wcollateralToWithdraw(
|
||||||
|
uint256 _p1LiqRatio,
|
||||||
|
uint256 _p2LiqRatio,
|
||||||
|
uint256 _col,
|
||||||
|
uint256 _bor,
|
||||||
|
uint256 _colPrice
|
||||||
|
) internal pure returns (uint256) {
|
||||||
|
return
|
||||||
|
_wdiv(
|
||||||
|
_sub(
|
||||||
|
_col,
|
||||||
|
_wdiv(
|
||||||
|
_sub(
|
||||||
|
_wmul(_p1LiqRatio, _col),
|
||||||
|
_wmul(_p1LiqRatio, _wmul(_p2LiqRatio, _bor))
|
||||||
|
),
|
||||||
|
_sub(_p1LiqRatio, _p2LiqRatio)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
_colPrice
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computation in wad
|
||||||
|
/// @notice return the amount of borrowed token we need to payback during the debt refinancing in wad standard.
|
||||||
|
/// @param _p1LiqRatio the liquidation ratio of protocol 1.
|
||||||
|
/// @param _p2LiqRatio the liquidation ratio of protocol 2.
|
||||||
|
/// @param _col token1 collateral to put on protocol 1.
|
||||||
|
/// @param _bor amount of borrowed token2 on protocol 1.
|
||||||
|
/// @return amount of borrowed token to pay back in wad standard
|
||||||
|
function _wborrowedTokenToPayback(
|
||||||
|
uint256 _p1LiqRatio,
|
||||||
|
uint256 _p2LiqRatio,
|
||||||
|
uint256 _col,
|
||||||
|
uint256 _bor
|
||||||
|
) internal pure returns (uint256) {
|
||||||
|
return
|
||||||
|
_sub(
|
||||||
|
_bor,
|
||||||
|
_wmul(
|
||||||
|
_wdiv(1e18, _p1LiqRatio),
|
||||||
|
_wdiv(
|
||||||
|
_sub(
|
||||||
|
_wmul(_p1LiqRatio, _col),
|
||||||
|
_wmul(_p1LiqRatio, _wmul(_p2LiqRatio, _bor))
|
||||||
|
),
|
||||||
|
_sub(_p1LiqRatio, _p2LiqRatio)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
76
contracts/ConnectGelatoProviderPayment.sol
Normal file
76
contracts/ConnectGelatoProviderPayment.sol
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// "SPDX-License-Identifier: UNLICENSED"
|
||||||
|
pragma solidity 0.6.12;
|
||||||
|
|
||||||
|
import "./IMemoryInterface.sol";
|
||||||
|
import {IERC20} from "@gelatonetwork/core/contracts/external/IERC20.sol";
|
||||||
|
|
||||||
|
interface ConnectorInterface {
|
||||||
|
function connectorID() external view returns (uint256 _type, uint256 _id);
|
||||||
|
|
||||||
|
function name() external view returns (string memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract contract ConnectGelatoProviderPaymentHelper is ConnectorInterface {
|
||||||
|
uint256 internal _id;
|
||||||
|
|
||||||
|
function connectorID()
|
||||||
|
public
|
||||||
|
view
|
||||||
|
override
|
||||||
|
returns (uint256 _type, uint256 _iD)
|
||||||
|
{
|
||||||
|
(_type, _iD) = (1, _id); // Should put specific value.
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getMemoryAddr() internal pure returns (address) {
|
||||||
|
return 0x8a5419CfC711B2343c17a6ABf4B2bAFaBb06957F; // InstaMemory Address
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getUint(uint256 _getId, uint256 _val)
|
||||||
|
internal
|
||||||
|
returns (uint256 returnVal)
|
||||||
|
{
|
||||||
|
returnVal = _getId == 0
|
||||||
|
? _val
|
||||||
|
: IMemoryInterface(_getMemoryAddr()).getUint(_getId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _setUint(uint256 setId, uint256 val) internal {
|
||||||
|
if (setId != 0) IMemoryInterface(_getMemoryAddr()).setUint(setId, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getAddressETH() internal pure returns (address) {
|
||||||
|
return 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; // ETH Address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract ConnectGelatoProviderPayment is ConnectGelatoProviderPaymentHelper {
|
||||||
|
// Constant name must be in capitalized SNAKE_CASE
|
||||||
|
// solhint-disable-next-line
|
||||||
|
string public constant override name = "GelatoProviderPayement-v1.0";
|
||||||
|
|
||||||
|
constructor(uint256 _iD) public {
|
||||||
|
_id = _iD;
|
||||||
|
}
|
||||||
|
|
||||||
|
function payProvider(
|
||||||
|
address _provider,
|
||||||
|
address _token,
|
||||||
|
uint256 _amt,
|
||||||
|
uint256 _getID,
|
||||||
|
uint256 _setID
|
||||||
|
) public {
|
||||||
|
// Desable linter for too long require statement
|
||||||
|
// solhint-disable-next-line
|
||||||
|
require(
|
||||||
|
_provider != address(0x0),
|
||||||
|
"ConnectGelatoProviderPayment.payProvider:INVALIDADDESS."
|
||||||
|
);
|
||||||
|
uint256 amt = _getUint(_getID, _amt);
|
||||||
|
if (_token == _getAddressETH()) {
|
||||||
|
payable(_provider).transfer(amt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
IERC20(_token).transfer(_provider, amt);
|
||||||
|
}
|
||||||
|
}
|
82
contracts/DSMath.sol
Normal file
82
contracts/DSMath.sol
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
// "SPDX-License-Identifier: UNLICENSED"
|
||||||
|
pragma solidity 0.6.12;
|
||||||
|
|
||||||
|
contract DSMath {
|
||||||
|
function _add(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||||
|
require((z = x + y) >= x, "ds-math-_add-overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
function _sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||||
|
require((z = x - y) <= x, "ds-math-_sub-underflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
function _mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||||
|
require(y == 0 || (z = x * y) / y == x, "ds-math-_mul-overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
function _min(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||||
|
return x <= y ? x : y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _max(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||||
|
return x >= y ? x : y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _imin(int256 x, int256 y) internal pure returns (int256 z) {
|
||||||
|
return x <= y ? x : y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _imax(int256 x, int256 y) internal pure returns (int256 z) {
|
||||||
|
return x >= y ? x : y;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint256 internal constant _WAD = 10**18;
|
||||||
|
uint256 internal constant _RAY = 10**27;
|
||||||
|
|
||||||
|
//rounds to zero if x*y < _WAD / 2
|
||||||
|
function _wmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||||
|
z = _add(_mul(x, y), _WAD / 2) / _WAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
//rounds to zero if x*y < _WAD / 2
|
||||||
|
function _rmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||||
|
z = _add(_mul(x, y), _RAY / 2) / _RAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
//rounds to zero if x*y < _WAD / 2
|
||||||
|
function _wdiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||||
|
z = _add(_mul(x, _WAD), y / 2) / y;
|
||||||
|
}
|
||||||
|
|
||||||
|
//rounds to zero if x*y < _RAY / 2
|
||||||
|
function _rdiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||||
|
z = _add(_mul(x, _RAY), y / 2) / y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This famous algorithm is called "exponentiation by squaring"
|
||||||
|
// and calculates x^n with x as fixed-point and n as regular unsigned.
|
||||||
|
//
|
||||||
|
// It's O(log n), instead of O(n) for naive repeated _multiplication.
|
||||||
|
//
|
||||||
|
// These facts are why it works:
|
||||||
|
//
|
||||||
|
// If n is even, then x^n = (x^2)^(n/2).
|
||||||
|
// If n is odd, then x^n = x * x^(n-1),
|
||||||
|
// and applying the equation for even x gives
|
||||||
|
// x^n = x * (x^2)^((n-1) / 2).
|
||||||
|
//
|
||||||
|
// Also, EVM division is flooring and
|
||||||
|
// floor[(n-1) / 2] = floor[n / 2].
|
||||||
|
//
|
||||||
|
function _rpow(uint256 x, uint256 n) internal pure returns (uint256 z) {
|
||||||
|
z = n % 2 != 0 ? x : _RAY;
|
||||||
|
|
||||||
|
for (n /= 2; n != 0; n /= 2) {
|
||||||
|
x = _rmul(x, x);
|
||||||
|
|
||||||
|
if (n % 2 != 0) {
|
||||||
|
z = _rmul(z, x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
contracts/IMemoryInterface.sol
Normal file
8
contracts/IMemoryInterface.sol
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// "SPDX-License-Identifier: UNLICENSED"
|
||||||
|
pragma solidity 0.6.12;
|
||||||
|
|
||||||
|
interface IMemoryInterface {
|
||||||
|
function setUint(uint256 _id, uint256 _val) external;
|
||||||
|
|
||||||
|
function getUint(uint256 _id) external returns (uint256);
|
||||||
|
}
|
56
contracts/OracleAggregator.sol
Normal file
56
contracts/OracleAggregator.sol
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// "SPDX-License-Identifier: UNLICENSED"
|
||||||
|
pragma solidity 0.6.12;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import {Ownable} from "@gelatonetwork/core/contracts/external/Ownable.sol";
|
||||||
|
import "./DSMath.sol";
|
||||||
|
|
||||||
|
interface IMakerPriceFeed {
|
||||||
|
function read() external view returns (bytes32);
|
||||||
|
}
|
||||||
|
|
||||||
|
contract OracleAggregatorStorage {
|
||||||
|
mapping(string => address) internal _makerOracle;
|
||||||
|
mapping(string => address) internal _compoundOracle;
|
||||||
|
mapping(string => address) internal _chainlinkOracle;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0x729D19f657BD0614b4985Cf1D82531c67569197B for ETH/USD medianizer it return value in wad standard.
|
||||||
|
contract OracleAggregator is OracleAggregatorStorage, Ownable, DSMath {
|
||||||
|
bool public mockMode;
|
||||||
|
uint256 public mockValue;
|
||||||
|
|
||||||
|
constructor() public Ownable() {
|
||||||
|
mockMode = false;
|
||||||
|
mockValue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mock(bool _mockMode, uint256 _mockValue) public onlyOwner {
|
||||||
|
mockMode = _mockMode;
|
||||||
|
mockValue = _mockValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addOracle(string memory _pair, address _oracleAddress)
|
||||||
|
external
|
||||||
|
onlyOwner
|
||||||
|
{
|
||||||
|
// Desable linter for too long require statement
|
||||||
|
// solhint-disable-next-line
|
||||||
|
require(
|
||||||
|
_makerOracle[_pair] == address(0x0),
|
||||||
|
"OracleAggregator.Maker: Oracle already set."
|
||||||
|
);
|
||||||
|
_makerOracle[_pair] = _oracleAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMakerTokenPrice(string memory _pair)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
if (mockMode) {
|
||||||
|
return mockValue;
|
||||||
|
}
|
||||||
|
return uint256(IMakerPriceFeed(_makerOracle[_pair]).read());
|
||||||
|
}
|
||||||
|
}
|
121
contracts/ProviderModuleDSA.sol
Normal file
121
contracts/ProviderModuleDSA.sol
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
// "SPDX-License-Identifier: UNLICENSED"
|
||||||
|
pragma solidity 0.6.12;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import {
|
||||||
|
GelatoProviderModuleStandard
|
||||||
|
} from "@gelatonetwork/core/contracts/provider_modules/GelatoProviderModuleStandard.sol";
|
||||||
|
import {
|
||||||
|
Task
|
||||||
|
} from "@gelatonetwork/core/contracts/gelato_core/interfaces/IGelatoCore.sol";
|
||||||
|
import "./ConnectGelatoProviderPayment.sol";
|
||||||
|
|
||||||
|
/// @dev InstaDapp Index
|
||||||
|
interface IndexInterface {
|
||||||
|
function connectors(uint256 version) external view returns (address);
|
||||||
|
|
||||||
|
function list() external view returns (address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev InstaDapp List
|
||||||
|
interface ListInterface {
|
||||||
|
function accountID(address _account) external view returns (uint64);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev InstaDapp Defi Smart Account wallet
|
||||||
|
interface AccountInterface {
|
||||||
|
function version() external view returns (uint256);
|
||||||
|
|
||||||
|
function isAuth(address user) external view returns (bool);
|
||||||
|
|
||||||
|
function shield() external view returns (bool);
|
||||||
|
|
||||||
|
function cast(
|
||||||
|
address[] calldata _targets,
|
||||||
|
bytes[] calldata _datas,
|
||||||
|
address _origin
|
||||||
|
) external payable returns (bytes32[] memory responses);
|
||||||
|
}
|
||||||
|
|
||||||
|
contract ProviderModuleDSA is GelatoProviderModuleStandard {
|
||||||
|
IndexInterface public immutable index;
|
||||||
|
address public immutable gelatoCore;
|
||||||
|
address public immutable connectGelatoProviderPayment;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
IndexInterface _index,
|
||||||
|
address _gelatoCore,
|
||||||
|
address _connectGelatoProviderPayment
|
||||||
|
) public {
|
||||||
|
index = _index;
|
||||||
|
gelatoCore = _gelatoCore;
|
||||||
|
connectGelatoProviderPayment = _connectGelatoProviderPayment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================= GELATO PROVIDER MODULE STANDARD ================
|
||||||
|
function isProvided(
|
||||||
|
address _userProxy,
|
||||||
|
address,
|
||||||
|
Task calldata _task
|
||||||
|
) external view override returns (string memory) {
|
||||||
|
// Verify InstaDapp account identity
|
||||||
|
if (ListInterface(index.list()).accountID(_userProxy) == 0)
|
||||||
|
return "ProviderModuleDSA.isProvided:InvalidUserProxy";
|
||||||
|
|
||||||
|
// Is GelatoCore authorized
|
||||||
|
if (!AccountInterface(_userProxy).isAuth(gelatoCore))
|
||||||
|
return "ProviderModuleDSA.isProvided:GelatoCoreNotAuth";
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev DS PROXY ONLY ALLOWS DELEGATE CALL for single actions, that's why we also use multisend
|
||||||
|
function execPayload(
|
||||||
|
uint256,
|
||||||
|
address,
|
||||||
|
address _provider,
|
||||||
|
Task calldata _task,
|
||||||
|
uint256
|
||||||
|
) external view override returns (bytes memory payload, bool) {
|
||||||
|
address[] memory targets = new address[](_task.actions.length);
|
||||||
|
for (uint256 i = 0; i < _task.actions.length; i++)
|
||||||
|
targets[i] = _task.actions[i].addr;
|
||||||
|
|
||||||
|
bytes[] memory datas = new bytes[](_task.actions.length);
|
||||||
|
for (uint256 i = 0; i < _task.actions.length; i++) {
|
||||||
|
if (_task.actions[i].addr == connectGelatoProviderPayment) {
|
||||||
|
// input the exact address of the provider
|
||||||
|
datas[i] = _getDelegateCallDataForProviderPaymentConnector(
|
||||||
|
_provider,
|
||||||
|
_task.actions[i].data
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
datas[i] = _task.actions[i].data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = abi.encodeWithSelector(
|
||||||
|
AccountInterface.cast.selector,
|
||||||
|
targets,
|
||||||
|
datas,
|
||||||
|
gelatoCore
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getDelegateCallDataForProviderPaymentConnector(
|
||||||
|
address _provider,
|
||||||
|
bytes calldata _data
|
||||||
|
) internal pure returns (bytes memory) {
|
||||||
|
(, address token, uint256 amt, uint256 getID, uint256 setID) = abi
|
||||||
|
.decode(_data[4:], (address, address, uint256, uint256, uint256));
|
||||||
|
return
|
||||||
|
abi.encodeWithSelector(
|
||||||
|
ConnectGelatoProviderPayment.payProvider.selector,
|
||||||
|
_provider,
|
||||||
|
token,
|
||||||
|
amt,
|
||||||
|
getID,
|
||||||
|
setID
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
359
pre-compiles/CTokenInterface.json
Normal file
359
pre-compiles/CTokenInterface.json
Normal file
|
@ -0,0 +1,359 @@
|
||||||
|
{
|
||||||
|
"contractName": "CTokenInterface",
|
||||||
|
"abi": [
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "_acceptAdmin",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address payable",
|
||||||
|
"name": "newPendingAdmin",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "_setPendingAdmin",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "owner",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "spender",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "allowance",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "spender",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "amount",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "approve",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bool",
|
||||||
|
"name": "",
|
||||||
|
"type": "bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "owner",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "balanceOf",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "owner",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "balanceOfUnderlying",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "account",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "borrowBalanceCurrent",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "account",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "borrowBalanceStored",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "borrowRatePerBlock",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "exchangeRateCurrent",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "exchangeRateStored",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "account",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "getAccountSnapshot",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "getCash",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "liquidator",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "borrower",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "seizeTokens",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "seize",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "supplyRatePerBlock",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "totalBorrowsCurrent",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "dst",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "amount",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "transfer",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bool",
|
||||||
|
"name": "",
|
||||||
|
"type": "bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "src",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "dst",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "amount",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "transferFrom",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bool",
|
||||||
|
"name": "",
|
||||||
|
"type": "bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bytecode": "0x",
|
||||||
|
"deployedBytecode": "0x",
|
||||||
|
"linkReferences": {},
|
||||||
|
"deployedLinkReferences": {}
|
||||||
|
}
|
1323
pre-compiles/ConnectGelato.json
Normal file
1323
pre-compiles/ConnectGelato.json
Normal file
File diff suppressed because one or more lines are too long
443
pre-compiles/ConnectInstaPool.json
Normal file
443
pre-compiles/ConnectInstaPool.json
Normal file
File diff suppressed because one or more lines are too long
257
pre-compiles/DssCdpManager.json
Normal file
257
pre-compiles/DssCdpManager.json
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
{
|
||||||
|
"contractName": "DssCdpManager",
|
||||||
|
"abi": [
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "cdpCan",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "count",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "flux",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "int256",
|
||||||
|
"name": "",
|
||||||
|
"type": "int256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "int256",
|
||||||
|
"name": "",
|
||||||
|
"type": "int256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "frob",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "give",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "ilks",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bytes32",
|
||||||
|
"name": "",
|
||||||
|
"type": "bytes32"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "last",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "move",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bytes32",
|
||||||
|
"name": "",
|
||||||
|
"type": "bytes32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "open",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "owns",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "urns",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "vat",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bytecode": "0x",
|
||||||
|
"deployedBytecode": "0x",
|
||||||
|
"linkReferences": {},
|
||||||
|
"deployedLinkReferences": {}
|
||||||
|
}
|
77
pre-compiles/GetCdps.json
Normal file
77
pre-compiles/GetCdps.json
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
{
|
||||||
|
"contractName": "GetCdps",
|
||||||
|
"abi": [
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "manager",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "guy",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "getCdpsAsc",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256[]",
|
||||||
|
"name": "ids",
|
||||||
|
"type": "uint256[]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address[]",
|
||||||
|
"name": "urns",
|
||||||
|
"type": "address[]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "bytes32[]",
|
||||||
|
"name": "ilks",
|
||||||
|
"type": "bytes32[]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "manager",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "guy",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "getCdpsDesc",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256[]",
|
||||||
|
"name": "ids",
|
||||||
|
"type": "uint256[]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address[]",
|
||||||
|
"name": "urns",
|
||||||
|
"type": "address[]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "bytes32[]",
|
||||||
|
"name": "ilks",
|
||||||
|
"type": "bytes32[]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bytecode": "0x",
|
||||||
|
"deployedBytecode": "0x",
|
||||||
|
"linkReferences": {},
|
||||||
|
"deployedLinkReferences": {}
|
||||||
|
}
|
775
test/2_Debt-Bridge-External-Provider.test.js
Normal file
775
test/2_Debt-Bridge-External-Provider.test.js
Normal file
|
@ -0,0 +1,775 @@
|
||||||
|
const {expect} = require("chai");
|
||||||
|
const bre = require("@nomiclabs/buidler");
|
||||||
|
const {constants} = require("ethers");
|
||||||
|
const {ethers} = bre;
|
||||||
|
const GelatoCoreLib = require("@gelatonetwork/core");
|
||||||
|
|
||||||
|
// #region Contracts ABI
|
||||||
|
|
||||||
|
const InstaIndex = require("../pre-compiles/InstaIndex.json");
|
||||||
|
const InstaList = require("../pre-compiles/InstaList.json");
|
||||||
|
const InstaAccount = require("../pre-compiles/InstaAccount.json");
|
||||||
|
const ConnectGelato = require("../pre-compiles/ConnectGelato.json");
|
||||||
|
const ConnectMaker = require("../pre-compiles/ConnectMaker.json");
|
||||||
|
const ConnectCompound = require("../pre-compiles/ConnectCompound.json");
|
||||||
|
const ConnectInstaPool = require("../pre-compiles/ConnectInstaPool.json");
|
||||||
|
const ConnectAuth = require("../pre-compiles/ConnectAuth.json");
|
||||||
|
const ConnectGelatoDebtBridgeABI = require("../artifacts/ConnectGelatoDebtBridge.json");
|
||||||
|
const ConnectGelatoProviderPaymentABI = require("../artifacts/ConnectGelatoProviderPayment.json");
|
||||||
|
const InstaConnector = require("../pre-compiles/InstaConnectors.json");
|
||||||
|
const DssCdpManager = require("../pre-compiles/DssCdpManager.json");
|
||||||
|
const GetCdps = require("../pre-compiles/GetCdps.json");
|
||||||
|
const IERC20 = require("../pre-compiles/IERC20.json");
|
||||||
|
const CTokenInterface = require("../pre-compiles/CTokenInterface.json");
|
||||||
|
|
||||||
|
const ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
|
||||||
|
const GAS_LIMIT = "4000000";
|
||||||
|
const GAS_PRICE_CEIL = ethers.utils.parseUnits("1000", "gwei");
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
describe("Debt Bridge with External Provider", function () {
|
||||||
|
this.timeout(0);
|
||||||
|
if (bre.network.name !== "ganache") {
|
||||||
|
console.error("Test Suite is meant to be run on ganache only");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wallet to use for local testing
|
||||||
|
let userWallet;
|
||||||
|
let userAddress;
|
||||||
|
let providerWallet;
|
||||||
|
let providerAddress;
|
||||||
|
|
||||||
|
// Deployed instances
|
||||||
|
let connectGelato;
|
||||||
|
let connectMaker;
|
||||||
|
let connectInstaPool;
|
||||||
|
let connectCompound;
|
||||||
|
let instaIndex;
|
||||||
|
let instaList;
|
||||||
|
let dssCdpManager;
|
||||||
|
let getCdps;
|
||||||
|
let daiToken;
|
||||||
|
let gelatoCore;
|
||||||
|
let cDaiToken;
|
||||||
|
let instaMaster;
|
||||||
|
let instaConnectors;
|
||||||
|
|
||||||
|
// Contracts to deploy and use for local testing
|
||||||
|
let conditionMakerVaultIsSafe;
|
||||||
|
let connectGelatoDebtBridge;
|
||||||
|
let connectGelatoProviderPayment;
|
||||||
|
let oracleAggregator;
|
||||||
|
let dsaProviderModule;
|
||||||
|
|
||||||
|
// Creation during test
|
||||||
|
let dsa;
|
||||||
|
let connectedGelatoCore;
|
||||||
|
|
||||||
|
before(async function () {
|
||||||
|
// Get Test Wallet for local testnet
|
||||||
|
[userWallet] = await ethers.getSigners();
|
||||||
|
userAddress = await userWallet.getAddress();
|
||||||
|
|
||||||
|
[, providerWallet] = await ethers.getSigners();
|
||||||
|
providerAddress = await providerWallet.getAddress();
|
||||||
|
|
||||||
|
instaMaster = await ethers.provider.getSigner(
|
||||||
|
bre.network.config.InstaMaster
|
||||||
|
);
|
||||||
|
|
||||||
|
// Ganache default accounts prefilled with 100 ETH
|
||||||
|
expect(await userWallet.getBalance()).to.be.gt(
|
||||||
|
ethers.utils.parseEther("10")
|
||||||
|
);
|
||||||
|
|
||||||
|
// ===== Get Deployed Contract Instance ==================
|
||||||
|
instaIndex = await ethers.getContractAt(
|
||||||
|
InstaIndex.abi,
|
||||||
|
bre.network.config.InstaIndex
|
||||||
|
);
|
||||||
|
instaList = await ethers.getContractAt(
|
||||||
|
InstaList.abi,
|
||||||
|
bre.network.config.InstaList
|
||||||
|
);
|
||||||
|
connectGelato = await ethers.getContractAt(
|
||||||
|
ConnectGelato.abi,
|
||||||
|
bre.network.config.ConnectGelato
|
||||||
|
);
|
||||||
|
connectMaker = await ethers.getContractAt(
|
||||||
|
ConnectMaker.abi,
|
||||||
|
bre.network.config.ConnectMaker
|
||||||
|
);
|
||||||
|
connectInstaPool = await ethers.getContractAt(
|
||||||
|
ConnectInstaPool.abi,
|
||||||
|
bre.network.config.ConnectInstaPool
|
||||||
|
);
|
||||||
|
connectCompound = await ethers.getContractAt(
|
||||||
|
ConnectCompound.abi,
|
||||||
|
bre.network.config.ConnectCompound
|
||||||
|
);
|
||||||
|
dssCdpManager = await ethers.getContractAt(
|
||||||
|
DssCdpManager.abi,
|
||||||
|
bre.network.config.DssCdpManager
|
||||||
|
);
|
||||||
|
getCdps = await ethers.getContractAt(
|
||||||
|
GetCdps.abi,
|
||||||
|
bre.network.config.GetCdps
|
||||||
|
);
|
||||||
|
daiToken = await ethers.getContractAt(IERC20.abi, bre.network.config.DAI);
|
||||||
|
gelatoCore = await ethers.getContractAt(
|
||||||
|
GelatoCoreLib.GelatoCore.abi,
|
||||||
|
bre.network.config.GelatoCore
|
||||||
|
);
|
||||||
|
cDaiToken = await ethers.getContractAt(
|
||||||
|
CTokenInterface.abi,
|
||||||
|
bre.network.config.CDAI
|
||||||
|
);
|
||||||
|
instaConnectors = await ethers.getContractAt(
|
||||||
|
InstaConnector.abi,
|
||||||
|
bre.network.config.InstaConnectors
|
||||||
|
);
|
||||||
|
// instaEvent = await ethers.getContractAt(
|
||||||
|
// InstaEvent.abi,
|
||||||
|
// bre.network.config.InstaEvent
|
||||||
|
// )
|
||||||
|
|
||||||
|
// ===== Deploy Needed Contract ==================
|
||||||
|
|
||||||
|
const OracleAggregator = await ethers.getContractFactory(
|
||||||
|
"OracleAggregator"
|
||||||
|
);
|
||||||
|
oracleAggregator = await OracleAggregator.deploy();
|
||||||
|
await oracleAggregator.deployed();
|
||||||
|
|
||||||
|
const ConditionMakerVaultIsSafe = await ethers.getContractFactory(
|
||||||
|
"ConditionMakerVaultIsSafe"
|
||||||
|
);
|
||||||
|
conditionMakerVaultIsSafe = await ConditionMakerVaultIsSafe.deploy(
|
||||||
|
oracleAggregator.address
|
||||||
|
);
|
||||||
|
await conditionMakerVaultIsSafe.deployed();
|
||||||
|
|
||||||
|
const connectorLength = await instaConnectors.connectorLength();
|
||||||
|
const connectorId = connectorLength.add(1);
|
||||||
|
|
||||||
|
const ConnectGelatoDebtBridge = await ethers.getContractFactory(
|
||||||
|
"ConnectGelatoDebtBridge"
|
||||||
|
);
|
||||||
|
connectGelatoDebtBridge = await ConnectGelatoDebtBridge.deploy(
|
||||||
|
connectorId,
|
||||||
|
oracleAggregator.address
|
||||||
|
);
|
||||||
|
await connectGelatoDebtBridge.deployed();
|
||||||
|
|
||||||
|
const ConnectGelatoProviderPayment = await ethers.getContractFactory(
|
||||||
|
"ConnectGelatoProviderPayment"
|
||||||
|
);
|
||||||
|
connectGelatoProviderPayment = await ConnectGelatoProviderPayment.deploy(
|
||||||
|
connectorId.add(1)
|
||||||
|
);
|
||||||
|
await connectGelatoProviderPayment.deployed();
|
||||||
|
|
||||||
|
const ProviderModuleDSA = await ethers.getContractFactory(
|
||||||
|
"ProviderModuleDSA"
|
||||||
|
);
|
||||||
|
dsaProviderModule = await ProviderModuleDSA.deploy(
|
||||||
|
bre.network.config.InstaIndex,
|
||||||
|
bre.network.config.GelatoCore,
|
||||||
|
connectGelatoProviderPayment.address
|
||||||
|
);
|
||||||
|
await dsaProviderModule.deployed();
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////// After Contracts Deployement : Setup ///////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Gelato Testing environment setup.
|
||||||
|
// Step 1 : Add EUR/USD Maker Medianizer in the Oracle Aggregator
|
||||||
|
// Step 2 : Enable Debt Bridge Connector and Gelato Provider Payment Connector
|
||||||
|
// Step 3 : Executor Staking on Gelato
|
||||||
|
// Step 4 : Provider put some fund on gelato for paying future tasks executions
|
||||||
|
// Step 5 : Provider choose a executor
|
||||||
|
// Step 6 : Provider will add a module
|
||||||
|
// Step 7 : Provider should whitelist task
|
||||||
|
|
||||||
|
//#region Step 1 Add EUR/USD Maker Medianizer in the Oracle Aggregator
|
||||||
|
|
||||||
|
// Oracle Aggregator is a price feeder aggregator
|
||||||
|
// You will be able to query price from multiple source through this aggregator
|
||||||
|
// For the demo we add the ETH/USD Medianizer to the aggregator
|
||||||
|
// MakerDAO price oracle are called Medianizer
|
||||||
|
|
||||||
|
await oracleAggregator.addOracle(
|
||||||
|
"ETH/USD",
|
||||||
|
"0x729D19f657BD0614b4985Cf1D82531c67569197B"
|
||||||
|
);
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region Step 2 Enable Debt Bridge Connector and Gelato Provider Payment Connector
|
||||||
|
|
||||||
|
// Debt Bridge Connector is used during refinancing of debt
|
||||||
|
// This Connect help the user to split a position in one protocol.
|
||||||
|
// to 2 protocol in a safe way. Both debt position will be safe.
|
||||||
|
|
||||||
|
// Gelato Provider Payment Connector is used for paying the provider
|
||||||
|
// for task execution. So when futur task will be executed, through a self financing
|
||||||
|
// transaction (user will pay during the execution of the task) task will
|
||||||
|
// be executed. Improvind user experience.
|
||||||
|
|
||||||
|
await userWallet.sendTransaction({
|
||||||
|
to: bre.network.config.InstaMaster,
|
||||||
|
value: ethers.utils.parseEther("0.1"),
|
||||||
|
});
|
||||||
|
await instaConnectors
|
||||||
|
.connect(instaMaster)
|
||||||
|
.enable(connectGelatoDebtBridge.address);
|
||||||
|
await instaConnectors
|
||||||
|
.connect(instaMaster)
|
||||||
|
.enable(connectGelatoProviderPayment.address);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await instaConnectors.isConnector([connectGelatoDebtBridge.address])
|
||||||
|
).to.be.true;
|
||||||
|
expect(
|
||||||
|
await instaConnectors.isConnector([connectGelatoProviderPayment.address])
|
||||||
|
).to.be.true;
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region Step 3 Executor Staking on Gelato
|
||||||
|
|
||||||
|
// For task execution provider will ask a executor to watch the
|
||||||
|
// blockchain for possible execution autorization given by
|
||||||
|
// the condition that user choose when submitting the task.
|
||||||
|
// And if all condition are meet executor will execute the task.
|
||||||
|
// For safety measure Gelato ask the executor to stake a minimum
|
||||||
|
// amount.
|
||||||
|
|
||||||
|
connectedGelatoCore = gelatoCore.connect(providerWallet);
|
||||||
|
gelatoCore = gelatoCore.connect(userWallet);
|
||||||
|
await connectedGelatoCore.stakeExecutor({
|
||||||
|
from: providerAddress,
|
||||||
|
value: await connectedGelatoCore.minExecutorStake(),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await connectedGelatoCore.isExecutorMinStaked(providerAddress)
|
||||||
|
).to.be.true;
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region Step 4 Provider put some fund on gelato for paying future tasks executions
|
||||||
|
|
||||||
|
// Provider put some funds in gelato system for paying the
|
||||||
|
// Executor when this one will execute task on behalf of the
|
||||||
|
// Provider. At each provider's task execution, some funds (approximatively
|
||||||
|
// the gas cost value) will be transfered to the Executor stake.
|
||||||
|
|
||||||
|
const TASK_AUTOMATION_FUNDS = await gelatoCore.minExecProviderFunds(
|
||||||
|
GAS_LIMIT,
|
||||||
|
GAS_PRICE_CEIL
|
||||||
|
);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
connectedGelatoCore.provideFunds(providerAddress, {
|
||||||
|
value: TASK_AUTOMATION_FUNDS,
|
||||||
|
})
|
||||||
|
).to.emit(gelatoCore, "LogFundsProvided");
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await connectedGelatoCore.providerFunds(providerAddress)
|
||||||
|
).to.be.equal(TASK_AUTOMATION_FUNDS);
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region Step 5 Provider choose a executor
|
||||||
|
|
||||||
|
// Provider choose a executor who will execute futur task
|
||||||
|
// for the provider, it will be compensated by the provider.
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
connectedGelatoCore.providerAssignsExecutor(providerAddress)
|
||||||
|
).to.emit(gelatoCore, "LogProviderAssignedExecutor");
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await connectedGelatoCore.executorByProvider(providerAddress)
|
||||||
|
).to.be.equal(providerAddress);
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region Step 6 Provider will add a module
|
||||||
|
|
||||||
|
// By adding a module the provider will format future task's
|
||||||
|
// payload by adding some specificity like his address to the
|
||||||
|
// Payment connector for receiving payment of User.
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
connectedGelatoCore.addProviderModules([dsaProviderModule.address])
|
||||||
|
).to.emit(gelatoCore, "LogProviderModuleAdded");
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await connectedGelatoCore.isModuleProvided(
|
||||||
|
providerAddress,
|
||||||
|
dsaProviderModule.address
|
||||||
|
)
|
||||||
|
).to.be.true;
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region Step 7 Provider should whitelist task
|
||||||
|
|
||||||
|
// By WhiteList task, the provider can constrain the type
|
||||||
|
// of task the user can submitting.
|
||||||
|
|
||||||
|
//#region Actions
|
||||||
|
|
||||||
|
const spells = [];
|
||||||
|
|
||||||
|
let debtBridge = new GelatoCoreLib.Action({
|
||||||
|
addr: connectGelatoDebtBridge.address,
|
||||||
|
data: constants.HashZero,
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
dataFlow: GelatoCoreLib.DataFlow.None,
|
||||||
|
termsOkCheck: false,
|
||||||
|
value: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(debtBridge);
|
||||||
|
|
||||||
|
let flashBorrow = new GelatoCoreLib.Action({
|
||||||
|
addr: connectInstaPool.address,
|
||||||
|
data: constants.HashZero,
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
dataFlow: GelatoCoreLib.DataFlow.None,
|
||||||
|
termsOkCheck: false,
|
||||||
|
value: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(flashBorrow);
|
||||||
|
|
||||||
|
let paybackMaker = new GelatoCoreLib.Action({
|
||||||
|
addr: connectMaker.address,
|
||||||
|
data: constants.HashZero,
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
dataFlow: GelatoCoreLib.DataFlow.None,
|
||||||
|
termsOkCheck: false,
|
||||||
|
value: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(paybackMaker);
|
||||||
|
|
||||||
|
let withdrawMaker = new GelatoCoreLib.Action({
|
||||||
|
addr: connectMaker.address,
|
||||||
|
data: constants.HashZero,
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
dataFlow: GelatoCoreLib.DataFlow.None,
|
||||||
|
termsOkCheck: false,
|
||||||
|
value: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(withdrawMaker);
|
||||||
|
|
||||||
|
let depositCompound = new GelatoCoreLib.Action({
|
||||||
|
addr: connectCompound.address,
|
||||||
|
data: constants.HashZero,
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
dataFlow: GelatoCoreLib.DataFlow.None,
|
||||||
|
termsOkCheck: false,
|
||||||
|
value: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(depositCompound);
|
||||||
|
|
||||||
|
let borrowCompound = new GelatoCoreLib.Action({
|
||||||
|
addr: connectCompound.address,
|
||||||
|
data: constants.HashZero,
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
dataFlow: GelatoCoreLib.DataFlow.None,
|
||||||
|
termsOkCheck: false,
|
||||||
|
value: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(borrowCompound);
|
||||||
|
|
||||||
|
let flashPayBack = new GelatoCoreLib.Action({
|
||||||
|
addr: connectInstaPool.address,
|
||||||
|
data: constants.HashZero,
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
dataFlow: GelatoCoreLib.DataFlow.None,
|
||||||
|
termsOkCheck: false,
|
||||||
|
value: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(flashPayBack);
|
||||||
|
|
||||||
|
let payProvider = new GelatoCoreLib.Action({
|
||||||
|
addr: connectGelatoProviderPayment.address,
|
||||||
|
data: constants.HashZero,
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
dataFlow: GelatoCoreLib.DataFlow.None,
|
||||||
|
termsOkCheck: false,
|
||||||
|
value: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(payProvider);
|
||||||
|
|
||||||
|
const gasPriceCeil = constants.MaxUint256;
|
||||||
|
|
||||||
|
const gelatoFlashLoanTaskSpec = new GelatoCoreLib.TaskSpec({
|
||||||
|
conditions: [conditionMakerVaultIsSafe.address],
|
||||||
|
actions: spells,
|
||||||
|
gasPriceCeil,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
connectedGelatoCore.provideTaskSpecs([gelatoFlashLoanTaskSpec])
|
||||||
|
).to.emit(gelatoCore, "LogTaskSpecProvided");
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await connectedGelatoCore.isTaskSpecProvided(
|
||||||
|
providerAddress,
|
||||||
|
gelatoFlashLoanTaskSpec
|
||||||
|
)
|
||||||
|
).to.be.equal("OK");
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await connectedGelatoCore.taskSpecGasPriceCeil(
|
||||||
|
providerAddress,
|
||||||
|
await connectedGelatoCore.hashTaskSpec(gelatoFlashLoanTaskSpec)
|
||||||
|
)
|
||||||
|
).to.be.equal(gasPriceCeil);
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Use Maker Compound refinancing if the maker vault become unsafe after a market move.", async function () {
|
||||||
|
// User Actions
|
||||||
|
// Step 1 : User create a DeFi Smart Account
|
||||||
|
// Step 2 : User open a Vault, put some ether on it and borrow some dai
|
||||||
|
// Step 3 : User give authorization to gelato to use his DSA on his behalf.
|
||||||
|
// Step 4 : User submit a Debt Refinancing task if market move against him
|
||||||
|
// Step 5 : Market Move against the user (Mock)
|
||||||
|
// Step 6 : Executor execute the user's task
|
||||||
|
|
||||||
|
//#region Step 1 User create a DeFi Smart Account
|
||||||
|
|
||||||
|
// User create a Instadapp DeFi Smart Account
|
||||||
|
// who give him the possibility to interact
|
||||||
|
// with a large list of DeFi protocol through one
|
||||||
|
// Proxy account.
|
||||||
|
|
||||||
|
const dsaAccountCount = await instaList.accounts();
|
||||||
|
|
||||||
|
await expect(instaIndex.build(userAddress, 1, userAddress)).to.emit(
|
||||||
|
instaIndex,
|
||||||
|
"LogAccountCreated"
|
||||||
|
);
|
||||||
|
const dsaID = dsaAccountCount.add(1);
|
||||||
|
await expect(await instaList.accounts()).to.be.equal(dsaID);
|
||||||
|
|
||||||
|
// Instantiate the DSA
|
||||||
|
dsa = await ethers.getContractAt(
|
||||||
|
InstaAccount.abi,
|
||||||
|
await instaList.accountAddr(dsaID)
|
||||||
|
);
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region Step 2 User open a Vault, put some ether on it and borrow some dai
|
||||||
|
|
||||||
|
// User open a maker vault
|
||||||
|
// He deposit 10 Eth on it
|
||||||
|
// He borrow a 1000 DAI
|
||||||
|
|
||||||
|
const openVault = await bre.run("abi-encode-withselector", {
|
||||||
|
abi: ConnectMaker.abi,
|
||||||
|
functionname: "open",
|
||||||
|
inputs: ["ETH-A"],
|
||||||
|
});
|
||||||
|
|
||||||
|
await dsa.cast([bre.network.config.ConnectMaker], [openVault], userAddress);
|
||||||
|
|
||||||
|
let cdps = await getCdps.getCdpsAsc(dssCdpManager.address, dsa.address);
|
||||||
|
let cdpId = String(cdps.ids[0]);
|
||||||
|
|
||||||
|
expect(cdps.ids[0].isZero()).to.be.false;
|
||||||
|
|
||||||
|
await dsa.cast(
|
||||||
|
[bre.network.config.ConnectMaker],
|
||||||
|
[
|
||||||
|
await bre.run("abi-encode-withselector", {
|
||||||
|
abi: ConnectMaker.abi,
|
||||||
|
functionname: "deposit",
|
||||||
|
inputs: [cdpId, ethers.utils.parseEther("10"), 0, 0],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
userAddress,
|
||||||
|
{
|
||||||
|
value: ethers.utils.parseEther("10"),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await dsa.cast(
|
||||||
|
[bre.network.config.ConnectMaker],
|
||||||
|
[
|
||||||
|
await bre.run("abi-encode-withselector", {
|
||||||
|
abi: ConnectMaker.abi,
|
||||||
|
functionname: "borrow",
|
||||||
|
inputs: [cdpId, ethers.utils.parseUnits("1000", 18), 0, 0],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
userAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(await daiToken.balanceOf(dsa.address)).to.be.equal(
|
||||||
|
ethers.utils.parseEther("1000")
|
||||||
|
);
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region Step 3 User give authorization to gelato to use his DSA on his behalf.
|
||||||
|
|
||||||
|
// Instadapp DSA contract give the possibility to the user to delegate
|
||||||
|
// action by giving authorization.
|
||||||
|
// In this case user give authorization to gelato to execute
|
||||||
|
// task for him if needed.
|
||||||
|
|
||||||
|
await dsa.cast(
|
||||||
|
[bre.network.config.ConnectAuth],
|
||||||
|
[
|
||||||
|
await bre.run("abi-encode-withselector", {
|
||||||
|
abi: ConnectAuth.abi,
|
||||||
|
functionname: "add",
|
||||||
|
inputs: [gelatoCore.address],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
userAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(await dsa.isAuth(gelatoCore.address)).to.be.true;
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region Step 4 User submit a Debt Refinancing task if market move against him
|
||||||
|
|
||||||
|
// User submit the refinancing task if market move against him.
|
||||||
|
// So in this case if the maker vault go to the unsafe area
|
||||||
|
// the refinancing task will be executed and the position
|
||||||
|
// will be split on two position on maker and compound.
|
||||||
|
// It will be done through a algorithm that will optimize the
|
||||||
|
// total borrow rate.
|
||||||
|
|
||||||
|
const debtBridgeCondition = new GelatoCoreLib.Condition({
|
||||||
|
inst: conditionMakerVaultIsSafe.address,
|
||||||
|
data: await conditionMakerVaultIsSafe.getConditionData(
|
||||||
|
cdpId,
|
||||||
|
"ETH/USD",
|
||||||
|
ethers.utils.parseUnits("3", 18)
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
// ======= Action/Spells setup ======
|
||||||
|
const spells = [];
|
||||||
|
|
||||||
|
let debtBridgeCalculation = new GelatoCoreLib.Action({
|
||||||
|
addr: connectGelatoDebtBridge.address,
|
||||||
|
data: await bre.run("abi-encode-withselector", {
|
||||||
|
abi: ConnectGelatoDebtBridgeABI.abi,
|
||||||
|
functionname: "debtBridgeMakerToCompound",
|
||||||
|
inputs: [
|
||||||
|
cdpId,
|
||||||
|
ethers.utils.parseUnits("3", 18),
|
||||||
|
ethers.utils.parseUnits("18", 17),
|
||||||
|
"ETH/USD",
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(debtBridgeCalculation);
|
||||||
|
|
||||||
|
let flashBorrow = new GelatoCoreLib.Action({
|
||||||
|
addr: connectInstaPool.address,
|
||||||
|
data: await bre.run("abi-encode-withselector", {
|
||||||
|
abi: ConnectInstaPool.abi,
|
||||||
|
functionname: "flashBorrow",
|
||||||
|
inputs: [bre.network.config.DAI, 0, "100", 0],
|
||||||
|
}),
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(flashBorrow);
|
||||||
|
|
||||||
|
let paybackMaker = new GelatoCoreLib.Action({
|
||||||
|
addr: connectMaker.address,
|
||||||
|
data: await bre.run("abi-encode-withselector", {
|
||||||
|
abi: ConnectMaker.abi,
|
||||||
|
functionname: "payback",
|
||||||
|
inputs: [cdpId, 0, "101", 0],
|
||||||
|
}),
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(paybackMaker);
|
||||||
|
|
||||||
|
let withdrawMaker = new GelatoCoreLib.Action({
|
||||||
|
addr: connectMaker.address,
|
||||||
|
data: await bre.run("abi-encode-withselector", {
|
||||||
|
abi: ConnectMaker.abi,
|
||||||
|
functionname: "withdraw",
|
||||||
|
inputs: [cdpId, 0, "102", 0],
|
||||||
|
}),
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(withdrawMaker);
|
||||||
|
|
||||||
|
let depositCompound = new GelatoCoreLib.Action({
|
||||||
|
addr: connectCompound.address,
|
||||||
|
data: await bre.run("abi-encode-withselector", {
|
||||||
|
abi: ConnectCompound.abi,
|
||||||
|
functionname: "deposit",
|
||||||
|
inputs: [ETH, 0, "103", 0],
|
||||||
|
}),
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(depositCompound);
|
||||||
|
|
||||||
|
let borrowCompound = new GelatoCoreLib.Action({
|
||||||
|
addr: connectCompound.address,
|
||||||
|
data: await bre.run("abi-encode-withselector", {
|
||||||
|
abi: ConnectCompound.abi,
|
||||||
|
functionname: "borrow",
|
||||||
|
inputs: [bre.network.config.DAI, 0, "104", 0],
|
||||||
|
}),
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(borrowCompound);
|
||||||
|
|
||||||
|
let flashPayBack = new GelatoCoreLib.Action({
|
||||||
|
addr: connectInstaPool.address,
|
||||||
|
data: await bre.run("abi-encode-withselector", {
|
||||||
|
abi: ConnectInstaPool.abi,
|
||||||
|
functionname: "flashPayback",
|
||||||
|
inputs: [bre.network.config.DAI, 0, 0],
|
||||||
|
}),
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(flashPayBack);
|
||||||
|
|
||||||
|
let payProvider = new GelatoCoreLib.Action({
|
||||||
|
addr: connectGelatoProviderPayment.address,
|
||||||
|
data: await bre.run("abi-encode-withselector", {
|
||||||
|
abi: ConnectGelatoProviderPaymentABI.abi,
|
||||||
|
functionname: "payProvider",
|
||||||
|
inputs: [ethers.constants.AddressZero, ETH, 0, "105", 0],
|
||||||
|
}),
|
||||||
|
operation: GelatoCoreLib.Operation.Delegatecall,
|
||||||
|
});
|
||||||
|
|
||||||
|
spells.push(payProvider);
|
||||||
|
|
||||||
|
const refinanceIfCompoundBorrowIsBetter = new GelatoCoreLib.Task({
|
||||||
|
conditions: [debtBridgeCondition],
|
||||||
|
actions: spells,
|
||||||
|
});
|
||||||
|
|
||||||
|
const gelatoExternalProvider = new GelatoCoreLib.GelatoProvider({
|
||||||
|
addr: providerAddress,
|
||||||
|
module: dsaProviderModule.address,
|
||||||
|
});
|
||||||
|
|
||||||
|
const expiryDate = 0;
|
||||||
|
await expect(
|
||||||
|
dsa.cast(
|
||||||
|
[connectGelato.address], // targets
|
||||||
|
[
|
||||||
|
await bre.run("abi-encode-withselector", {
|
||||||
|
abi: ConnectGelato.abi,
|
||||||
|
functionname: "submitTask",
|
||||||
|
inputs: [
|
||||||
|
gelatoExternalProvider,
|
||||||
|
refinanceIfCompoundBorrowIsBetter,
|
||||||
|
expiryDate,
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
], // datas
|
||||||
|
userAddress, // origin
|
||||||
|
{
|
||||||
|
gasLimit: 5000000,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).to.emit(gelatoCore, "LogTaskSubmitted");
|
||||||
|
|
||||||
|
const taskReceipt = new GelatoCoreLib.TaskReceipt({
|
||||||
|
id: await gelatoCore.currentTaskReceiptId(),
|
||||||
|
userProxy: dsa.address,
|
||||||
|
provider: gelatoExternalProvider,
|
||||||
|
tasks: [refinanceIfCompoundBorrowIsBetter],
|
||||||
|
expiryDate,
|
||||||
|
});
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region Step 5 Market Move against the user (Mock)
|
||||||
|
|
||||||
|
// Ether market price went from the current price to 250$
|
||||||
|
|
||||||
|
const gelatoGasPrice = await bre.run("fetchGelatoGasPrice");
|
||||||
|
expect(gelatoGasPrice).to.be.lte(GAS_PRICE_CEIL);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await connectedGelatoCore.canExec(taskReceipt, GAS_LIMIT, gelatoGasPrice)
|
||||||
|
).to.be.equal("ConditionNotOk:NotOKMakerVaultIsSafe");
|
||||||
|
|
||||||
|
await oracleAggregator.mock(true, ethers.utils.parseUnits("250", 18));
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await connectedGelatoCore.canExec(taskReceipt, GAS_LIMIT, gelatoGasPrice)
|
||||||
|
).to.be.equal("OK");
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region Step 6 Executor execute the user's task
|
||||||
|
|
||||||
|
// The market move make the vault unsafe, so the executor
|
||||||
|
// will execute the user's task to make the user position safe
|
||||||
|
// by a debt refinancing in compound.
|
||||||
|
|
||||||
|
let providerBalanceBeforeExecution = await providerWallet.getBalance();
|
||||||
|
await expect(
|
||||||
|
connectedGelatoCore.exec(taskReceipt, {
|
||||||
|
gasPrice: gelatoGasPrice, // Exectutor must use gelatoGasPrice (Chainlink fast gwei)
|
||||||
|
gasLimit: GAS_LIMIT,
|
||||||
|
})
|
||||||
|
).to.emit(gelatoCore, "LogExecSuccess");
|
||||||
|
|
||||||
|
let providerBalanceAfterExecution = await providerWallet.getBalance();
|
||||||
|
expect(providerBalanceAfterExecution).to.be.gt(
|
||||||
|
providerBalanceBeforeExecution
|
||||||
|
);
|
||||||
|
const amtOfBorrowedDAIOnCompound = (
|
||||||
|
await cDaiToken.getAccountSnapshot(dsa.address)
|
||||||
|
)[2];
|
||||||
|
expect(amtOfBorrowedDAIOnCompound).to.be.lt(
|
||||||
|
ethers.utils.parseUnits("1000", 18)
|
||||||
|
); // Check the borrow amount
|
||||||
|
expect(await daiToken.balanceOf(dsa.address)).to.be.equal(
|
||||||
|
ethers.utils.parseUnits("1000", 18)
|
||||||
|
);
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user