IonPool

Git Source

Inherits: PausableUpgradeable, RewardModule

IonPool is the central contract of the Ion Protocol system. All other contracts in the system revolve around it. Directly interacting with IonPool may be unintuitive and it is recommended to interface with the protocol through Handler contracts for a more UX-friendly experience.

State Variables

GEM_JOIN_ROLE

bytes32 public constant GEM_JOIN_ROLE = keccak256("GEM_JOIN_ROLE");

LIQUIDATOR_ROLE

bytes32 public constant LIQUIDATOR_ROLE = keccak256("LIQUIDATOR_ROLE");

ADDRESS_THIS

address private immutable ADDRESS_THIS = address(this);

IonPoolStorageLocation

bytes32 private constant IonPoolStorageLocation = 0xceba3d526b4d5afd91d1b752bf1fd37917c20a6daf576bcb41dd1c57c1f67e00;

Functions

onlyWhitelistedBorrowers

modifier onlyWhitelistedBorrowers(uint8 ilkIndex, address user, bytes32[] memory proof);

onlyWhitelistedLenders

modifier onlyWhitelistedLenders(address user, bytes32[] memory proof);

_getIonPoolStorage

function _getIonPoolStorage() internal pure returns (IonPoolStorage storage $);

constructor

constructor();

initialize

function initialize(
    address _underlying,
    address _treasury,
    uint8 decimals_,
    string memory name_,
    string memory symbol_,
    address initialDefaultAdmin,
    InterestRate _interestRateModule,
    Whitelist _whitelist
)
    external
    initializer;

initializeIlk

Initializes a market with a new collateral type.

This function and the entire protocol as a whole operates under the assumption that there will never be more than 256 collaterals.

function initializeIlk(address ilkAddress) external onlyRole(ION);

Parameters

NameTypeDescription

ilkAddress

address

address of the ERC-20 collateral.

updateIlkSpot

Updates the spot oracle for a given collateral.

function updateIlkSpot(uint8 ilkIndex, SpotOracle newSpot) external onlyRole(ION);

Parameters

NameTypeDescription

ilkIndex

uint8

index of the collateral.

newSpot

SpotOracle

address of the new spot oracle.

updateIlkDebtCeiling

A market can be sunset by setting the debt ceiling to 0. It would still be possible to repay debt but creating new debt would not be possible.

Updates the debt ceiling for a given collateral.

function updateIlkDebtCeiling(uint8 ilkIndex, uint256 newCeiling) external onlyRole(ION);

Parameters

NameTypeDescription

ilkIndex

uint8

index of the collateral.

newCeiling

uint256

new debt ceiling.

updateIlkDust

When increasing the dust, it is possible that some vaults will be dusty after the update. However, changes to the vault position from there will require that the vault be non-dusty (either by repaying all debt or increasing debt beyond the dust).

Updates the dust amount for a given collateral.

function updateIlkDust(uint8 ilkIndex, uint256 newDust) external onlyRole(ION);

Parameters

NameTypeDescription

ilkIndex

uint8

index of the collateral.

newDust

uint256

new dust

updateSupplyCap

Reducing the supply cap will not affect existing deposits. However, if it is below the totalSupply, then no new deposits will be allowed until the totalSupply is below the new supplyCap.

Updates the supply cap.

function updateSupplyCap(uint256 newSupplyCap) external onlyRole(ION);

Parameters

NameTypeDescription

newSupplyCap

uint256

new supply cap.

updateInterestRateModule

Updates the interest rate module. There is a check to ensure that collateralCount() on the new interest rate module match the current number of collaterals in the pool.

function updateInterestRateModule(InterestRate _interestRateModule) external onlyRole(ION);

Parameters

NameTypeDescription

_interestRateModule

InterestRate

new interest rate module.

updateWhitelist

Updates the whitelist.

function updateWhitelist(Whitelist _whitelist) external onlyRole(ION);

Parameters

NameTypeDescription

_whitelist

Whitelist

new whitelist address.

pause

Pause actions but accrue interest as well.

function pause() external onlyRole(ION);

unpause

Unpause actions but this will also update the lastRateUpdate to the unpause transaction timestamp. This essentially allows for a pausing and unpausing of the accrual of interest.

function unpause() external onlyRole(ION);

accrueInterest

