Skip to main content

DepositRedemptionVault

Git Source

Inherits: Policy, IDepositRedemptionVault, PolicyEnabler, ReentrancyGuard

Title: DepositRedemptionVault

forge-lint: disable-start(asm-keccak256, mixed-case-variable)

A contract that manages the redemption of receipt tokens with facility coordination and borrowing

State Variables

ONE_HUNDRED_PERCENT

The number representing 100%

uint16 public constant ONE_HUNDRED_PERCENT = 100e2

_MONTHS_IN_YEAR

The number of months in a year

uint8 internal constant _MONTHS_IN_YEAR = 12

_ONE_MONTH

Constant for one month

uint48 internal constant _ONE_MONTH = 30 days

_NO_POSITION

Used to denote no position ID

uint256 internal constant _NO_POSITION = type(uint256).max

_assetFacilityMaxBorrowPercentages

Per-asset-facility max borrow percentage (in 100e2, e.g. 8500 = 85%)

mapping(bytes32 => uint16) internal _assetFacilityMaxBorrowPercentages

_assetFacilityAnnualInterestRates

Per-asset-facility interest rate (annual, in 100e2, e.g. 500 = 5%)

mapping(bytes32 => uint16) internal _assetFacilityAnnualInterestRates

_claimDefaultRewardPercentage

Keeper reward percentage (in 100e2, e.g. 500 = 5%)

uint16 internal _claimDefaultRewardPercentage

DEPOSIT_MANAGER

The address of the token manager

IDepositManager public immutable DEPOSIT_MANAGER

TRSRY

The TRSRY module.

TRSRYv1 public TRSRY

DEPOS

The DEPOS module.

DEPOSv1 public DEPOS

_userRedemptionCount

The number of redemptions per user

mapping(address => uint16) internal _userRedemptionCount

_userRedemptions

The redemption for each user and redemption ID

Use _getUserRedemptionKey() to calculate the key for the mapping. A complex key is used to save gas compared to a nested mapping.

mapping(bytes32 => UserRedemption) internal _userRedemptions

_authorizedFacilities

Registered facilities

EnumerableSet.AddressSet internal _authorizedFacilities

_redemptionLoan

Loan for each redemption

Use _getUserRedemptionKey() to calculate the key for the mapping. A complex key is used to save gas compared to a nested mapping.

mapping(bytes32 => Loan) internal _redemptionLoan

Functions

constructor

constructor(address kernel_, address depositManager_) Policy(Kernel(kernel_));

configureDependencies

Define module dependencies for this policy.

function configureDependencies() external override returns (Keycode[] memory dependencies);

Returns

NameTypeDescription
dependenciesKeycode[]- Keycode array of module dependencies.

requestPermissions

Function called by kernel to set module function permissions.

function requestPermissions() external pure override returns (Permissions[] memory permissions);

Returns

NameTypeDescription
permissionsPermissions[]requests - Array of keycodes and function selectors for requested permissions.

authorizeFacility

Authorize a facility

function authorizeFacility(address facility_) external onlyAdminRole;

Parameters

NameTypeDescription
facility_addressThe address of the facility to authorize

deauthorizeFacility

Deauthorize a facility

function deauthorizeFacility(address facility_) external onlyEmergencyOrAdminRole;

Parameters

NameTypeDescription
facility_addressThe address of the facility to deauthorize

isAuthorizedFacility

Check if a facility is authorized

function isAuthorizedFacility(address facility_) external view returns (bool);

Parameters

NameTypeDescription
facility_addressThe address of the facility to check

Returns

NameTypeDescription
<none>boolisAuthorized True if the facility is authorized

getAuthorizedFacilities

Get all authorized facilities

function getAuthorizedFacilities() external view returns (address[] memory);

Returns

NameTypeDescription
<none>address[]facilities Array of authorized facility addresses

_pullReceiptToken

Pull the receipt tokens from the caller

function _pullReceiptToken(IERC20 depositToken_, uint8 depositPeriod_, address facility_, uint256 amount_)
internal;

_getUserRedemptionKey

function _getUserRedemptionKey(address user_, uint16 redemptionId_) internal pure returns (bytes32);

_getAssetFacilityKey