Updates accumulators for all ilks based on current interest rates.

function accrueInterest() external whenNotPaused returns (uint256 newTotalDebt);

Returns

NameTypeDescription

newTotalDebt

uint256

the new total debt after interest accrual

_accrueInterest

function _accrueInterest() internal returns (uint256 newTotalDebt);

calculateRewardAndDebtDistribution

function calculateRewardAndDebtDistribution()
    public
    view
    override
    returns (
        uint256 totalSupplyFactorIncrease,
        uint256 totalTreasuryMintAmount,
        uint104[] memory rateIncreases,
        uint256 totalDebtIncrease,
        uint48[] memory timestampIncreases
    );

calculateRewardAndDebtDistributionForIlk

This is primarily for simulation purposes to see how an individual ilk's state will change after an accrual.

function calculateRewardAndDebtDistributionForIlk(uint8 ilkIndex)
    public
    view
    returns (uint104 newRateIncrease, uint48 timestampIncrease);

Parameters

NameTypeDescription

ilkIndex

uint8

index of the collateral.

Returns

NameTypeDescription

newRateIncrease

uint104

the rate increase for the ilk.

timestampIncrease

uint48

the timestamp increase for the ilk.

_calculateRewardAndDebtDistributionForIlk

function _calculateRewardAndDebtDistributionForIlk(
    uint8 ilkIndex,
    uint256 totalEthSupply
)
    internal
    view
    returns (
        uint256 supplyFactorIncrease,
        uint256 treasuryMintAmount,
        uint104 newRateIncrease,
        uint256 newDebtIncrease,
        uint48 timestampIncrease
    );

withdraw

Allows lenders to redeem their interest-bearing position for the underlying asset. It is possible that dust amounts more of the position are burned than the underlying received due to rounding.

function withdraw(address receiverOfUnderlying, uint256 amount) external whenNotPaused;

Parameters

NameTypeDescription

receiverOfUnderlying

address

the address to which the redeemed underlying asset should be sent to.

amount

uint256

of underlying to reedeem for.

supply

Allows lenders to deposit their underlying asset into the pool and earn interest on it.

function supply(
    address user,
    uint256 amount,
    bytes32[] calldata proof
)
    external
    whenNotPaused
    onlyWhitelistedLenders(user, proof);

Parameters

NameTypeDescription

user

address

the address to receive credit for the position.

amount

uint256

of underlying asset to use to create the position.

proof

bytes32[]

merkle proof that the user is whitelisted.

borrow

Allows a borrower to create debt in a position.

function borrow(
    uint8 ilkIndex,
    address user,
    address recipient,
    uint256 amountOfNormalizedDebt,
    bytes32[] memory proof
)
    external
    whenNotPaused
    onlyWhitelistedBorrowers(ilkIndex, user, proof);

Parameters

NameTypeDescription

ilkIndex

uint8

index of the collateral.

user

address

to create the position for.

recipient

address

to receive the borrowed funds

amountOfNormalizedDebt

uint256

to create.

proof

bytes32[]

merkle proof that the user is whitelist.

repay

Allows a borrower to repay debt in a position.

function repay(uint8 ilkIndex, address user, address payer, uint256 amountOfNormalizedDebt) external whenNotPaused;

Parameters

NameTypeDescription

ilkIndex

uint8

index of the collateral.

user

address

to repay the debt for.

payer

address

to source the funds from.

amountOfNormalizedDebt

uint256

to repay.

withdrawCollateral

Moves collateral from internal vault.collateral balances to gem

function withdrawCollateral(uint8 ilkIndex, address user, address recipient, uint256 amount) external whenNotPaused;

Parameters

NameTypeDescription

ilkIndex

uint8

index of the collateral.

user

address

to withdraw the collateral for.

recipient

address

to receive the collateral.

amount

uint256

to withdraw.

depositCollateral

Moves collateral from gem balances to internal vault.collateral

function depositCollateral(
    uint8 ilkIndex,
    address user,
    address depositor,
    uint256 amount,
    bytes32[] calldata proof
)
    external
    whenNotPaused
    onlyWhitelistedBorrowers(ilkIndex, user, proof);

Parameters

NameTypeDescription

ilkIndex

uint8

index of the collateral.

user

address

to deposit the collateral for.

depositor

address

to deposit the collateral from.

amount

uint256

to deposit.

proof

bytes32[]

merkle proof that the user is whitelisted.

_modifyPosition

function _modifyPosition(
    uint8 ilkIndex,
    address u,
    address v,
    address w,
    int256 changeInCollateral,
    int256 changeInNormalizedDebt
)
    internal
    returns (uint104 ilkRate, uint256 newTotalDebt);

repayBadDebt

To be used by protocol to settle bad debt using reserves NOTE: Can pay another user's bad debt with the sender's asset

function repayBadDebt(address user, uint256 rad) external whenNotPaused;

Parameters

NameTypeDescription

user

address

the address that owns the bad debt being paid off

rad

uint256

amount of debt to be repaid (45 decimals)

_transferWeth

Helper function to deal with borrowing and repaying debt. A positive amount is a borrow while negative amount is a repayment

function _transferWeth(address user, int256 amount) internal;

Parameters

NameTypeDescription

user

address

receiver if transfer to, or sender if transfer from

amount

int256

amount to transfer [RAD]

confiscateVault

This function foregoes pausability for pausability at the liquidation module layer

function confiscateVault(
    uint8 ilkIndex,
    address u,
    address v,
    address w,
    int256 changeInCollateral,
    int256 changeInNormalizedDebt
)
    external
    whenNotPaused
    onlyRole(LIQUIDATOR_ROLE);

Parameters

NameTypeDescription

ilkIndex

uint8

index of the collateral.

u

address

user to confiscate the vault from.

v

address

address to either credit gem to or deduct gem from

w

address

changeInCollateral

int256

collateral to add or remove from the vault

changeInNormalizedDebt

int256

debt to add or remove from the vault

mintAndBurnGem

To be called by GemJoin contracts. After a user deposits collateral, credit the user with collateral internally

function mintAndBurnGem(uint8 ilkIndex, address usr, int256 wad) external onlyRole(GEM_JOIN_ROLE);

Parameters

NameTypeDescription

ilkIndex

uint8

collateral

usr

address

user

wad

int256

amount to add or remove

transferGem

Transfer gem across the internal accounting of the pool

function transferGem(uint8 ilkIndex, address src, address dst, uint256 wad) external whenNotPaused;

Parameters

NameTypeDescription

ilkIndex

uint8

index of the collateral

src

address

source of the gem

dst

address

destination of the gem

wad

uint256

amount of gem

ilkCount

function ilkCount() external view returns (uint256);

Returns

NameTypeDescription

<none>

uint256

The total amount of collateral in the pool.

getIlkIndex

function getIlkIndex(address ilkAddress) external view returns (uint8);

Returns

NameTypeDescription

<none>

uint8

The index of the collateral with ilkAddress.

getIlkAddress

function getIlkAddress(uint256 ilkIndex) external view returns (address);

Returns

NameTypeDescription

<none>

address

The address of the collateral at index ilkIndex.

addressContains

function addressContains(address ilk) external view returns (bool);

Returns

NameTypeDescription

<none>

bool

Whether or not an address is a supported collateral.

totalNormalizedDebt

function totalNormalizedDebt(uint8 ilkIndex) external view returns (uint256);

Returns

NameTypeDescription

<none>

uint256

The total amount of normalized debt for collateral with index ilkIndex.

rateUnaccrued

function rateUnaccrued(uint8 ilkIndex) external view returns (uint256);

rate

function rate(uint8 ilkIndex) external view returns (uint256);

Returns

NameTypeDescription

<none>

uint256

The rate (debt accumulator) for collateral with index ilkIndex.

lastRateUpdate

function lastRateUpdate(uint8 ilkIndex) external view returns (uint256);

Returns

NameTypeDescription

<none>

uint256

The timestamp of the last rate update for collateral with index ilkIndex.

spot

function spot(uint8 ilkIndex) external view returns (SpotOracle);

Returns

NameTypeDescription

<none>

SpotOracle

The spot oracle for collateral with index ilkIndex.

debtCeiling

function debtCeiling(uint8 ilkIndex) external view returns (uint256);

Returns

NameTypeDescription

<none>

uint256

debt ceiling for collateral with index ilkIndex.

dust

function dust(uint8 ilkIndex) external view returns (uint256);