Generate a key for the asset-facility parameter mappings

function _getAssetFacilityKey(address asset_, address facility_) internal pure returns (bytes32);

Parameters

NameTypeDescription
asset_addressThe asset address
facility_addressThe facility address

Returns

NameTypeDescription
<none>bytes32The key for the mapping

getUserRedemptionCount

Gets the number of redemptions a user has started

function getUserRedemptionCount(address user_) external view returns (uint16 count);

Parameters

NameTypeDescription
user_addressThe address of the user

Returns

NameTypeDescription
countuint16The number of redemptions

getUserRedemption

Gets the details of a user's redemption

function getUserRedemption(address user_, uint16 redemptionId_)
external
view
returns (UserRedemption memory redemption);

Parameters

NameTypeDescription
user_addressThe address of the user
redemptionId_uint16The ID of the redemption

Returns

NameTypeDescription
redemptionUserRedemptionThe details of the redemption

getUserRedemptions

Gets all redemptions for a user

Notes:

  • This function is gas-intensive for users with many redemptions.
  • The index of an element in the returned array is the redemption ID.
  • Redemptions with an amount of 0 (fully redeemed) are included in the array.
function getUserRedemptions(address user_) external view returns (UserRedemption[] memory);

Parameters

NameTypeDescription
user_addressThe address of the user

Returns

NameTypeDescription
<none>UserRedemption[]redemptions The array of redemptions

_onlyValidRedemptionId

function _onlyValidRedemptionId(address user_, uint16 redemptionId_) internal view;

onlyValidRedemptionId

modifier onlyValidRedemptionId(address user_, uint16 redemptionId_) ;

_validateFacility

function _validateFacility(address facility_) internal view;

onlyValidFacility

modifier onlyValidFacility(address facility_) ;

startRedemption

Starts a redemption of a quantity of deposit tokens

This function expects receipt tokens to be unwrapped (i.e. native ERC6909 tokens) This function reverts if:

  • The contract is disabled
  • The amount is 0
  • The provided facility is not authorized
function startRedemption(IERC20 depositToken_, uint8 depositPeriod_, uint256 amount_, address facility_)
external
nonReentrant
onlyEnabled
onlyValidFacility(facility_)
returns (uint16 redemptionId);

Parameters

NameTypeDescription
depositToken_IERC20The address of the deposit token
depositPeriod_uint8The period of the deposit in months
amount_uint256The amount of deposit tokens to redeem
facility_addressThe facility to handle this redemption

Returns

NameTypeDescription
redemptionIduint16The ID of the user redemption

startRedemption

Starts a redemption based on a position ID, using the position's conversion expiry

This function expects receipt tokens to be unwrapped (i.e. native ERC6909 tokens) This function reverts if:

  • The contract is disabled
  • The amount is 0
  • The caller is not the owner of the position
  • The amount is greater than the remainingDeposit of the position
  • The facility that created the position is not authorized
function startRedemption(uint256 positionId_, uint256 amount_)
external
nonReentrant
onlyEnabled
returns (uint16 redemptionId);

Parameters

NameTypeDescription
positionId_uint256The ID of the position to redeem from
amount_uint256The amount of deposit tokens to redeem

Returns

NameTypeDescription
redemptionIduint16The ID of the user redemption

cancelRedemption

Cancels a redemption of a quantity of deposit tokens

This function reverts if:

  • The contract is disabled
  • The caller is not the owner of the redemption ID
  • The facility in the redemption record is not authorized
  • The amount is 0
  • The amount is greater than the redemption amount
  • There is an unpaid loan
function cancelRedemption(uint16 redemptionId_, uint256 amount_)
external
nonReentrant
onlyEnabled
onlyValidRedemptionId(msg.sender, redemptionId_);

Parameters

NameTypeDescription
redemptionId_uint16The ID of the user redemption
amount_uint256The amount of deposit tokens to cancel

finishRedemption

Finishes a redemption of a quantity of deposit tokens

This function reverts if:

  • The contract is disabled
  • The caller is not the owner of the redemption ID
  • The facility in the redemption record is not authorized
  • The redemption amount is 0
  • It is too early for redemption
  • There is an unpaid loan