Returns

NameTypeDescription

<none>

uint256

dust amount for collateral with index ilkIndex.

collateral

function collateral(uint8 ilkIndex, address user) external view returns (uint256);

Returns

NameTypeDescription

<none>

uint256

The amount of collateral user has for collateral with index ilkIndex.

normalizedDebt

function normalizedDebt(uint8 ilkIndex, address user) external view returns (uint256);

Returns

NameTypeDescription

<none>

uint256

The amount of normalized debt user has for collateral with index ilkIndex.

vault

function vault(uint8 ilkIndex, address user) external view returns (uint256, uint256);

Returns

NameTypeDescription

<none>

uint256

All data within vault for user with index ilkIndex.

<none>

uint256

gem

function gem(uint8 ilkIndex, address user) external view returns (uint256);

Returns

NameTypeDescription

<none>

uint256

Amount of gem that user has for collateral with index ilkIndex.

unbackedDebt

function unbackedDebt(address user) external view returns (uint256);

Returns

NameTypeDescription

<none>

uint256

The amount of unbacked debt user has.

isOperator

function isOperator(address user, address operator) external view returns (bool);

Returns

NameTypeDescription

<none>

bool

Whether or not operator is an operator on user's positions.

isAllowed

function isAllowed(address user, address operator) public view returns (bool);

Returns

NameTypeDescription

<none>

bool

Whether or not operator has permission to make unsafe changes to user's positions.

debtUnaccrued

function debtUnaccrued() external view returns (uint256);

debt

This includes unbacked debt.

function debt() external view returns (uint256);

Returns

NameTypeDescription

<none>

uint256

The total amount of debt.

totalUnbackedDebt

function totalUnbackedDebt() external view returns (uint256);

Returns

NameTypeDescription

<none>

uint256

The total amount of unbacked debt.

interestRateModule

function interestRateModule() external view returns (address);

Returns

NameTypeDescription

<none>

address

The address of interest rate module.

whitelist

function whitelist() external view returns (address);

Returns

NameTypeDescription

<none>

address

The address of the whitelist.

weth

function weth() external view returns (uint256);

Returns

NameTypeDescription

<none>

uint256

The total amount of ETH liquidity in the pool.

getCurrentBorrowRate

Gets the current borrow rate for borrowing against a given collateral.

function getCurrentBorrowRate(uint8 ilkIndex) external view returns (uint256 borrowRate, uint256 reserveFactor);

implementation

Address of the implementation. This is stored immutably on the implementation so that it can be read by the proxy.

function implementation() external view returns (address);

addOperator

Allows an operator to make unsafe changes to _msgSender()s positions.

function addOperator(address operator) external;

removeOperator

Disallows an operator to make unsafe changes to _msgSender()s positions.

function removeOperator(address operator) external;

_add

function _add(uint256 x, int256 y) internal pure returns (uint256 z);

_sub

function _sub(uint256 x, int256 y) internal pure returns (uint256 z);

_rpow

x and the returned value are to be interpreted as fixed-point integers with scaling factor b. For example, if b == 100, this specifies two decimal digits of precision and the normal decimal value 2.1 would be represented as 210; rpow(210, 2, 100) returns 441 (the two-decimal digit fixed-point representation of 2.1^2 = 4.41) (From MCD docs)

function _rpow(uint256 x, uint256 n, uint256 b) internal pure returns (uint256 z);

Parameters

NameTypeDescription

x

uint256

base

n

uint256

exponent

b

uint256

scaling factor

either

function either(bool x, bool y) internal pure returns (bool z);

both

function both(bool x, bool y) internal pure returns (bool z);

Events

IlkInitialized

event IlkInitialized(uint8 indexed ilkIndex, address indexed ilkAddress);

IlkSpotUpdated

event IlkSpotUpdated(uint8 indexed ilkIndex, address newSpot);

IlkDebtCeilingUpdated

event IlkDebtCeilingUpdated(uint8 indexed ilkIndex, uint256 newDebtCeiling);

IlkDustUpdated

event IlkDustUpdated(uint8 indexed ilkIndex, uint256 newDust);

SupplyCapUpdated

event SupplyCapUpdated(uint256 newSupplyCap);

InterestRateModuleUpdated

event InterestRateModuleUpdated(address newModule);

WhitelistUpdated

event WhitelistUpdated(address newWhitelist);

AddOperator

event AddOperator(address indexed user, address indexed operator);

RemoveOperator

event RemoveOperator(address indexed user, address indexed operator);

MintAndBurnGem

event MintAndBurnGem(uint8 indexed ilkIndex, address indexed usr, int256 wad);

TransferGem

event TransferGem(uint8 indexed ilkIndex, address indexed src, address indexed dst, uint256 wad);

Supply

event Supply(
    address indexed user, address indexed underlyingFrom, uint256 amount, uint256 supplyFactor, uint256 newDebt
);

Withdraw

event Withdraw(address indexed user, address indexed target, uint256 amount, uint256 supplyFactor, uint256 newDebt);

WithdrawCollateral

event WithdrawCollateral(uint8 indexed ilkIndex, address indexed user, address indexed recipient, uint256 amount);

DepositCollateral

event DepositCollateral(uint8 indexed ilkIndex, address indexed user, address indexed depositor, uint256 amount);

Borrow

event Borrow(
    uint8 indexed ilkIndex,
    address indexed user,
    address indexed recipient,
    uint256 amountOfNormalizedDebt,
    uint256 ilkRate,
    uint256 totalDebt
);

Repay

event Repay(
    uint8 indexed ilkIndex,
    address indexed user,
    address indexed payer,
    uint256 amountOfNormalizedDebt,
    uint256 ilkRate,
    uint256 totalDebt
);

RepayBadDebt

event RepayBadDebt(address indexed user, address indexed payer, uint256 rad);

ConfiscateVault

event ConfiscateVault(
    uint8 indexed ilkIndex,
    address indexed u,
    address v,
    address indexed w,
    int256 changeInCollateral,
    int256 changeInNormalizedDebt
);

Errors

CeilingExceeded

error CeilingExceeded(uint256 newDebt, uint256 debtCeiling);

UnsafePositionChange

error UnsafePositionChange(uint256 newTotalDebtInVault, uint256 collateral, uint256 spot);

UnsafePositionChangeWithoutConsent

error UnsafePositionChangeWithoutConsent(uint8 ilkIndex, address user, address unconsentedOperator);

GemTransferWithoutConsent

error GemTransferWithoutConsent(uint8 ilkIndex, address user, address unconsentedOperator);

UseOfCollateralWithoutConsent

error UseOfCollateralWithoutConsent(uint8 ilkIndex, address depositor, address unconsentedOperator);

TakingWethWithoutConsent

error TakingWethWithoutConsent(address payer, address unconsentedOperator);

VaultCannotBeDusty

error VaultCannotBeDusty(uint256 amountLeft, uint256 dust);

ArithmeticError

error ArithmeticError();

IlkAlreadyAdded

error IlkAlreadyAdded(address ilkAddress);

IlkNotInitialized

error IlkNotInitialized(uint256 ilkIndex);

DepositSurpassesSupplyCap

error DepositSurpassesSupplyCap(uint256 depositAmount, uint256 supplyCap);

MaxIlksReached

error MaxIlksReached();

InvalidIlkAddress

error InvalidIlkAddress();

InvalidInterestRateModule

error InvalidInterestRateModule(InterestRate invalidInterestRateModule);

InvalidWhitelist

error InvalidWhitelist();

Structs

Ilk

struct Ilk {
    uint104 totalNormalizedDebt;
    uint104 rate;
    uint48 lastRateUpdate;
    SpotOracle spot;
    uint256 debtCeiling;
    uint256 dust;
}

Vault

struct Vault {
    uint256 collateral;
    uint256 normalizedDebt;
}

IonPoolStorage

struct IonPoolStorage {
    Ilk[] ilks;
    EnumerableSet.AddressSet ilkAddresses;
    mapping(uint256 ilkIndex => mapping(address user => Vault)) vaults;
    mapping(uint256 ilkIndex => mapping(address user => uint256)) gem;
    mapping(address unbackedDebtor => uint256) unbackedDebt;
    mapping(address user => mapping(address operator => uint256)) isOperator;
    uint256 debt;
    uint256 weth;
    uint256 wethSupplyCap;
    uint256 totalUnbackedDebt;
    InterestRate interestRateModule;
    Whitelist whitelist;
}