function finishRedemption(uint16 redemptionId_)
external
nonReentrant
onlyEnabled
onlyValidRedemptionId(msg.sender, redemptionId_)
returns (uint256 actualAmount);

Parameters

NameTypeDescription
redemptionId_uint16The ID of the user redemption

Returns

NameTypeDescription
actualAmountuint256The quantity of deposit tokens transferred to the caller

_calculateInterest

function _calculateInterest(uint256 principal_, uint256 interestRate_, uint256 depositPeriod_)
internal
pure
returns (uint256);

_previewBorrowAgainstRedemption

function _previewBorrowAgainstRedemption(address user_, uint16 redemptionId_)
internal
view
returns (uint256, uint256, uint48);

previewBorrowAgainstRedemption

Preview the maximum amount that can be borrowed against an active redemption

Notes:

  • The calculated amount may differ from the actual amount borrowed (using borrowAgainstRedemption()) by a few wei, due to rounding behaviour in ERC4626 vaults.
function previewBorrowAgainstRedemption(address user_, uint16 redemptionId_)
external
view
returns (uint256, uint256, uint48);

Parameters

NameTypeDescription
user_addressThe address of the user
redemptionId_uint16The ID of the redemption to borrow against

Returns

NameTypeDescription
<none>uint256principal The principal amount that can be borrowed
<none>uint256interest The interest amount that will be charged
<none>uint48dueDate The due date of the loan

borrowAgainstRedemption

Borrow the maximum amount against an active redemption

Borrows the maximum possible amount against an existing redemption. The loan will be for a fixed-term. The interest is calculated on the basis of that term, and the full amount will be payable in order to close the loan. This function will revert if:

  • The contract is not enabled
  • The redemption ID is invalid
  • The facility is not authorized
  • The amount is 0
  • The interest rate is not set
function borrowAgainstRedemption(uint16 redemptionId_)
external
nonReentrant
onlyEnabled
onlyValidRedemptionId(msg.sender, redemptionId_)
returns (uint256);

Parameters

NameTypeDescription
redemptionId_uint16The ID of the redemption to borrow against

Returns

NameTypeDescription
<none>uint256actualAmount The quantity of underlying assets transferred to the recipient

repayLoan

Repay a loan

This function will repay the outstanding loan amount. Interest is paid back first, followed by principal. To prevent irrecoverable overpayments, the maximum slippage is used to validate that a repayment is within bounds of the remaining loan principal. This function will revert if:

  • The contract is not enabled
  • The redemption ID is invalid
  • The redemption has no loan
  • The amount is 0
  • The loan is expired, defaulted or fully repaid
function repayLoan(uint16 redemptionId_, uint256 amount_, uint256 maxSlippage_)
external
nonReentrant
onlyEnabled
onlyValidRedemptionId(msg.sender, redemptionId_);

Parameters

NameTypeDescription
redemptionId_uint16The ID of the redemption
amount_uint256The amount to repay
maxSlippage_uint256The maximum slippage allowed for the repayment

_previewExtendLoan

function _previewExtendLoan(
address asset_,
address facility_,
uint256 principal_,
uint48 dueDate_,
uint8 extensionMonths_
) internal view returns (uint48, uint256);

previewExtendLoan

Preview the interest payable for extending a loan

This function will revert if:

  • The redemption ID is invalid
  • The loan is invalid
  • The loan is expired, defaulted or fully repaid
  • The months is 0
function previewExtendLoan(address user_, uint16 redemptionId_, uint8 months_)
external
view
onlyValidRedemptionId(user_, redemptionId_)
returns (uint48, uint256);

Parameters

NameTypeDescription
user_addressThe address of the user
redemptionId_uint16The ID of the redemption
months_uint8The number of months to extend the loan

Returns

NameTypeDescription
<none>uint48newDueDate The new due date
<none>uint256interestPayable The interest payable upon extension

extendLoan

Extend a loan's due date

This function will revert if:

  • The contract is not enabled
  • The redemption ID is invalid
  • The loan is invalid
  • The loan is expired, defaulted or fully repaid
  • The months is 0
function extendLoan(uint16 redemptionId_, uint8 months_)
external
nonReentrant
onlyEnabled
onlyValidRedemptionId(msg.sender, redemptionId_);

Parameters

NameTypeDescription
redemptionId_uint16The ID of the redemption
months_uint8The number of months to extend the loan

claimDefaultedLoan

Claim a defaulted loan and collect the reward

This function will revert if:

  • The contract is not enabled
  • The redemption ID is invalid
  • The loan is invalid
  • The loan is not expired
  • The loan is already defaulted
function claimDefaultedLoan(address user_, uint16 redemptionId_)
external
nonReentrant
onlyEnabled
onlyValidRedemptionId(user_, redemptionId_);

Parameters

NameTypeDescription
user_addressThe address of the user
redemptionId_uint16The ID of the redemption

getRedemptionLoan

Get all loans for a redemption

function getRedemptionLoan(address user_, uint16 redemptionId_) external view returns (Loan memory);

Parameters

NameTypeDescription
user_addressThe address of the user
redemptionId_uint16The ID of the redemption

Returns

NameTypeDescription
<none>Loanloan The loan

setMaxBorrowPercentage

Set the maximum borrow percentage for an asset-facility combination

Notes:

  • When setting the max borrow percentage, keep in mind the annual interest rate and claim default reward percentage, as the three configuration values can create incentives for borrowers to not repay their loans (e.g. claim default on their own loan)
  • This function allows setting the value even if the asset or facility are not registered This function reverts if:
  • The contract is not enabled
  • The caller does not have the admin or manager role
  • asset_ is the zero address
  • facility_ is the zero address
  • percent_ is out of range
function setMaxBorrowPercentage(IERC20 asset_, address facility_, uint16 percent_)
external
onlyEnabled
onlyManagerOrAdminRole;

Parameters

NameTypeDescription
asset_IERC20The address of the asset
facility_addressThe address of the facility
percent_uint16The maximum borrow percentage

getMaxBorrowPercentage

Get the maximum borrow percentage for an asset-facility combination

function getMaxBorrowPercentage(IERC20 asset_, address facility_) external view returns (uint16);

Parameters

NameTypeDescription
asset_IERC20The address of the asset
facility_addressThe address of the facility

Returns

NameTypeDescription
<none>uint16percent The maximum borrow percentage (100e2 == 100%)

setAnnualInterestRate

Set the annual interest rate for an asset-facility combination

Notes:

  • When setting the annual interest rate, keep in mind the max borrow percentage and claim default reward percentage, as the three configuration values can create incentives for borrowers to not repay their loans (e.g. claim default on their own loan)
  • This function allows setting the value even if the asset or facility are not registered This function reverts if:
  • The contract is not enabled
  • The caller does not have the admin or manager role
  • asset_ is the zero address
  • facility_ is the zero address
  • percent_ is out of range
function setAnnualInterestRate(IERC20 asset_, address facility_, uint16 rate_)
external
onlyEnabled
onlyManagerOrAdminRole;

Parameters

NameTypeDescription
asset_IERC20The address of the asset
facility_addressThe address of the facility
rate_uint16The annual interest rate (100e2 == 100%)

getAnnualInterestRate

Get the annual interest rate for an asset-facility combination

function getAnnualInterestRate(IERC20 asset_, address facility_) external view returns (uint16);

Parameters

NameTypeDescription
asset_IERC20The address of the asset
facility_addressThe address of the facility

Returns

NameTypeDescription
<none>uint16rate The annual interest rate, in terms of 100e2

setClaimDefaultRewardPercentage

Set the reward percentage when a claiming a defaulted loan

Notes:

  • When setting the claim default reward percentage, keep in mind the annual interest rate and max borrow percentage, as the three configuration values can create incentives for borrowers to not repay their loans (e.g. claim default on their own loan)
function setClaimDefaultRewardPercentage(uint16 percent_) external onlyEnabled onlyManagerOrAdminRole;

Parameters

NameTypeDescription
percent_uint16The claim default reward percentage

getClaimDefaultRewardPercentage

Get the claim default reward percentage

function getClaimDefaultRewardPercentage() external view returns (uint16);

Returns

NameTypeDescription
<none>uint16percent The claim default reward percentage, in terms of 100e2

supportsInterface

function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool);