Ultimate Synthetic Delta Neutral - USDN

Main workflow Release Workflow

Using from Other Projects

To import contracts, interfaces or ABIs into other projects, you can use one of the following options:

Soldeer

[forge] soldeer install @smardex-usdn-contracts~1.1.0

NPM, pnpm

npm i @smardex/usdn-contracts
pnpm add @smardex/usdn-contracts

JSR

deno add jsr:@smardex/usdn-contracts
bunx jsr add @smardex/usdn-contracts
pnpm i jsr:@smardex/usdn-contracts

Install Development Environment

Foundry

To install Foundry, run the following commands in your terminal:

curl -L https://foundry.paradigm.xyz | bash
source ~/.bashrc
foundryup

Dependencies

To install existing dependencies, run the following commands:

forge soldeer install
npm install

The forge soldeer install command is only used to add libraries for the smart contracts. Other dependencies should be managed with npm.

In order to add a new dependency, use the forge soldeer install [packagename]~[version] command with any package from the soldeer registry.

For instance, to add OpenZeppelin library version 5.0.2:

forge soldeer install @openzeppelin-contracts~5.0.2

The last step is to update the remappings array in the foundry.toml config file.

You must have Node.js >= 20 installed.

Nix

If using nix, the repository provides a development shell in the form of a flake.

The devshell can be activated with the nix develop command.

To automatically activate the dev shell when opening the workspace, install direnv (available on nixpkgs) and run the following command inside this folder:

direnv allow

The environment provides the following tools:

  • load .env file as environment variables
  • foundry
  • lcov
  • Node 20 + Typescript
  • Rust toolchain
  • just
  • lintspec
  • mdbook
  • trufflehog
  • typst (with gyre-fonts)
  • test_utils dependencies

Usage

Tests

Compile the test utils by running the following command at the root of the repo (requires the Rust toolchain):

cargo build --release

This requires some dependencies to build (the m4 lib notably). Using the provided nix devShell should provide everything.

To run tests, use forge test -vvv or npm run test.

Deployment Scripts

Deployment for anvil forks should be done with a custom bash script at script/fork/deployFork.sh which can be run without arguments. It must set up any environment variable required by the foundry deployment script.

Deployment for mainnet should be done with a custom bash script at script/deployMainnet.sh. To know which variables are required, run the following command:

script/deployMainnet.sh --help

All information about the script can be found in the script/ folder's README.

Docker Anvil Fork

You can deploy the contracts to an anvil fork using docker. The following commands will build the docker image and run the deployment script.

docker build -t usdn-anvil .
docker run --rm -it -p 8545:8545 usdn-anvil script/deployFork.sh

Foundry Documentation

For comprehensive details on Foundry, refer to the Foundry book.

Helpful Resources

Code Standards and Tools

Forge Formatter

Foundry comes with a built-in code formatter that we configured like this (default values were omitted):

[profile.default.fmt]
line_length = 120 # Max line length
bracket_spacing = true # Spacing the brackets in the code
wrap_comments = true # use max line length for comments as well
number_underscore = "thousands" # add underscore separators in large numbers

Husky

The pre-commit configuration for Husky runs forge fmt --check to check the code formatting before each commit. It also checks for any private key in the codebase with trufflehog.

In order to setup the git pre-commit hook, run npm install.

Contributors

Implemented by Stéphane Ballmer, Lilyan Bastien, Valentin Bersier, Yoan Capron, Sami Darnaud, Nicolas Decosterd, Léo Fasano, Alfred Gaillard, Paul-Alexandre Tessier

Contents

LiquidationRewardsManager

Git Source

Inherits: ILiquidationRewardsManager, Ownable2Step

This abstract contract calculates the bonus portion of the rewards based on the size of the liquidated ticks. The actual reward calculation is left to the implementing contract.

State Variables

BPS_DIVISOR

Gets the denominator used for the reward multipliers.

uint32 public constant BPS_DIVISOR = 10_000;

BASE_GAS_COST

Gets the fixed gas amount used as a base for transaction cost computations.

Stored as a uint256 to prevent overflow during gas usage computations.

uint256 public constant BASE_GAS_COST = 21_000;

MAX_GAS_USED_PER_TICK

Gets the maximum allowable gas usage per liquidated tick.

uint256 public constant MAX_GAS_USED_PER_TICK = 500_000;

MAX_OTHER_GAS_USED

Gets the maximum allowable gas usage for all other computations.

uint256 public constant MAX_OTHER_GAS_USED = 1_000_000;

MAX_REBASE_GAS_USED

Gets the maximum allowable gas usage for rebase operations.

uint256 public constant MAX_REBASE_GAS_USED = 200_000;

MAX_REBALANCER_GAS_USED

Gets the maximum allowable gas usage for triggering the optional rebalancer.

uint256 public constant MAX_REBALANCER_GAS_USED = 300_000;

_rewardAsset

The address of the reward asset.

IERC20 internal immutable _rewardAsset;

_rewardsParameters

Holds the parameters used for rewards calculation.

Parameters should be updated to reflect changes in gas costs or protocol adjustments.

RewardsParameters internal _rewardsParameters;

Functions

getLiquidationRewards

Computes the amount of assets to reward a liquidator.

function getLiquidationRewards(
    Types.LiqTickInfo[] calldata liquidatedTicks,
    uint256 currentPrice,
    bool rebased,
    Types.RebalancerAction rebalancerAction,
    Types.ProtocolAction action,
    bytes calldata rebaseCallbackResult,
    bytes calldata priceData
) external view virtual returns (uint256 rewards_);

Parameters

NameTypeDescription
liquidatedTicksTypes.LiqTickInfo[]Information about the liquidated ticks.
currentPriceuint256The current price of the asset.
rebasedboolIndicates whether a USDN rebase was performed.
rebalancerActionTypes.RebalancerActionThe action performed by the _triggerRebalancer function.
actionTypes.ProtocolActionThe type of protocol action that triggered the liquidation.
rebaseCallbackResultbytesThe result of the rebase callback, if any.
priceDatabytesThe oracle price data, if any. This can be used to differentiate rewards based on the oracle used to provide the liquidation price.

Returns

NameTypeDescription
rewards_uint256assetRewards_ The amount of asset tokens to reward the liquidator.

getRewardsParameters

Retrieves the current parameters used for reward calculations.

function getRewardsParameters() external view returns (RewardsParameters memory);

Returns

NameTypeDescription
<none>RewardsParametersrewardsParameters_ A struct containing the rewards parameters.

setRewardsParameters

Updates the parameters used for calculating liquidation rewards.

function setRewardsParameters(
    uint32 gasUsedPerTick,
    uint32 otherGasUsed,
    uint32 rebaseGasUsed,
    uint32 rebalancerGasUsed,
    uint64 baseFeeOffset,
    uint16 gasMultiplierBps,
    uint16 positionBonusMultiplierBps,
    uint128 fixedReward,
    uint128 maxReward
) external onlyOwner;

Parameters

NameTypeDescription
gasUsedPerTickuint32The gas consumed per tick for liquidation.
otherGasUseduint32The gas consumed for all additional computations.
rebaseGasUseduint32The gas consumed for optional USDN rebase operation.
rebalancerGasUseduint32The gas consumed for the optional rebalancer trigger.
baseFeeOffsetuint64An offset added to the block's base gas fee.
gasMultiplierBpsuint16The multiplier for the gas usage (in BPS).
positionBonusMultiplierBpsuint16Multiplier for position size bonus (in BPS).
fixedRewarduint128A fixed reward amount (in native currency, converted to wstETH).
maxRewarduint128The maximum allowable reward amount (in native currency, converted to wstETH).

_calcGasPrice

Calculates the gas price used for rewards calculations.

function _calcGasPrice(uint64 baseFeeOffset) internal view returns (uint256 gasPrice_);

Parameters

NameTypeDescription
baseFeeOffsetuint64An offset added to the block's base gas fee.

Returns

NameTypeDescription
gasPrice_uint256The gas price used for reward calculation.

_calcPositionSizeBonus

Computes the size and price-dependent bonus given for liquidating the ticks.

function _calcPositionSizeBonus(Types.LiqTickInfo[] calldata liquidatedTicks, uint256 currentPrice, uint16 multiplier)
    internal
    pure
    returns (uint256 bonus_);

Parameters

NameTypeDescription
liquidatedTicksTypes.LiqTickInfo[]Information about the liquidated ticks.
currentPriceuint256The current asset price.
multiplieruint16The bonus multiplier (in BPS).

Returns

NameTypeDescription
bonus_uint256The calculated bonus (in _rewardAsset).

LiquidationRewardsManagerWstEth

Git Source

Inherits: LiquidationRewardsManager

This contract calculates rewards for liquidators within the USDN protocol, using wstETH as the underlying asset. Rewards are computed based on gas costs, which are converted to wstETH using the current conversion rate between wstETH and stETH, assuming a one-to-one rate between stETH and ETH. Additionally a fixed reward is added along with a bonus based on the size of the liquidated ticks.

Functions

constructor

constructor(IWstETH wstETH) Ownable(msg.sender);

Parameters

NameTypeDescription
wstETHIWstETHThe address of the wstETH token.

getLiquidationRewards

Computes the amount of assets to reward a liquidator.

function getLiquidationRewards(
    Types.LiqTickInfo[] calldata liquidatedTicks,
    uint256 currentPrice,
    bool rebased,
    Types.RebalancerAction rebalancerAction,
    Types.ProtocolAction,
    bytes calldata,
    bytes calldata
) external view override returns (uint256 wstETHRewards_);

Parameters

NameTypeDescription
liquidatedTicksTypes.LiqTickInfo[]Information about the liquidated ticks.
currentPriceuint256The current price of the asset.
rebasedboolIndicates whether a USDN rebase was performed.
rebalancerActionTypes.RebalancerActionThe action performed by the _triggerRebalancer function.
<none>Types.ProtocolAction
<none>bytes
<none>bytes

Returns

NameTypeDescription
wstETHRewards_uint256assetRewards_ The amount of asset tokens to reward the liquidator.

LiquidationRewardsManagerWusdn

Git Source

Inherits: LiquidationRewardsManager

This contract calculates rewards for liquidators within the USDN protocol, using wUSDN as the underlying asset. Rewards are computed based on gas costs which are converted to wUSDN using the current price. Additionally a fixed reward is added along with a bonus based on the size of the liquidated ticks.

State Variables

PRICE_PRECISION

The precision used for the price.

uint256 internal constant PRICE_PRECISION = 1e18;

Functions

constructor

constructor(IWusdn wusdn) Ownable(msg.sender);

Parameters

NameTypeDescription
wusdnIWusdnThe address of the wUSDN token.

getLiquidationRewards

Computes the amount of assets to reward a liquidator.

function getLiquidationRewards(
    Types.LiqTickInfo[] calldata liquidatedTicks,
    uint256 currentPrice,
    bool,
    Types.RebalancerAction rebalancerAction,
    Types.ProtocolAction,
    bytes calldata,
    bytes calldata
) external view override returns (uint256 wUsdnRewards_);

Parameters

NameTypeDescription
liquidatedTicksTypes.LiqTickInfo[]Information about the liquidated ticks.
currentPriceuint256The current price of the asset.
<none>bool
rebalancerActionTypes.RebalancerActionThe action performed by the _triggerRebalancer function.
<none>Types.ProtocolAction
<none>bytes
<none>bytes

Returns

NameTypeDescription
wUsdnRewards_uint256assetRewards_ The amount of asset tokens to reward the liquidator.

Contents

Contents

MockWstEthOracleMiddlewareWithPyth

Git Source

Inherits: WstEthOracleMiddlewareWithPyth

This contract is used to get the price of wstETH by setting up a price or forwarding it to wstethMiddleware

This aims at simulating price action. Do not use in production

State Variables

_wstethMockedConfBps

Confidence interval percentage numerator

uint16 internal _wstethMockedConfBps = 20;

_wstethMockedPrice

wstETH mocked price

This price will be used if greater than zero

uint256 internal _wstethMockedPrice;

_verifySignature

If we need to verify the provided signature data or not

If _wstethMockedPrice == 0, this setting is ignored

bool internal _verifySignature = true;

Functions

constructor

constructor(
    address pythContract,
    bytes32 pythFeedId,
    address chainlinkPriceFeed,
    address wsteth,
    uint256 chainlinkTimeElapsedLimit
) WstEthOracleMiddlewareWithPyth(pythContract, pythFeedId, chainlinkPriceFeed, wsteth, chainlinkTimeElapsedLimit);

parseAndValidatePrice

function parseAndValidatePrice(
    bytes32 actionId,
    uint128 targetTimestamp,
    Types.ProtocolAction action,
    bytes calldata data
) public payable override returns (PriceInfo memory price_);

setWstethMockedPrice

Set WstEth mocked price

If the new mocked WstEth is greater than zero this will validate this mocked price else this will validate the parent middleware price

function setWstethMockedPrice(uint256 newWstethMockedPrice) external;

Parameters

NameTypeDescription
newWstethMockedPriceuint256The mock price to set

setWstethMockedConfBps

Set Wsteth mocked confidence interval percentage

To calculate a percentage of the neutral price up or down in some protocol actions

function setWstethMockedConfBps(uint16 newWstethMockedConfPct) external;

Parameters

NameTypeDescription
newWstethMockedConfPctuint16The mock confidence interval

getWstethMockedPrice

Get current WstEth mocked price

function getWstethMockedPrice() external view returns (uint256);

getWstethMockedConfBps

Get current WstEth mocked confidence interval

function getWstethMockedConfBps() external view returns (uint64);

getVerifySignature

Get the signature verification flag

function getVerifySignature() external view returns (bool);

setVerifySignature

Set the signature verification flag

function setVerifySignature(bool verify) external;

validationCost

function validationCost(bytes calldata data, Types.ProtocolAction action)
    public
    view
    override(IBaseOracleMiddleware, CommonOracleMiddleware)
    returns (uint256 result_);

Contents

ChainlinkDataStreamsOracle

Git Source

Inherits: IOracleMiddlewareErrors, IChainlinkDataStreamsOracle

This contract is used to get the price of the asset that corresponds to the stored Chainlink data streams ID.

Is implemented by the OracleMiddlewareWithDataStreams contract.

State Variables

PROXY_VERIFIER

The address of the Chainlink proxy verifier contract.

IVerifierProxy internal immutable PROXY_VERIFIER;

STREAM_ID

The ID of the Chainlink data streams.

Any data streams are standardized to 18 decimals.

bytes32 internal immutable STREAM_ID;

REPORT_VERSION

The report version.

uint256 internal constant REPORT_VERSION = 3;

_dataStreamsRecentPriceDelay

The maximum age of a recent price to be considered valid for Chainlink data streams.

uint256 internal _dataStreamsRecentPriceDelay = 45 seconds;

Functions

constructor

constructor(address verifierAddress, bytes32 streamId);

Parameters

NameTypeDescription
verifierAddressaddressThe address of the Chainlink proxy verifier contract.
streamIdbytes32The ID of the Chainlink data streams.

getProxyVerifier

Gets the Chainlink Proxy verifier contract.

function getProxyVerifier() external view returns (IVerifierProxy proxyVerifier_);

Returns

NameTypeDescription
proxyVerifier_IVerifierProxyThe address of the proxy verifier contract.

getStreamId

Gets the supported Chainlink data stream ID.

function getStreamId() external view returns (bytes32 streamId_);

Returns

NameTypeDescription
streamId_bytes32The unique identifier for the Chainlink data streams.

getDataStreamRecentPriceDelay

Gets the maximum age of a recent price to be considered valid.

function getDataStreamRecentPriceDelay() external view returns (uint256 delay_);

Returns

NameTypeDescription
delay_uint256The maximum acceptable age of a recent price in seconds.

getReportVersion

Gets the supported Chainlink data streams report version.

function getReportVersion() external pure returns (uint256 version_);

Returns

NameTypeDescription
version_uint256The version number of the supported Chainlink data streams report.

_getChainlinkDataStreamPrice

Gets the formatted price of the asset with Chainlink data streams.

function _getChainlinkDataStreamPrice(bytes calldata payload, uint128 targetTimestamp, uint128 targetLimit)
    internal
    returns (FormattedDataStreamsPrice memory formattedPrice_);

Parameters

NameTypeDescription
payloadbytesThe full report obtained from the Chainlink data streams API.
targetTimestampuint128The target timestamp of the price. If zero, then we accept all recent prices.
targetLimituint128The most recent timestamp a price can have. Can be zero if targetTimestamp is zero.

Returns

NameTypeDescription
formattedPrice_FormattedDataStreamsPriceThe Chainlink formatted price with 18 decimals.

_getChainlinkDataStreamFeeData

Gets the fee asset data to decode the payload.

The native token fee option will be used.

function _getChainlinkDataStreamFeeData(bytes calldata payload)
    internal
    view
    returns (IFeeManager.Asset memory feeData_);

Parameters

NameTypeDescription
payloadbytesThe data streams payload (full report).

Returns

NameTypeDescription
feeData_IFeeManager.AssetThe fee asset data including the token and the amount required to verify the report.

ChainlinkOracle

Git Source

Inherits: IChainlinkOracle, IOracleMiddlewareErrors

This contract is used to get the price of an asset from Chainlink. It is used by the USDN protocol to get the price of the USDN underlying asset, and by the LiquidationRewardsManager to get the price of the gas.

State Variables

PRICE_TOO_OLD

The sentinel value returned instead of the price if the data from the oracle is too old.

int256 public constant PRICE_TOO_OLD = type(int256).min;

_priceFeed

The Chainlink price feed aggregator contract.

AggregatorV3Interface internal immutable _priceFeed;

_timeElapsedLimit

Tolerated elapsed time until we consider the data too old.

uint256 internal _timeElapsedLimit;

Functions

constructor

constructor(address chainlinkPriceFeed, uint256 timeElapsedLimit);

Parameters

NameTypeDescription
chainlinkPriceFeedaddressAddress of the price feed.
timeElapsedLimituint256Tolerated elapsed time before the data is considered invalid.

getChainlinkDecimals

Gets the number of decimals of the asset from Chainlink.

function getChainlinkDecimals() public view returns (uint256 decimals_);

Returns

NameTypeDescription
decimals_uint256The number of decimals of the asset.

getPriceFeed

Gets the Chainlink price feed aggregator contract address.

function getPriceFeed() public view returns (AggregatorV3Interface priceFeed_);

Returns

NameTypeDescription
priceFeed_AggregatorV3InterfaceThe address of the Chainlink price feed contract.

getChainlinkTimeElapsedLimit

Gets the duration after which the Chainlink data is considered stale or invalid.

function getChainlinkTimeElapsedLimit() external view returns (uint256 limit_);

Returns

NameTypeDescription
limit_uint256The price validity duration.

_getChainlinkLatestPrice

Gets the latest price of the asset from Chainlink.

If the price is too old, the returned price will be equal to PRICE_TOO_OLD.

function _getChainlinkLatestPrice() internal view virtual returns (ChainlinkPriceInfo memory price_);

Returns

NameTypeDescription
price_ChainlinkPriceInfoThe price of the asset.

_getFormattedChainlinkLatestPrice

Gets the latest price of the asset from Chainlink, formatted to the specified number of decimals.

function _getFormattedChainlinkLatestPrice(uint256 middlewareDecimals)
    internal
    view
    returns (ChainlinkPriceInfo memory formattedPrice_);

Parameters

NameTypeDescription
middlewareDecimalsuint256The number of decimals to format the price to.

Returns

NameTypeDescription
formattedPrice_ChainlinkPriceInfoThe formatted price of the asset.

_getFormattedChainlinkPrice

Gets the price of the asset at the specified round ID, formatted to the specified number of decimals.

function _getFormattedChainlinkPrice(uint256 middlewareDecimals, uint80 roundId)
    internal
    view
    returns (ChainlinkPriceInfo memory formattedPrice_);

Parameters

NameTypeDescription
middlewareDecimalsuint256The number of decimals to format the price to.
roundIduint80The targeted round ID.

Returns

NameTypeDescription
formattedPrice_ChainlinkPriceInfoThe formatted price of the asset.

_getChainlinkPrice

Gets the price of the asset at the specified round ID.

function _getChainlinkPrice(uint80 roundId) internal view virtual returns (ChainlinkPriceInfo memory price_);

Parameters

NameTypeDescription
roundIduint80The Chainlink roundId price.

Returns

NameTypeDescription
price_ChainlinkPriceInfoThe price of the asset.

PythOracle

Git Source

Inherits: IPythOracle

This contract is used to get the price of the asset that corresponds to the stored feed ID.

Is implemented by the CommonOracleMiddleware contract.

State Variables

_pythFeedId

The ID of the Pyth price feed.

bytes32 internal immutable _pythFeedId;

_pyth

The address of the Pyth contract.

IPyth internal immutable _pyth;

_pythRecentPriceDelay

The maximum age of a recent price to be considered valid.

uint64 internal _pythRecentPriceDelay = 45 seconds;

Functions

constructor

constructor(address pythAddress, bytes32 pythFeedId);

Parameters

NameTypeDescription
pythAddressaddressThe address of the Pyth contract.
pythFeedIdbytes32The ID of the Pyth price feed.

getPyth

Gets the Pyth contract address.

function getPyth() external view returns (IPyth);

Returns

NameTypeDescription
<none>IPythpyth_ The Pyth contract address.

getPythFeedId

Gets the ID of the price feed queried by this contract.

function getPythFeedId() external view returns (bytes32);

Returns

NameTypeDescription
<none>bytes32feedId_ The Pyth price feed ID.

getPythRecentPriceDelay

Gets the recent price delay.

function getPythRecentPriceDelay() external view returns (uint64);

Returns

NameTypeDescription
<none>uint64recentPriceDelay_ The maximum age of a recent price to be considered valid.

_getPythPrice

Gets the price of the asset from the stored Pyth price feed.

function _getPythPrice(bytes calldata priceUpdateData, uint128 targetTimestamp, uint128 targetLimit)
    internal
    returns (PythStructs.Price memory);

Parameters

NameTypeDescription
priceUpdateDatabytesThe data required to update the price feed.
targetTimestampuint128The timestamp of the price in the given priceUpdateData. If zero, then we accept all recent prices.
targetLimituint128The most recent timestamp a price can have. Can be zero if targetTimestamp is zero.

Returns

NameTypeDescription
<none>PythStructs.Priceprice_ The raw price of the asset returned by Pyth.

_getFormattedPythPrice

Gets the price of the asset from Pyth, formatted to the specified number of decimals.

function _getFormattedPythPrice(
    bytes calldata priceUpdateData,
    uint128 targetTimestamp,
    uint256 middlewareDecimals,
    uint128 targetLimit
) internal returns (FormattedPythPrice memory price_);

Parameters

NameTypeDescription
priceUpdateDatabytesThe data required to update the price feed.
targetTimestampuint128The timestamp of the price in the given priceUpdateData. If zero, then we accept all recent prices.
middlewareDecimalsuint256The number of decimals to format the price to.
targetLimituint128The most recent timestamp a price can have. Can be zero if targetTimestamp is zero.

Returns

NameTypeDescription
price_FormattedPythPriceThe Pyth price formatted with middlewareDecimals.

_formatPythPrice

Formats a Pyth price object to normalize to the specified number of decimals.

function _formatPythPrice(PythStructs.Price memory pythPrice, uint256 middlewareDecimals)
    internal
    pure
    returns (FormattedPythPrice memory price_);

Parameters

NameTypeDescription
pythPricePythStructs.PriceA Pyth price object.
middlewareDecimalsuint256The number of decimals to format the price to.

Returns

NameTypeDescription
price_FormattedPythPriceThe Pyth price formatted with middlewareDecimals.

_getPythUpdateFee

Gets the fee required to update the price feed.

function _getPythUpdateFee(bytes calldata priceUpdateData) internal view returns (uint256);

Parameters

NameTypeDescription
priceUpdateDatabytesThe data required to update the price feed.

Returns

NameTypeDescription
<none>uint256updateFee_ The fee required to update the price feed.

_getLatestStoredPythPrice

Gets the latest seen (cached) price from the Pyth contract.

function _getLatestStoredPythPrice(uint256 middlewareDecimals)
    internal
    view
    returns (FormattedPythPrice memory price_);

Parameters

NameTypeDescription
middlewareDecimalsuint256The number of decimals for the returned price.

Returns

NameTypeDescription
price_FormattedPythPriceThe formatted cached Pyth price, or all-zero values if there was no valid Pyth price on-chain.

RedstoneOracle

Git Source

Inherits: IRedstoneOracle, PrimaryProdDataServiceConsumerBase, IOracleMiddlewareErrors

This contract is used to get the price of the asset that corresponds to the stored feed ID.

Is implemented by the OracleMiddlewareWithRedstone contract.

State Variables

REDSTONE_HEARTBEAT

Gets the interval between two Redstone price updates.

uint48 public constant REDSTONE_HEARTBEAT = 10 seconds;

REDSTONE_DECIMALS

Gets the number of decimals for prices contained in Redstone price updates.

uint8 public constant REDSTONE_DECIMALS = 8;

_redstoneFeedId

The ID of the Redstone price feed.

bytes32 internal immutable _redstoneFeedId;

_redstoneRecentPriceDelay

The maximum age of a price to be considered recent.

uint48 internal _redstoneRecentPriceDelay = 45 seconds;

Functions

constructor

constructor(bytes32 redstoneFeedId);

Parameters

NameTypeDescription
redstoneFeedIdbytes32The ID of the price feed.

getRedstoneFeedId

Gets the ID of the Redstone price feed.

function getRedstoneFeedId() external view returns (bytes32 feedId_);

Returns

NameTypeDescription
feedId_bytes32The feed ID.

getRedstoneRecentPriceDelay

Gets the maximum age of a price to be considered recent.

function getRedstoneRecentPriceDelay() external view returns (uint48 delay_);

Returns

NameTypeDescription
delay_uint48The age in seconds.

validateTimestamp

Used by the Redstone contract internally, we override it to allow all timestamps.

function validateTimestamp(uint256) public pure override(IRedstoneOracle, RedstoneConsumerBase);

Parameters

NameTypeDescription
<none>uint256

_getFormattedRedstonePrice

Gets the price of the asset from Redstone, formatted to the specified number of decimals.

Redstone automatically retrieves data from the end of the calldata, no need to pass the pointer.

function _getFormattedRedstonePrice(uint128 targetTimestamp, uint256 middlewareDecimals)
    internal
    view
    returns (RedstonePriceInfo memory formattedPrice_);

Parameters

NameTypeDescription
targetTimestampuint128The target timestamp to validate the price. If zero, then we accept a price as old as block.timestamp - _redstoneRecentPriceDelay.
middlewareDecimalsuint256The number of decimals to format the price to.

Returns

NameTypeDescription
formattedPrice_RedstonePriceInfoThe price from Redstone, normalized to middlewareDecimals.

_extractPriceUpdateTimestamp

Extract the timestamp from the price update.

extractedTimestamp_ is a timestamp in seconds.

function _extractPriceUpdateTimestamp() internal pure returns (uint48 extractedTimestamp_);

Returns

NameTypeDescription
extractedTimestamp_uint48The timestamp of the price update.

CommonOracleMiddleware

Git Source

Inherits: ICommonOracleMiddleware, AccessControlDefaultAdminRules, ChainlinkOracle, PythOracle

This contract serves as a common base that must be implemented by other middleware contracts.

State Variables

ADMIN_ROLE

Gets the admin role's signature.

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

MIDDLEWARE_DECIMALS

The number of decimals for the returned price.

uint8 internal constant MIDDLEWARE_DECIMALS = 18;

_validationDelay

The delay (in seconds) between the moment an action is initiated and the timestamp of the price data used to validate that action.

uint256 internal _validationDelay = 24 seconds;

_lowLatencyDelay

The amount of time during which a low latency oracle price validation is available.

This value should be greater than or equal to _lowLatencyValidatorDeadline of the USDN protocol.

uint16 internal _lowLatencyDelay = 20 minutes;

Functions

constructor

constructor(address pythContract, bytes32 pythFeedId, address chainlinkPriceFeed, uint256 chainlinkTimeElapsedLimit)
    PythOracle(pythContract, pythFeedId)
    ChainlinkOracle(chainlinkPriceFeed, chainlinkTimeElapsedLimit)
    AccessControlDefaultAdminRules(0, msg.sender);

Parameters

NameTypeDescription
pythContractaddressAddress of the Pyth contract.
pythFeedIdbytes32The Pyth price feed ID for the asset.
chainlinkPriceFeedaddressAddress of the Chainlink price feed.
chainlinkTimeElapsedLimituint256The duration after which a Chainlink price is considered stale.

getDecimals

Gets the number of decimals for the price.

function getDecimals() external pure returns (uint8 decimals_);

Returns

NameTypeDescription
decimals_uint8The number of decimals.

getValidationDelay

Gets the required delay (in seconds) between the moment an action is initiated and the timestamp of the price data used to validate that action.

function getValidationDelay() external view returns (uint256 delay_);

Returns

NameTypeDescription
delay_uint256The validation delay.

getLowLatencyDelay

Gets The maximum amount of time (in seconds) after initiation during which a low-latency price oracle can be used for validation.

function getLowLatencyDelay() external view returns (uint16 delay_);

Returns

NameTypeDescription
delay_uint16The maximum delay for low-latency validation.

validationCost

Returns the cost of one price validation for the given action (in native token).

function validationCost(bytes calldata data, Types.ProtocolAction) public view virtual returns (uint256 result_);

Parameters

NameTypeDescription
databytesPrice data for which to get the fee.
<none>Types.ProtocolAction

Returns

NameTypeDescription
result_uint256cost_ The cost of one price validation (in native token).

parseAndValidatePrice

Parse and validate data and returns the corresponding price data.

The data format is specific to the middleware and is simply forwarded from the user transaction's calldata. A fee amounting to exactly validationCost (with the same data and action) must be sent or the transaction will revert.

function parseAndValidatePrice(bytes32, uint128 targetTimestamp, Types.ProtocolAction action, bytes calldata data)
    public
    payable
    virtual
    returns (PriceInfo memory price_);

Parameters

NameTypeDescription
<none>bytes32
targetTimestampuint128The target timestamp for validating the price data. For validation actions, this is the timestamp of the initiation.
actionTypes.ProtocolActionType of action for which the price is requested. The middleware may use this to alter the validation of the price or the returned price.
databytesThe data to be used to communicate with oracles, the format varies from middleware to middleware and can be different depending on the action.

Returns

NameTypeDescription
price_PriceInforesult_ The price and timestamp as PriceInfo.

setValidationDelay

Sets the validation delay (in seconds) between an action timestamp and the price data timestamp used to validate that action.

function setValidationDelay(uint256 newValidationDelay) external onlyRole(ADMIN_ROLE);

Parameters

NameTypeDescription
newValidationDelayuint256The new validation delay.

setChainlinkTimeElapsedLimit

Sets the elapsed time tolerated before we consider the price from Chainlink invalid.

function setChainlinkTimeElapsedLimit(uint256 newTimeElapsedLimit) external onlyRole(ADMIN_ROLE);

Parameters

NameTypeDescription
newTimeElapsedLimituint256The new time elapsed limit.

setPythRecentPriceDelay

Sets the amount of time after which we do not consider a price as recent.

function setPythRecentPriceDelay(uint64 newDelay) external onlyRole(ADMIN_ROLE);

Parameters

NameTypeDescription
newDelayuint64The maximum age of a price to be considered recent.

setLowLatencyDelay

Sets the new low latency delay.

function setLowLatencyDelay(uint16 newLowLatencyDelay, IUsdnProtocol usdnProtocol) external onlyRole(ADMIN_ROLE);

Parameters

NameTypeDescription
newLowLatencyDelayuint16The new low latency delay.
usdnProtocolIUsdnProtocolThe address of the USDN protocol.

withdrawEther

Withdraws the ether balance of this contract.

This contract can receive funds but is not designed to hold them. So this function can be used if there's an error and funds remain after a call.

function withdrawEther(address to) external onlyRole(ADMIN_ROLE);

Parameters

NameTypeDescription
toaddressThe address to send the ether to.

_getLowLatencyPrice

Gets the price from the low-latency oracle.

function _getLowLatencyPrice(bytes calldata data, uint128 actionTimestamp, PriceAdjustment dir, uint128 targetLimit)
    internal
    virtual
    returns (PriceInfo memory price_);

Parameters

NameTypeDescription
databytesThe signed price update data.
actionTimestampuint128The timestamp of the action corresponding to the price. If zero, then we must accept all prices younger than the recent price delay.
dirPriceAdjustmentThe direction for the low latency price adjustment.
targetLimituint128The most recent timestamp a price can have (can be zero if actionTimestamp is zero).

Returns

NameTypeDescription
price_PriceInfoThe price from the low-latency oracle, adjusted according to the price adjustment direction.

_getInitiateActionPrice

Gets the price for an initiate action of the protocol.

function _getInitiateActionPrice(bytes calldata data, PriceAdjustment dir)
    internal
    virtual
    returns (PriceInfo memory price_);

Parameters

NameTypeDescription
databytesThe low latency data.
dirPriceAdjustmentThe direction to adjust the price (when using a low latency price).

Returns

NameTypeDescription
price_PriceInfoThe price to use for the user action.

_getValidateActionPrice

Gets the price for a validate action of the protocol.

If the low latency delay is not exceeded, validate the price with the low-latency oracle(s). Else, get the specified roundId on-chain price from Chainlink. In case of chainlink price, we don't have a price adjustment, so both neutralPrice and price are equal.

function _getValidateActionPrice(bytes calldata data, uint128 targetTimestamp, PriceAdjustment dir)
    internal
    virtual
    returns (PriceInfo memory price_);

Parameters

NameTypeDescription
databytesAn optional low-latency price update or a chainlink roundId (abi-encoded uint80).
targetTimestampuint128The timestamp of the initiate action.
dirPriceAdjustmentThe direction to adjust the price (when using a low latency price).

Returns

NameTypeDescription
price_PriceInfoThe price to use for the user action.

_getLiquidationPrice

Gets the price from the low-latency oracle.

function _getLiquidationPrice(bytes calldata data) internal virtual returns (PriceInfo memory price_);

Parameters

NameTypeDescription
databytesThe signed price update data.

Returns

NameTypeDescription
price_PriceInfoThe low-latency oracle price.

_validateChainlinkRoundId

Checks that the given round ID is valid and returns its corresponding price data.

Round IDs are not necessarily consecutive, so additional computing can be necessary to find the previous round ID.

function _validateChainlinkRoundId(uint128 targetLimit, uint80 roundId)
    internal
    view
    returns (ChainlinkPriceInfo memory providedRoundPrice_);

Parameters

NameTypeDescription
targetLimituint128The timestamp of the initiate action + _lowLatencyDelay.
roundIduint80The round ID to validate.

Returns

NameTypeDescription
providedRoundPrice_ChainlinkPriceInfoThe price data of the provided round ID.

_isPythData

Checks if the passed calldata corresponds to a Pyth message.

function _isPythData(bytes calldata data) internal pure returns (bool isPythData_);

Parameters

NameTypeDescription
databytesThe calldata pointer to the message.

Returns

NameTypeDescription
isPythData_boolWhether the data is a valid Pyth message or not.

OracleMiddlewareWithDataStreams

Git Source

Inherits: CommonOracleMiddleware, ChainlinkDataStreamsOracle, IOracleMiddlewareWithDataStreams

This contract is used to get the price of an asset from different oracles. It is used by the USDN protocol to get the price of the USDN underlying asset.

Functions

constructor

constructor(
    address pythContract,
    bytes32 pythFeedId,
    address chainlinkPriceFeed,
    uint256 chainlinkTimeElapsedLimit,
    address chainlinkProxyVerifierAddress,
    bytes32 chainlinkStreamId
)
    CommonOracleMiddleware(pythContract, pythFeedId, chainlinkPriceFeed, chainlinkTimeElapsedLimit)
    ChainlinkDataStreamsOracle(chainlinkProxyVerifierAddress, chainlinkStreamId);

Parameters

NameTypeDescription
pythContractaddressAddress of the Pyth contract.
pythFeedIdbytes32The Pyth price feed ID for the asset.
chainlinkPriceFeedaddressThe address of the Chainlink price feed.
chainlinkTimeElapsedLimituint256The duration after which a Chainlink price is considered stale.
chainlinkProxyVerifierAddressaddressThe address of the Chainlink proxy verifier contract.
chainlinkStreamIdbytes32The supported Chainlink data stream ID.

validationCost

Returns the cost of one price validation for the given action (in native token).

function validationCost(bytes calldata data, Types.ProtocolAction)
    public
    view
    override(CommonOracleMiddleware, IBaseOracleMiddleware)
    returns (uint256 result_);

Parameters

NameTypeDescription
databytesPrice data for which to get the fee.
<none>Types.ProtocolAction

Returns

NameTypeDescription
result_uint256cost_ The cost of one price validation (in native token).

setDataStreamsRecentPriceDelay

Sets the amount of time after which we do not consider a price as recent for Chainlink.

function setDataStreamsRecentPriceDelay(uint64 newDelay) external onlyRole(ADMIN_ROLE);

Parameters

NameTypeDescription
newDelayuint64The maximum age of a price to be considered recent.

_getLowLatencyPrice

Gets the price from the low-latency oracle.

function _getLowLatencyPrice(bytes calldata payload, uint128 actionTimestamp, PriceAdjustment dir, uint128 targetLimit)
    internal
    virtual
    override
    returns (PriceInfo memory price_);

Parameters

NameTypeDescription
payloadbytes
actionTimestampuint128The timestamp of the action corresponding to the price. If zero, then we must accept all prices younger than the recent price delay.
dirPriceAdjustmentThe direction for the low latency price adjustment.
targetLimituint128The most recent timestamp a price can have (can be zero if actionTimestamp is zero).

Returns

NameTypeDescription
price_PriceInfoThe price from the low-latency oracle, adjusted according to the price adjustment direction.

_getInitiateActionPrice

Gets the price for an initiate action of the protocol.

If the data parameter is not empty, validate the price with the low latency oracle. Else, get the on-chain price from ChainlinkOracle and compare its timestamp with the latest seen Pyth price (cached). If Pyth is more recent, we return it. Otherwise, we return the Chainlink price. For the latter, we don't have a price adjustment, so both neutralPrice and price are equal.

function _getInitiateActionPrice(bytes calldata data, PriceAdjustment dir)
    internal
    override
    returns (PriceInfo memory price_);

Parameters

NameTypeDescription
databytesThe low latency data.
dirPriceAdjustmentThe direction to adjust the price (when using a low latency price).

Returns

NameTypeDescription
price_PriceInfoThe price to use for the user action.

_getLiquidationPrice

Gets the price from the low-latency oracle.

function _getLiquidationPrice(bytes calldata data) internal virtual override returns (PriceInfo memory price_);

Parameters

NameTypeDescription
databytesThe signed price update data.

Returns

NameTypeDescription
price_PriceInfoThe low-latency oracle price.

_convertPythPrice

Converts a formatted Pyth price into a PriceInfo.

function _convertPythPrice(FormattedPythPrice memory pythPrice) internal pure returns (PriceInfo memory price_);

Parameters

NameTypeDescription
pythPriceFormattedPythPriceThe formatted Pyth price containing the price and publish time.

Returns

NameTypeDescription
price_PriceInfoThe PriceInfo with the price, neutral price, and timestamp set from the Pyth price data.

_adjustDataStreamPrice

Applies the ask, bid or price according to the dir direction.

function _adjustDataStreamPrice(FormattedDataStreamsPrice memory formattedPrice, PriceAdjustment dir)
    internal
    pure
    returns (PriceInfo memory price_);

Parameters

NameTypeDescription
formattedPriceFormattedDataStreamsPriceThe Chainlink data streams formatted price.
dirPriceAdjustmentThe direction to adjust the price.

Returns

NameTypeDescription
price_PriceInfoThe adjusted price according to the direction.

OracleMiddlewareWithPyth

Git Source

Inherits: CommonOracleMiddleware, IOracleMiddlewareWithPyth

This contract is used to get the price of an asset from different oracles. It is used by the USDN protocol to get the price of the USDN underlying asset.

State Variables

BPS_DIVISOR

Gets the denominator for the variables using basis points as a unit.

uint16 public constant BPS_DIVISOR = 10_000;

MAX_CONF_RATIO

Gets the maximum value for _confRatioBps.

uint16 public constant MAX_CONF_RATIO = BPS_DIVISOR * 2;

_confRatioBps

Ratio to applied to the Pyth confidence interval (in basis points).

uint16 internal _confRatioBps = 4000;

Functions

constructor

constructor(address pythContract, bytes32 pythFeedId, address chainlinkPriceFeed, uint256 chainlinkTimeElapsedLimit)
    CommonOracleMiddleware(pythContract, pythFeedId, chainlinkPriceFeed, chainlinkTimeElapsedLimit);

Parameters

NameTypeDescription
pythContractaddressAddress of the Pyth contract.
pythFeedIdbytes32The Pyth price feed ID for the asset.
chainlinkPriceFeedaddressAddress of the Chainlink price feed.
chainlinkTimeElapsedLimituint256The duration after which a Chainlink price is considered stale.

getConfRatioBps

Gets the confidence ratio.

This ratio is used to apply a specific portion of the confidence interval provided by an oracle, which is used to adjust the precision of predictions or estimations.

function getConfRatioBps() external view returns (uint16 ratio_);

Returns

NameTypeDescription
ratio_uint16The confidence ratio (in basis points).

setConfRatio

Sets the confidence ratio.

The new value should be lower than MAX_CONF_RATIO.

function setConfRatio(uint16 newConfRatio) external onlyRole(ADMIN_ROLE);

Parameters

NameTypeDescription
newConfRatiouint16the new confidence ratio.

_getLowLatencyPrice

Gets the price from the low-latency oracle.

function _getLowLatencyPrice(bytes calldata data, uint128 actionTimestamp, PriceAdjustment dir, uint128 targetLimit)
    internal
    virtual
    override
    returns (PriceInfo memory price_);

Parameters

NameTypeDescription
databytesThe signed price update data.
actionTimestampuint128The timestamp of the action corresponding to the price. If zero, then we must accept all prices younger than the recent price delay.
dirPriceAdjustmentThe direction for the low latency price adjustment.
targetLimituint128The most recent timestamp a price can have (can be zero if actionTimestamp is zero).

Returns

NameTypeDescription
price_PriceInfoThe price from the low-latency oracle, adjusted according to the price adjustment direction.

_getInitiateActionPrice

Gets the price for an initiate action of the protocol.

If the data parameter is not empty, validate the price with the low latency oracle. Else, get the on-chain price from ChainlinkOracle and compare its timestamp with the latest seen Pyth price (cached). If Pyth is more recent, we return it. Otherwise, we return the Chainlink price. For the latter, we don't have a price adjustment, so both neutralPrice and price are equal.

function _getInitiateActionPrice(bytes calldata data, PriceAdjustment dir)
    internal
    override
    returns (PriceInfo memory price_);

Parameters

NameTypeDescription
databytesThe low latency data.
dirPriceAdjustmentThe direction to adjust the price (when using a low latency price).

Returns

NameTypeDescription
price_PriceInfoThe price to use for the user action.

_adjustPythPrice

Applies the confidence interval in the dir direction, scaled by the configured _confRatioBps.

function _adjustPythPrice(FormattedPythPrice memory pythPrice, PriceAdjustment dir)
    internal
    view
    returns (PriceInfo memory price_);

Parameters

NameTypeDescription
pythPriceFormattedPythPriceThe formatted Pyth price object.
dirPriceAdjustmentThe direction of the confidence interval to apply.

Returns

NameTypeDescription
price_PriceInfoThe adjusted price according to the confidence interval and confidence ratio.

OracleMiddlewareWithRedstone

Git Source

Inherits: IOracleMiddlewareWithRedstone, OracleMiddlewareWithPyth, RedstoneOracle

This contract is used to get the price of an asset from different oracles. It is used by the USDN protocol to get the price of the USDN underlying asset.

This contract allows users to use the Redstone oracle and exists in case the Pyth infrastructure fails and we need a temporary solution. Redstone and Pyth are used concurrently, which could introduce arbitrage opportunities.

State Variables

_penaltyBps

The penalty for using a non-Pyth price with low latency oracle (in basis points).

uint16 internal _penaltyBps = 25;

Functions

constructor

constructor(
    address pythContract,
    bytes32 pythFeedId,
    bytes32 redstoneFeedId,
    address chainlinkPriceFeed,
    uint256 chainlinkTimeElapsedLimit
)
    OracleMiddlewareWithPyth(pythContract, pythFeedId, chainlinkPriceFeed, chainlinkTimeElapsedLimit)
    RedstoneOracle(redstoneFeedId);

Parameters

NameTypeDescription
pythContractaddressAddress of the Pyth contract.
pythFeedIdbytes32The Pyth price feed ID for the asset.
redstoneFeedIdbytes32The Redstone price feed ID for the asset.
chainlinkPriceFeedaddressAddress of the Chainlink price feed.
chainlinkTimeElapsedLimituint256The duration after which a Chainlink price is considered stale.

getPenaltyBps

Gets the penalty for using a non-Pyth price with low latency oracle (in basis points)

function getPenaltyBps() external view returns (uint16 penaltyBps_);

Returns

NameTypeDescription
penaltyBps_uint16The penalty (in basis points).

_getLowLatencyPrice

Gets the price from the low-latency oracle (Pyth or Redstone).

function _getLowLatencyPrice(bytes calldata data, uint128 actionTimestamp, PriceAdjustment dir, uint128 targetLimit)
    internal
    override
    returns (PriceInfo memory price_);

Parameters

NameTypeDescription
databytes
actionTimestampuint128The timestamp of the action corresponding to the price. If zero, then we must accept all prices younger than _pythRecentPriceDelay or _redstoneRecentPriceDelay.
dirPriceAdjustment
targetLimituint128

_adjustRedstonePrice

Applies the confidence interval in the dir direction, applying the penalty _penaltyBps

function _adjustRedstonePrice(RedstonePriceInfo memory redstonePrice, PriceAdjustment dir)
    internal
    view
    returns (PriceInfo memory price_);

Parameters

NameTypeDescription
redstonePriceRedstonePriceInfoThe formatted Redstone price object.
dirPriceAdjustmentThe direction to apply the penalty.

Returns

NameTypeDescription
price_PriceInfoThe adjusted price according to the penalty.

setRedstoneRecentPriceDelay

Sets the Redstone recent price delay.

function setRedstoneRecentPriceDelay(uint48 newDelay) external onlyRole(ADMIN_ROLE);

Parameters

NameTypeDescription
newDelayuint48The maximum age of a price to be considered recent.

setPenaltyBps

Sets the penalty (in basis points).

function setPenaltyBps(uint16 newPenaltyBps) external onlyRole(ADMIN_ROLE);

Parameters

NameTypeDescription
newPenaltyBpsuint16The new penalty.

WstEthOracleMiddlewareWithDataStreams

Git Source

Inherits: OracleMiddlewareWithDataStreams

This contract is used to get the price of wstETH from the ETH price or the wstETH price directly.

State Variables

_wstETH

The wstETH contract.

IWstETH internal immutable _wstETH;

Functions

constructor

constructor(
    address pythContract,
    bytes32 pythFeedId,
    address chainlinkPriceFeed,
    address wstETH,
    uint256 chainlinkTimeElapsedLimit,
    address chainlinkProxyVerifierAddress,
    bytes32 chainlinkStreamId
)
    OracleMiddlewareWithDataStreams(
        pythContract,
        pythFeedId,
        chainlinkPriceFeed,
        chainlinkTimeElapsedLimit,
        chainlinkProxyVerifierAddress,
        chainlinkStreamId
    );

Parameters

NameTypeDescription
pythContractaddressThe address of the Pyth contract.
pythFeedIdbytes32The ETH/USD Pyth price feed ID for the asset.
chainlinkPriceFeedaddressThe address of the Chainlink ETH/USD price feed.
wstETHaddressThe address of the wstETH contract.
chainlinkTimeElapsedLimituint256The duration after which a Chainlink price is considered stale.
chainlinkProxyVerifierAddressaddressThe address of the Chainlink proxy verifier contract.
chainlinkStreamIdbytes32The supported Chainlink wstETH/USD data stream ID.

parseAndValidatePrice

Parses and validates data, returns the corresponding price data, applying ETH/wstETH ratio if the price is in ETH.

The data format is specific to the middleware and is simply forwarded from the user transaction's calldata. If needed, the wstETH price is calculated as follows: ethPrice x stEthPerToken / 1 ether. A fee amounting to exactly {validationCost} (with the same data and action) must be sent or the transaction will revert.

function parseAndValidatePrice(
    bytes32 actionId,
    uint128 targetTimestamp,
    Types.ProtocolAction action,
    bytes calldata data
) public payable virtual override(IBaseOracleMiddleware, CommonOracleMiddleware) returns (PriceInfo memory);

Parameters

NameTypeDescription
actionIdbytes32A unique identifier for the current action. This identifier can be used to link an Initiate call with the corresponding Validate call.
targetTimestampuint128The target timestamp for validating the price data. For validation actions, this is the timestamp of the initiation.
actionTypes.ProtocolActionType of action for which the price is requested. The middleware may use this to alter the validation of the price or the returned price.
databytesThe data to be used to communicate with oracles, the format varies from middleware to middleware and can be different depending on the action.

Returns

NameTypeDescription
<none>PriceInforesult_ The price and timestamp as PriceInfo.

WstEthOracleMiddlewareWithPyth

Git Source

Inherits: OracleMiddlewareWithPyth

This contract is used to get the price of wstETH from the ETH price oracle.

State Variables

_wstEth

The wstETH contract.

IWstETH internal immutable _wstEth;

Functions

constructor

constructor(
    address pythContract,
    bytes32 pythPriceID,
    address chainlinkPriceFeed,
    address wstETH,
    uint256 chainlinkTimeElapsedLimit
) OracleMiddlewareWithPyth(pythContract, pythPriceID, chainlinkPriceFeed, chainlinkTimeElapsedLimit);

Parameters

NameTypeDescription
pythContractaddressThe address of the Pyth contract.
pythPriceIDbytes32The ID of the ETH Pyth price feed.
chainlinkPriceFeedaddressThe address of the ETH Chainlink price feed.
wstETHaddressThe address of the wstETH contract.
chainlinkTimeElapsedLimituint256The duration after which a Chainlink price is considered stale.

parseAndValidatePrice

Parses and validates data, returns the corresponding price data by applying ETH/wstETH ratio.

The data format is specific to the middleware and is simply forwarded from the user transaction's calldata. Wsteth price is calculated as follows: ethPrice x stEthPerToken / 1 ether. A fee amounting to exactly {validationCost} (with the same data and action) must be sent or the transaction will revert.

function parseAndValidatePrice(
    bytes32 actionId,
    uint128 targetTimestamp,
    Types.ProtocolAction action,
    bytes calldata data
) public payable virtual override(IBaseOracleMiddleware, CommonOracleMiddleware) returns (PriceInfo memory);

Parameters

NameTypeDescription
actionIdbytes32A unique identifier for the current action. This identifier can be used to link an Initiate call with the corresponding Validate call.
targetTimestampuint128The target timestamp for validating the price data. For validation actions, this is the timestamp of the initiation.
actionTypes.ProtocolActionType of action for which the price is requested. The middleware may use this to alter the validation of the price or the returned price.
databytesThe data to be used to communicate with oracles, the format varies from middleware to middleware and can be different depending on the action.

Returns

NameTypeDescription
<none>PriceInforesult_ The price and timestamp as PriceInfo.

WusdnToEthOracleMiddlewareWithDataStreams

Git Source

Inherits: OracleMiddlewareWithDataStreams

This contract is used to get the "inverse" price in number of ETH per WUSDN, so that it can be used for a shorting version of the USDN protocol with WUSDN as the underlying asset.

This version uses Pyth or Chainlink Data Streams for liquidations, and only Chainlink Data Streams for validation actions.

State Variables

ONE_DOLLAR

One dollar with the middleware decimals.

uint256 internal constant ONE_DOLLAR = 10 ** MIDDLEWARE_DECIMALS;

USDN_MAX_DIVISOR

Max divisor from the USDN token (as constant for gas optimisation).

uint256 internal constant USDN_MAX_DIVISOR = 1e18;

PRICE_NUMERATOR

Numerator for the price calculation in parseAndValidatePrice.

uint256 internal constant PRICE_NUMERATOR = 10 ** MIDDLEWARE_DECIMALS * ONE_DOLLAR * USDN_MAX_DIVISOR;

USDN

The USDN token address.

IUsdn internal immutable USDN;

Functions

constructor

constructor(
    address pythContract,
    bytes32 pythPriceID,
    address chainlinkPriceFeed,
    address usdnToken,
    uint256 chainlinkTimeElapsedLimit,
    address chainlinkProxyVerifierAddress,
    bytes32 chainlinkStreamId
)
    OracleMiddlewareWithDataStreams(
        pythContract,
        pythPriceID,
        chainlinkPriceFeed,
        chainlinkTimeElapsedLimit,
        chainlinkProxyVerifierAddress,
        chainlinkStreamId
    );

Parameters

NameTypeDescription
pythContractaddressThe address of the Pyth contract.
pythPriceIDbytes32The ID of the ETH Pyth price feed.
chainlinkPriceFeedaddressThe address of the ETH Chainlink price feed.
usdnTokenaddressThe address of the USDN token.
chainlinkTimeElapsedLimituint256The duration after which a Chainlink price is considered stale.
chainlinkProxyVerifierAddressaddressThe address of the Chainlink proxy verifier contract.
chainlinkStreamIdbytes32The Chainlink data stream ID for ETH/USD.

parseAndValidatePrice

Parse and validate data and returns the corresponding price data.

*This function returns an approximation of the price, so how much ETH each WUSDN token is worth. The exact formula would be to divide the $/WUSDN price by the $/ETH price, which would look like this (as a decimal number): p = pWUSDN / pETH = (pUSDN * MAX_DIVISOR / divisor) / pETH = (pUSDN * MAX_DIVISOR) / (pETH * divisor) = ((usdnVaultBalance * pWstETH / usdnTotalSupply) * MAX_DIVISOR) / (pETH * divisor) = (usdnVaultBalance * pETH * stETHRatio * MAX_DIVISOR) / (pETH * divisor * usdnTotalSupply) = (usdnVaultBalance * stETHRatio * MAX_DIVISOR) / (usdnTotalSupply * divisor) Because we don't have historical access to the vault balance, the stETH ratio, the USDN total supply and the USDN divisor, we must approximate some parameters. The following approximations are made:

  • The USDN price is $1
  • The USDN divisor's current value is valid (constant) for the period where we need to provide prices. This greatly simplifies the formula (with $1 and pETH having 18 decimals): p = ($1 * MAX_DIVISOR) / (pETH * divisor) = 1e18 * MAX_DIVISOR / (pETH * divisor) Since we want to represent this price as an integer with a fixed precision of 18 decimals, the number needs to be multiplied by 1e18. p_wei = 1e54 / (pETH * divisor) Because we re-use the logic of the {OracleMiddleware}, we need to invert the adjustment direction. So if an action in the original protocol requires that we add the confidence interval to the neutral price (e.g. to open a new long position), then this oracle middleware needs to subtract the same confidence interval from the neutral price to achieve the same effect, i.e. penalizing the user. This is because the ETH price is in the denominator of the formula.*
function parseAndValidatePrice(
    bytes32 actionId,
    uint128 targetTimestamp,
    Types.ProtocolAction action,
    bytes calldata data
) public payable virtual override(CommonOracleMiddleware, IBaseOracleMiddleware) returns (PriceInfo memory);

Parameters

NameTypeDescription
actionIdbytes32A unique identifier for the current action. This identifier can be used to link an Initiate call with the corresponding Validate call.
targetTimestampuint128The target timestamp for validating the price data. For validation actions, this is the timestamp of the initiation.
actionTypes.ProtocolActionType of action for which the price is requested. The middleware may use this to alter the validation of the price or the returned price.
databytesThe data to be used to communicate with oracles, the format varies from middleware to middleware and can be different depending on the action.

Returns

NameTypeDescription
<none>PriceInforesult_ The price and timestamp as PriceInfo.

WusdnToEthOracleMiddlewareWithPyth

Git Source

Inherits: OracleMiddlewareWithPyth

This contract is used to get the "inverse" price in number of ETH per WUSDN, so that it can be used for a shorting version of the USDN protocol with WUSDN as the underlying asset.

This version uses Pyth for low-latency prices used during validation actions and liquidations.

State Variables

ONE_DOLLAR

One dollar with the middleware decimals.

uint256 internal constant ONE_DOLLAR = 10 ** MIDDLEWARE_DECIMALS;

USDN_MAX_DIVISOR

Max divisor from the USDN token (as constant for gas optimisation).

uint256 internal constant USDN_MAX_DIVISOR = 1e18;

PRICE_NUMERATOR

Numerator for the price calculation in parseAndValidatePrice.

uint256 internal constant PRICE_NUMERATOR = 10 ** MIDDLEWARE_DECIMALS * ONE_DOLLAR * USDN_MAX_DIVISOR;

USDN

The USDN token address.

IUsdn internal immutable USDN;

Functions

constructor

constructor(
    address pythContract,
    bytes32 pythPriceID,
    address chainlinkPriceFeed,
    address usdnToken,
    uint256 chainlinkTimeElapsedLimit
) OracleMiddlewareWithPyth(pythContract, pythPriceID, chainlinkPriceFeed, chainlinkTimeElapsedLimit);

Parameters

NameTypeDescription
pythContractaddressThe address of the Pyth contract.
pythPriceIDbytes32The ID of the ETH Pyth price feed.
chainlinkPriceFeedaddressThe address of the ETH Chainlink price feed.
usdnTokenaddressThe address of the USDN token.
chainlinkTimeElapsedLimituint256The duration after which a Chainlink price is considered stale.

parseAndValidatePrice

Parse and validate data and returns the corresponding price data.

*This function returns an approximation of the price, so how much ETH each WUSDN token is worth. The exact formula would be to divide the $/WUSDN price by the $/ETH price, which would look like this (as a decimal number): p = pWUSDN / pETH = (pUSDN * MAX_DIVISOR / divisor) / pETH = (pUSDN * MAX_DIVISOR) / (pETH * divisor) = ((usdnVaultBalance * pWstETH / usdnTotalSupply) * MAX_DIVISOR) / (pETH * divisor) = (usdnVaultBalance * pETH * stETHRatio * MAX_DIVISOR) / (pETH * divisor * usdnTotalSupply) = (usdnVaultBalance * stETHRatio * MAX_DIVISOR) / (usdnTotalSupply * divisor) Because we don't have historical access to the vault balance, the stETH ratio, the USDN total supply and the USDN divisor, we must approximate some parameters. The following approximations are made:

  • The USDN price is $1
  • The USDN divisor's current value is valid (constant) for the period where we need to provide prices. This greatly simplifies the formula (with $1 and pETH having 18 decimals): p = ($1 * MAX_DIVISOR) / (pETH * divisor) = 1e18 * MAX_DIVISOR / (pETH * divisor) Since we want to represent this price as an integer with a fixed precision of 18 decimals, the number needs to be multiplied by 1e18. p_wei = 1e54 / (pETH * divisor) Because we re-use the logic of the {OracleMiddleware}, we need to invert the adjustment direction. So if an action in the original protocol requires that we add the confidence interval to the neutral price (e.g. to open a new long position), then this oracle middleware needs to subtract the same confidence interval from the neutral price to achieve the same effect, i.e. penalizing the user. This is because the ETH price is in the denominator of the formula.*
function parseAndValidatePrice(
    bytes32 actionId,
    uint128 targetTimestamp,
    Types.ProtocolAction action,
    bytes calldata data
) public payable virtual override(CommonOracleMiddleware, IBaseOracleMiddleware) returns (PriceInfo memory);

Parameters

NameTypeDescription
actionIdbytes32A unique identifier for the current action. This identifier can be used to link an Initiate call with the corresponding Validate call.
targetTimestampuint128The target timestamp for validating the price data. For validation actions, this is the timestamp of the initiation.
actionTypes.ProtocolActionType of action for which the price is requested. The middleware may use this to alter the validation of the price or the returned price.
databytesThe data to be used to communicate with oracles, the format varies from middleware to middleware and can be different depending on the action.

Returns

NameTypeDescription
<none>PriceInforesult_ The price and timestamp as PriceInfo.

Contents

Rebalancer

Git Source

Inherits: Ownable2Step, ReentrancyGuard, ERC165, IOwnershipCallback, IRebalancer, EIP712

The goal of this contract is to push the imbalance of the USDN protocol back to an healthy level when liquidations reduce long trading exposure. It will manage a single position with sufficient trading exposure to re-balance the protocol after liquidations. The position will be closed and reopened as needed, utilizing new and existing funds, whenever the imbalance reaches a defined threshold.

State Variables

MULTIPLIER_FACTOR

Gets the value of the multiplier at 1x.

Also helps to normalize the result of multiplier calculations.

uint256 public constant MULTIPLIER_FACTOR = 1e38;

MAX_ACTION_COOLDOWN

The maximum cooldown time between actions.

uint256 public constant MAX_ACTION_COOLDOWN = 48 hours;

MAX_CLOSE_DELAY

Gets the maximum amount of seconds to wait to execute a initiateClosePosition since a new rebalancer long position has been created.

uint256 public constant MAX_CLOSE_DELAY = 7 days;

INITIATE_CLOSE_TYPEHASH

The EIP712 initiateClosePosition typehash.

By including this hash into the EIP712 message for this domain, this can be used together with ECDSA-recover to obtain the signer of a message.

bytes32 public constant INITIATE_CLOSE_TYPEHASH = keccak256(
    "InitiateClosePositionDelegation(uint88 amount,address to,uint256 userMinPrice,uint256 deadline,address depositOwner,address depositCloser,uint256 nonce)"
);

_asset

The address of the asset used by the USDN protocol.

IERC20Metadata internal immutable _asset;

_assetDecimals

The number of decimals of the asset used by the USDN protocol.

uint256 internal immutable _assetDecimals;

_usdnProtocol

The address of the USDN protocol.

IUsdnProtocol internal immutable _usdnProtocol;

_maxLeverage

The maximum leverage that a position can have.

uint256 internal _maxLeverage = 3 * 10 ** Constants.LEVERAGE_DECIMALS;

_minAssetDeposit

The minimum amount of assets to be deposited by a user.

uint256 internal _minAssetDeposit;

_closeLockedUntil

The timestamp by which a user must wait to perform a initiateClosePosition.

This value will be updated each time a new rebalancer long position is created.

uint256 internal _closeLockedUntil;

_timeLimits

The time limits for the initiate/validate process of deposits and withdrawals.

The user must wait validationDelay after the initiate action to perform the corresponding validate action. If the validationDeadline has passed, the user is blocked from interacting until the cooldown duration has elapsed (since the moment of the initiate action). After the cooldown, in case of a deposit action, the user must withdraw their funds with resetDepositAssets. After the cooldown, in case of a withdrawal action, the user can initiate a new withdrawal again.

TimeLimits internal _timeLimits = TimeLimits({
    validationDelay: 24 seconds,
    validationDeadline: 20 minutes,
    actionCooldown: 4 hours,
    closeDelay: 4 hours
});

_positionVersion

The current position version.

uint128 internal _positionVersion;

_pendingAssetsAmount

The amount of assets waiting to be used in the next version of the position.

uint128 internal _pendingAssetsAmount;

_lastLiquidatedVersion

The version of the last position that got liquidated.

uint128 internal _lastLiquidatedVersion;

_userDeposit

The data about the assets deposited in this contract by users.

mapping(address => UserDeposit) internal _userDeposit;

_positionData

The data for the specific version of the position.

mapping(uint256 => PositionData) internal _positionData;

_nonce

The user EIP712 nonce.

Check getNonce for more information.

mapping(address => uint256) internal _nonce;

Functions

onlyAdmin

Reverts if the caller is not the USDN protocol nor the owner.

modifier onlyAdmin();

onlyProtocol

Reverts if the caller is not the USDN protocol.

modifier onlyProtocol();

constructor

constructor(IUsdnProtocol usdnProtocol) Ownable(msg.sender) EIP712("Rebalancer", "1");

Parameters

NameTypeDescription
usdnProtocolIUsdnProtocolThe address of the USDN protocol.

receive

Allows this contract to receive ether sent by the USDN protocol.

receive() external payable onlyProtocol;

getAsset

Returns the address of the asset used by the USDN protocol.

function getAsset() external view returns (IERC20Metadata asset_);

Returns

NameTypeDescription
asset_IERC20MetadataThe address of the asset used by the USDN protocol.

getUsdnProtocol

Returns the address of the USDN protocol.

function getUsdnProtocol() external view returns (IUsdnProtocol protocol_);

Returns

NameTypeDescription
protocol_IUsdnProtocolThe address of the USDN protocol.

getPendingAssetsAmount

Returns the amount of assets deposited and waiting for the next version to be opened.

function getPendingAssetsAmount() external view returns (uint128 pendingAssetsAmount_);

Returns

NameTypeDescription
pendingAssetsAmount_uint128The amount of pending assets.

getPositionVersion

Returns the version of the current position (0 means no position open).

function getPositionVersion() external view returns (uint128 version_);

Returns

NameTypeDescription
version_uint128The version of the current position.

getPositionMaxLeverage

Returns the maximum leverage the rebalancer position can have.

In some edge cases during the calculation of the rebalancer position's tick, this value might be exceeded by a slight margin.

function getPositionMaxLeverage() external view returns (uint256 maxLeverage_);

Returns

NameTypeDescription
maxLeverage_uint256The maximum leverage.

getCurrentStateData

Returns the necessary data for the USDN protocol to update the position.

function getCurrentStateData()
    external
    view
    returns (uint128 pendingAssets_, uint256 maxLeverage_, Types.PositionId memory currentPosId_);

Returns

NameTypeDescription
pendingAssets_uint128The amount of assets that are pending inclusion in the protocol.
maxLeverage_uint256The maximum leverage of the rebalancer.
currentPosId_Types.PositionIdThe ID of the current position (tick == NO_POSITION_TICK if no position).

getLastLiquidatedVersion

Returns the version of the last position that got liquidated.

0 means no liquidated version yet.

function getLastLiquidatedVersion() external view returns (uint128 version_);

Returns

NameTypeDescription
version_uint128The version of the last position that got liquidated.

getMinAssetDeposit

Returns the minimum amount of assets a user can deposit in the rebalancer.

function getMinAssetDeposit() external view returns (uint256 minAssetDeposit_);

Returns

NameTypeDescription
minAssetDeposit_uint256The minimum amount of assets that can be deposited by a user.

getPositionData

Returns the data of the provided version of the position.

function getPositionData(uint128 version) external view returns (PositionData memory positionData_);

Parameters

NameTypeDescription
versionuint128The version of the position.

Returns

NameTypeDescription
positionData_PositionDataThe data for the provided version of the position.

getTimeLimits

Gets the time limits for the action validation process.

function getTimeLimits() external view returns (TimeLimits memory timeLimits_);

Returns

NameTypeDescription
timeLimits_TimeLimitsThe time limits.

getUserDepositData

Returns the data regarding the assets deposited by the provided user.

function getUserDepositData(address user) external view returns (UserDeposit memory data_);

Parameters

NameTypeDescription
useraddressThe address of the user.

Returns

NameTypeDescription
data_UserDepositThe data regarding the assets deposited by the provided user.

getNonce

Gets the nonce a user can use to generate a delegation signature.

This is to prevent replay attacks when using an EIP712 delegation signature.

function getNonce(address user) external view returns (uint256 nonce_);

Parameters

NameTypeDescription
useraddressThe user address of the deposited amount in the rebalancer.

Returns

NameTypeDescription
nonce_uint256The user's nonce.

domainSeparatorV4

Gets the domain separator v4 used for EIP-712 signatures.

function domainSeparatorV4() external view returns (bytes32 domainSeparator_);

Returns

NameTypeDescription
domainSeparator_bytes32The domain separator v4.

getCloseLockedUntil

Gets the timestamp by which a user must wait to perform a initiateClosePosition.

function getCloseLockedUntil() external view returns (uint256 timestamp_);

Returns

NameTypeDescription
timestamp_uint256The timestamp until which the position cannot be closed.

increaseAssetAllowance

Increases the allowance of assets for the USDN protocol spender by addAllowance.

function increaseAssetAllowance(uint256 addAllowance) external;

Parameters

NameTypeDescription
addAllowanceuint256Amount to add to the allowance of the USDN Protocol.

initiateDepositAssets

Deposits assets into this contract to be included in the next position after validation

The user must call validateDepositAssets between _timeLimits.validationDelay and. _timeLimits.validationDeadline seconds after this action.

function initiateDepositAssets(uint88 amount, address to) external nonReentrant;

Parameters

NameTypeDescription
amountuint88The amount in assets that will be deposited into the rebalancer.
toaddressThe address which will need to validate and which will own the position.

validateDepositAssets

Validates a deposit to be included in the next position version.

The to from the initiateDepositAssets must call this function between _timeLimits.validationDelay and _timeLimits.validationDeadline seconds after the initiate action. After that, the user must wait until _timeLimits.actionCooldown seconds has elapsed, and then can call resetDepositAssets to retrieve their assets.

function validateDepositAssets() external nonReentrant;

resetDepositAssets

Retrieves the assets for a failed deposit due to waiting too long before calling validateDepositAssets.

The user must wait _timeLimits.actionCooldown since the initiateDepositAssets before calling this function.

function resetDepositAssets() external nonReentrant;

initiateWithdrawAssets

Withdraws assets that were not yet included in a position.

The user must call validateWithdrawAssets between _timeLimits.validationDelay and _timeLimits.validationDeadline seconds after this action.

function initiateWithdrawAssets() external nonReentrant;

validateWithdrawAssets

Validates a withdrawal of assets that were not yet included in a position.

The user must call this function between _timeLimits.validationDelay and _timeLimits.validationDeadline seconds after initiateWithdrawAssets. After that, the user must wait until the cooldown has elapsed, and then can call initiateWithdrawAssets again or wait to be included in the next position.

function validateWithdrawAssets(uint88 amount, address to) external nonReentrant;

Parameters

NameTypeDescription
amountuint88The amount of assets to withdraw.
toaddressThe recipient of the assets.

initiateClosePosition

Closes the provided amount from the current rebalancer's position.

The rebalancer allows partially closing its position to withdraw the user's assets + PnL. The remaining amount needs to be above _minAssetDeposit. The validator is always the msg.sender, which means the user must call validateClosePosition on the protocol side after calling this function.

function initiateClosePosition(
    uint88 amount,
    address to,
    address payable validator,
    uint256 userMinPrice,
    uint256 deadline,
    bytes calldata currentPriceData,
    Types.PreviousActionsData calldata previousActionsData,
    bytes calldata delegationData
) external payable nonReentrant returns (Types.LongActionOutcome outcome_);

Parameters

NameTypeDescription
amountuint88The amount to close relative to the amount deposited.
toaddressThe recipient of the assets.
validatoraddress payableThe address that should validate the open position.
userMinPriceuint256The minimum price at which the position can be closed.
deadlineuint256The deadline of the close position to be initiated.
currentPriceDatabytesThe current price data.
previousActionsDataTypes.PreviousActionsDataThe data needed to validate actionable pending actions.
delegationDatabytesAn optional delegation data that include the depositOwner and an EIP712 signature to provide when closing a position on the owner's behalf. If used, it needs to be encoded with abi.encode(depositOwner, abi.encodePacked(r, s, v)).

Returns

NameTypeDescription
outcome_Types.LongActionOutcomeThe outcome of the UsdnProtocol's initiateClosePosition call, check initiateClosePosition for more details.

_refundEther

Refunds any ether in this contract to the caller.

This contract should not hold any ether so any sent to it belongs to the current caller.

function _refundEther() internal;

updatePosition

Indicates that the previous version of the position was closed and a new one was opened.

If previousPosValue equals 0, it means the previous version got liquidated.

function updatePosition(Types.PositionId calldata newPosId, uint128 previousPosValue)
    external
    onlyProtocol
    nonReentrant;

Parameters

NameTypeDescription
newPosIdTypes.PositionIdThe position ID of the new position.
previousPosValueuint128The amount of assets left in the previous position.

setPositionMaxLeverage

Updates the max leverage a position can have.

newMaxLeverage must be between the min and max leverage of the USDN protocol. This function can only be called by the owner of the contract.

function setPositionMaxLeverage(uint256 newMaxLeverage) external onlyOwner;

Parameters

NameTypeDescription
newMaxLeverageuint256The new max leverage.

setMinAssetDeposit

Sets the minimum amount of assets to be deposited by a user.

The new minimum amount must be greater than or equal to the minimum long position of the USDN protocol. This function can only be called by the owner or the USDN protocol.

function setMinAssetDeposit(uint256 minAssetDeposit) external onlyAdmin;

Parameters

NameTypeDescription
minAssetDeposituint256The new minimum amount of assets to be deposited.

setTimeLimits

Sets the various time limits in seconds.

This function can only be called by the owner of the contract.

function setTimeLimits(uint64 validationDelay, uint64 validationDeadline, uint64 actionCooldown, uint64 closeDelay)
    external
    onlyOwner;

Parameters

NameTypeDescription
validationDelayuint64The amount of time to wait before an initiate can be validated.
validationDeadlineuint64The amount of time a user has to validate an initiate.
actionCooldownuint64The amount of time to wait after the deadline has passed before trying again.
closeDelayuint64The close delay that will be applied to the next long position opening.

ownershipCallback

Called by the USDN protocol on the new position owner after an ownership transfer occurs.

Implementers can use this callback to perform actions triggered by the ownership change.

function ownershipCallback(address, Types.PositionId calldata) external pure;

Parameters

NameTypeDescription
<none>address
<none>Types.PositionId

supportsInterface

Query if a contract implements an interface

Interface identification is specified in ERC-165. This function uses less than 30,000 gas.

function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(ERC165, IERC165)
    returns (bool isSupported_);

Parameters

NameTypeDescription
interfaceIdbytes4

Returns

NameTypeDescription
isSupported_booltrue if the contract implements interfaceID and interfaceID is not 0xffffffff, false otherwise

_checkValidationTime

Checks if the validate action happens between the validation delay and the validation deadline.

If the block timestamp is before initiateTimestamp + validationDelay, the function will revert. If the block timestamp is after initiateTimestamp + validationDeadline, the function will revert.

function _checkValidationTime(uint40 initiateTimestamp) internal view;

Parameters

NameTypeDescription
initiateTimestampuint40The timestamp of the initiate action.

_verifyInitiateCloseDelegation

Performs the initiateClosePosition EIP712 delegation signature verification.

Reverts if the function arguments don't match those included in the signature and if the signer isn't the owner of the deposit.

function _verifyInitiateCloseDelegation(
    uint88 amount,
    address to,
    uint256 userMinPrice,
    uint256 deadline,
    bytes calldata delegationData
) internal returns (address depositOwner_);

Parameters

NameTypeDescription
amountuint88The amount to close relative to the amount deposited.
toaddressThe recipient of the assets.
userMinPriceuint256The minimum price at which the position can be closed, not guaranteed.
deadlineuint256The deadline of the close position to be initiated.
delegationDatabytesThe delegation data that should include the depositOwner and the delegation signature.

Returns

NameTypeDescription
depositOwner_addressThe owner of the assets deposited in the rebalancer.

_initiateClosePosition

Closes a user deposited amount of the current UsdnProtocol rebalancer position.

function _initiateClosePosition(
    InitiateCloseData memory data,
    bytes calldata currentPriceData,
    Types.PreviousActionsData calldata previousActionsData,
    bytes calldata delegationData
) internal returns (Types.LongActionOutcome outcome_);

Parameters

NameTypeDescription
dataInitiateCloseDataThe structure to hold the transient data during initiateClosePosition.
currentPriceDatabytesThe current price data (used to calculate the temporary leverage and entry price, pending validation).
previousActionsDataTypes.PreviousActionsDataThe data needed to validate actionable pending actions.
delegationDatabytesAn optional delegation data that include the depositOwner and an EIP712 signature to provide when closing a position on the owner's behalf.

Returns

NameTypeDescription
outcome_Types.LongActionOutcomeThe outcome of the initiateClosePosition call to the USDN protocol.

Structs

InitiateCloseData

Structure to hold the transient data during initiateClosePosition.

struct InitiateCloseData {
    UserDeposit userDepositData;
    uint88 remainingAssets;
    uint256 positionVersion;
    PositionData currentPositionData;
    uint256 amountToCloseWithoutBonus;
    uint256 amountToClose;
    Types.Position protocolPosition;
    address user;
    uint256 balanceOfAssetBefore;
    uint256 balanceOfAssetAfter;
    uint88 amount;
    address to;
    address payable validator;
    uint256 userMinPrice;
    uint256 deadline;
    uint256 closeLockedUntil;
}

Properties

NameTypeDescription
userDepositDataUserDepositThe user deposit data.
remainingAssetsuint88The remaining rebalancer assets.
positionVersionuint256The current rebalancer position version.
currentPositionDataPositionDataThe current rebalancer position data.
amountToCloseWithoutBonusuint256The user amount to close without bonus.
amountToCloseuint256The user amount to close including bonus.
protocolPositionTypes.PositionThe protocol rebalancer position.
useraddressThe address of the user that deposited the funds in the rebalancer.
balanceOfAssetBeforeuint256The balance of asset before the USDN protocol's initiateClosePosition.
balanceOfAssetAfteruint256The balance of asset after the USDN protocol's initiateClosePosition.
amountuint88The amount to close relative to the amount deposited.
toaddressThe recipient of the assets.
validatoraddress payableThe address that should validate the open position.
userMinPriceuint256The minimum price at which the position can be closed.
deadlineuint256The deadline of the close position to be initiated.
closeLockedUntiluint256The timestamp by which a user must wait to perform a initiateClosePosition.

Contents

Usdn

Git Source

Inherits: IUsdn, ERC20Permit, ERC20Burnable, AccessControl

The USDN token supports the USDN Protocol. It is minted when assets are deposited into the USDN Protocol vault and burned when withdrawn. The total supply and individual balances are periodically increased by modifying a global divisor, ensuring the token's value doesn't grow too far past 1 USD.

This contract extends OpenZeppelin's ERC-20 implementation, adapted to support growable balances. Unlike a traditional ERC-20, balances are stored as shares, which are converted into token amounts using the global divisor. This design allows for supply growth without updating individual balances. Any divisor modification can only make balances and total supply increase.

State Variables

MINTER_ROLE

Gets the minter role signature.

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

REBASER_ROLE

Gets the rebaser role signature.

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

MAX_DIVISOR

Gets the maximum value of the divisor, which is also the initial value.

uint256 public constant MAX_DIVISOR = 1e18;

MIN_DIVISOR

Gets the minimum acceptable value of the divisor.

The minimum divisor that can be set. This corresponds to a growth of 1B times. Technically, 1e5 would still work without precision errors.

uint256 public constant MIN_DIVISOR = 1e9;

NAME

The name of the USDN token.

string internal constant NAME = "Ultimate Synthetic Delta Neutral";

SYMBOL

The symbol of the USDN token.

string internal constant SYMBOL = "USDN";

_shares

Mapping of the number of shares held by each account.

mapping(address account => uint256) internal _shares;

_totalShares

The sum of all the shares.

uint256 internal _totalShares;

_divisor

The divisor used for conversion between shares and tokens.

uint256 internal _divisor = MAX_DIVISOR;

_rebaseHandler

Address of a contract to be called upon a rebase event.

IRebaseCallback internal _rebaseHandler;

Functions

constructor

constructor(address minter, address rebaser) ERC20(NAME, SYMBOL) ERC20Permit(NAME);

Parameters

NameTypeDescription
minteraddressAddress to be granted the minter role (pass zero address to skip).
rebaseraddressAddress to be granted the rebaser role (pass zero address to skip).

totalSupply

Returns the total supply of tokens in existence.

This value is derived from the total number of shares and the current divisor. It does not represent the exact sum of all token balances due to the divisor mechanism. For an accurate representation, consider using the total number of shares via totalShares.

function totalSupply() public view override(ERC20, IERC20) returns (uint256 totalSupply_);

Returns

NameTypeDescription
totalSupply_uint256The total supply of tokens as computed from shares.

balanceOf

Returns the token balance of a given account.

The returned value is based on the current divisor and may not represent an accurate balance in terms of shares. For precise calculations, use the number of shares via sharesOf.

function balanceOf(address account) public view override(ERC20, IERC20) returns (uint256 balance_);

Parameters

NameTypeDescription
accountaddressThe address of the account to query.

Returns

NameTypeDescription
balance_uint256The token balance of the account as computed from shares.

nonces

Returns the current nonce for owner. This value must be included whenever a signature is generated for {permit}. Every successful call to {permit} increases owner's nonce by one. This prevents a signature from being used multiple times.

function nonces(address owner) public view override(IERC20Permit, ERC20Permit) returns (uint256);

burn

Destroys a value amount of tokens from the caller, reducing the total supply.

function burn(uint256 value) public override(ERC20Burnable, IUsdn);

Parameters

NameTypeDescription
valueuint256Amount of tokens to burn, is internally converted to the proper shares amounts.

burnFrom

Destroys a value amount of tokens from account, deducting from the caller's allowance.

function burnFrom(address account, uint256 value) public override(ERC20Burnable, IUsdn);

Parameters

NameTypeDescription
accountaddressAccount to burn tokens from.
valueuint256Amount of tokens to burn, is internally converted to the proper shares amounts.

sharesOf

Returns the number of shares owned by account.

function sharesOf(address account) public view returns (uint256 shares_);

Parameters

NameTypeDescription
accountaddressThe account to query.

Returns

NameTypeDescription
shares_uint256The number of shares.

totalShares

Returns the total number of shares in existence.

function totalShares() external view returns (uint256 shares_);

Returns

NameTypeDescription
shares_uint256The number of shares.

convertToTokens

Converts a number of shares to the corresponding amount of tokens.

The conversion never overflows as we are performing a division. The conversion rounds to the nearest amount of tokens that minimizes the error when converting back to shares.

function convertToTokens(uint256 amountShares) external view returns (uint256 tokens_);

Parameters

NameTypeDescription
amountSharesuint256The amount of shares to convert to tokens.

Returns

NameTypeDescription
tokens_uint256The corresponding amount of tokens.

convertToTokensRoundUp

Converts a number of shares to the corresponding amount of tokens, rounding up.

Use this function to determine the amount of a token approval, as we always round up when deducting from a token transfer allowance.

function convertToTokensRoundUp(uint256 amountShares) external view returns (uint256 tokens_);

Parameters

NameTypeDescription
amountSharesuint256The amount of shares to convert to tokens.

Returns

NameTypeDescription
tokens_uint256The corresponding amount of tokens, rounded up.

convertToShares

Converts a number of tokens to the corresponding amount of shares.

The conversion reverts with UsdnMaxTokensExceeded if the corresponding amount of shares overflows.

function convertToShares(uint256 amountTokens) public view returns (uint256 shares_);

Parameters

NameTypeDescription
amountTokensuint256The amount of tokens to convert to shares.

Returns

NameTypeDescription
shares_uint256The corresponding amount of shares.

divisor

Gets the current value of the divisor that converts between tokens and shares.

function divisor() external view returns (uint256 divisor_);

Returns

NameTypeDescription
divisor_uint256The current divisor.

rebaseHandler

Gets the rebase handler address, which is called whenever a rebase happens.

function rebaseHandler() external view returns (IRebaseCallback rebaseHandler_);

Returns

NameTypeDescription
rebaseHandler_IRebaseCallbackThe rebase handler address.

maxTokens

Returns the current maximum tokens supply, given the current divisor.

This function is used to check if a conversion operation would overflow.

function maxTokens() public view returns (uint256 maxTokens_);

Returns

NameTypeDescription
maxTokens_uint256The maximum number of tokens that can exist.

transferShares

Transfers a given amount of shares from the msg.sender to to.

function transferShares(address to, uint256 value) external returns (bool success_);

Parameters

NameTypeDescription
toaddressRecipient of the shares.
valueuint256Number of shares to transfer.

Returns

NameTypeDescription
success_boolIndicates whether the transfer was successfully executed.

transferSharesFrom

Transfers a given amount of shares from the from to to.

There should be sufficient allowance for the spender. Be mindful of the rebase logic. The allowance is in tokens. So, after a rebase, the same amount of shares will be worth a higher amount of tokens. In that case, the allowance of the initial approval will not be enough to transfer the new amount of tokens. This can also happen when your transaction is in the mempool and the rebase happens before your transaction. Also note that the amount of tokens deduced from the allowance is rounded up, so the convertToTokensRoundUp function should be used when converting shares into an allowance value.

function transferSharesFrom(address from, address to, uint256 value) external returns (bool success_);

Parameters

NameTypeDescription
fromaddressThe owner of the shares.
toaddressRecipient of the shares.
valueuint256Number of shares to transfer.

Returns

NameTypeDescription
success_boolIndicates whether the transfer was successfully executed.

burnShares

Destroys a value amount of shares from the caller, reducing the total supply.

function burnShares(uint256 value) external;

Parameters

NameTypeDescription
valueuint256Amount of shares to burn.

burnSharesFrom

Destroys a value amount of shares from account, deducting from the caller's allowance.

There should be sufficient allowance for the spender. Be mindful of the rebase logic. The allowance is in tokens. So, after a rebase, the same amount of shares will be worth a higher amount of tokens. In that case, the allowance of the initial approval will not be enough to transfer the new amount of tokens. This can also happen when your transaction is in the mempool and the rebase happens before your transaction. Also note that the amount of tokens deduced from the allowance is rounded up, so the convertToTokensRoundUp function should be used when converting shares into an allowance value.

function burnSharesFrom(address account, uint256 value) public;

Parameters

NameTypeDescription
accountaddressAccount to burn shares from.
valueuint256Amount of shares to burn.

mint

Mints new shares, providing a token value.

Caller must have the MINTER_ROLE.

function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE);

Parameters

NameTypeDescription
toaddressAccount to receive the new shares.
amountuint256Amount of tokens to mint, is internally converted to the proper shares amounts.

mintShares

Mints new shares, providing a share value.

Caller must have the MINTER_ROLE.

function mintShares(address to, uint256 amount) external onlyRole(MINTER_ROLE) returns (uint256 mintedTokens_);

Parameters

NameTypeDescription
toaddressAccount to receive the new shares.
amountuint256Amount of shares to mint.

Returns

NameTypeDescription
mintedTokens_uint256Amount of tokens that were minted (informational).

rebase

Decreases the global divisor, which effectively grows all balances and the total supply.

If the provided divisor is larger than or equal to the current divisor value, no rebase will happen If the new divisor is smaller than MIN_DIVISOR, the value will be clamped to MIN_DIVISOR. Caller must have the REBASER_ROLE.

function rebase(uint256 newDivisor)
    external
    onlyRole(REBASER_ROLE)
    returns (bool rebased_, uint256 oldDivisor_, bytes memory callbackResult_);

Parameters

NameTypeDescription
newDivisoruint256The new divisor, should be strictly smaller than the current one and greater or equal to MIN_DIVISOR.

Returns

NameTypeDescription
rebased_boolWhether a rebase happened.
oldDivisor_uint256The previous value of the divisor.
callbackResult_bytesThe result of the callback, if a rebase happened and a callback handler is defined.

setRebaseHandler

Sets the rebase handler address.

Emits a RebaseHandlerUpdated event. If set to the zero address, no handler will be called after a rebase. Caller must have the DEFAULT_ADMIN_ROLE.

function setRebaseHandler(IRebaseCallback newHandler) external onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
newHandlerIRebaseCallbackThe new handler address.

_convertToTokens

Converts an amount of shares into the corresponding amount of tokens, rounding the division according to rounding.

If rounding to the nearest integer and the result is exactly at the halfway point, we round up.

function _convertToTokens(uint256 amountShares, Rounding rounding, uint256 d) internal pure returns (uint256 tokens_);

Parameters

NameTypeDescription
amountSharesuint256The amount of shares to convert to tokens.
roundingRoundingThe rounding direction: down, closest, or up.
duint256The current divisor value used for the conversion.

Returns

NameTypeDescription
tokens_uint256The calculated equivalent amount of tokens.

_transferShares

Transfers a given amount of shares.

Reverts if the from or to address is the zero address.

function _transferShares(address from, address to, uint256 value, uint256 tokenValue) internal;

Parameters

NameTypeDescription
fromaddressThe address from which shares are transferred.
toaddressThe address to which shares are transferred.
valueuint256The amount of shares to transfer.
tokenValueuint256The converted token value, used for the {IERC20.Transfer} event.

_burnShares

Burns a given amount of shares from an account.

Reverts if the account address is the zero address.

function _burnShares(address account, uint256 value, uint256 tokenValue) internal;

Parameters

NameTypeDescription
accountaddressThe account from which shares are burned.
valueuint256The amount of shares to burn.
tokenValueuint256The converted token value, used for the {IERC20.Transfer} event.

_updateShares

Updates the shares of accounts during transferShares, mintShares, or burnShares.

Emits a {IERC20.Transfer} event with the token equivalent of the operation. If from is the zero address, the operation is a mint. If to is the zero address, the operation is a burn.

function _updateShares(address from, address to, uint256 value, uint256 tokenValue) internal;

Parameters

NameTypeDescription
fromaddressThe source address.
toaddressThe destination address.
valueuint256The number of shares to transfer, mint, or burn.
tokenValueuint256The converted token value, used for the {IERC20.Transfer} event.

_update

Updates the shares of accounts during transfers, mints, or burns.

Emits a {IERC20.Transfer} event. If from is the zero address, the operation is a mint. If to is the zero address, the operation is a burn.

function _update(address from, address to, uint256 value) internal override;

Parameters

NameTypeDescription
fromaddressThe source address.
toaddressThe destination address.
valueuint256The number of tokens to transfer, mint, or burn.

Enums

Rounding

Enum representing the rounding options when converting from shares to tokens.

enum Rounding {
    Down,
    Closest,
    Up
}

UsdnNoRebase

Git Source

Inherits: IUsdn, ERC20Permit, ERC20Burnable, Ownable

The USDN token supports the USDN Protocol. It is minted when assets are deposited into the USDN Protocol vault and burned when withdrawn. While the original USDN token implement rebases to inflates its supply to stay as close to a certain price as possible, this version removes all of this logic to be used with a protocol that does not have any target price.

As rebasing is completely disabled, 1 share always equals to 1 token, and the divisor never changes.

State Variables

MINTER_ROLE

Gets the minter role signature.

Only here to match the IUsdn interface, this contract uses Ownable instead.

bytes32 public constant MINTER_ROLE = "";

REBASER_ROLE

Gets the rebaser role signature.

Only here to match the IUsdn interface, this contract uses Ownable instead.

bytes32 public constant REBASER_ROLE = "";

MAX_DIVISOR

Gets the maximum value of the divisor, which is also the initial value.

Only here to match the IUsdn interface, this contract does not use shares.

uint256 public constant MAX_DIVISOR = 1;

MIN_DIVISOR

Gets the minimum acceptable value of the divisor.

Only here to match the IUsdn interface, this contract does not use shares.

uint256 public constant MIN_DIVISOR = 1;

Functions

constructor

constructor(string memory name, string memory symbol) ERC20(name, symbol) ERC20Permit(name) Ownable(msg.sender);

Parameters

NameTypeDescription
namestringThe name of the ERC20 token.
symbolstringThe symbol of the ERC20 token.

nonces

Returns the current nonce for owner. This value must be included whenever a signature is generated for {permit}. Every successful call to {permit} increases owner's nonce by one. This prevents a signature from being used multiple times.

function nonces(address owner) public view override(IERC20Permit, ERC20Permit) returns (uint256);

burn

Destroys a value amount of tokens from the caller, reducing the total supply.

function burn(uint256 value) public override(ERC20Burnable, IUsdn);

Parameters

NameTypeDescription
valueuint256Amount of tokens to burn, is internally converted to the proper shares amounts.

burnFrom

Destroys a value amount of tokens from account, deducting from the caller's allowance.

function burnFrom(address account, uint256 value) public override(ERC20Burnable, IUsdn);

Parameters

NameTypeDescription
accountaddressAccount to burn tokens from.
valueuint256Amount of tokens to burn, is internally converted to the proper shares amounts.

sharesOf

Returns the number of shares owned by account.

function sharesOf(address account) public view returns (uint256 shares_);

Parameters

NameTypeDescription
accountaddressThe account to query.

Returns

NameTypeDescription
shares_uint256The number of shares.

totalShares

Returns the total number of shares in existence.

function totalShares() external view returns (uint256 shares_);

Returns

NameTypeDescription
shares_uint256The number of shares.

convertToTokens

Converts a number of shares to the corresponding amount of tokens.

The conversion never overflows as we are performing a division. The conversion rounds to the nearest amount of tokens that minimizes the error when converting back to shares.

function convertToTokens(uint256 amountShares) external pure returns (uint256 tokens_);

Parameters

NameTypeDescription
amountSharesuint256The amount of shares to convert to tokens.

Returns

NameTypeDescription
tokens_uint256The corresponding amount of tokens.

convertToTokensRoundUp

Converts a number of shares to the corresponding amount of tokens, rounding up.

Use this function to determine the amount of a token approval, as we always round up when deducting from a token transfer allowance.

function convertToTokensRoundUp(uint256 amountShares) external pure returns (uint256 tokens_);

Parameters

NameTypeDescription
amountSharesuint256The amount of shares to convert to tokens.

Returns

NameTypeDescription
tokens_uint256The corresponding amount of tokens, rounded up.

convertToShares

Converts a number of tokens to the corresponding amount of shares.

The conversion reverts with UsdnMaxTokensExceeded if the corresponding amount of shares overflows.

function convertToShares(uint256 amountTokens) public pure returns (uint256 shares_);

Parameters

NameTypeDescription
amountTokensuint256The amount of tokens to convert to shares.

Returns

NameTypeDescription
shares_uint256The corresponding amount of shares.

divisor

Gets the current value of the divisor that converts between tokens and shares.

function divisor() external pure returns (uint256 divisor_);

Returns

NameTypeDescription
divisor_uint256The current divisor.

rebaseHandler

Gets the rebase handler address, which is called whenever a rebase happens.

function rebaseHandler() external pure returns (IRebaseCallback);

Returns

NameTypeDescription
<none>IRebaseCallbackrebaseHandler_ The rebase handler address.

maxTokens

Returns the current maximum tokens supply, given the current divisor.

This function is used to check if a conversion operation would overflow.

function maxTokens() public pure returns (uint256 maxTokens_);

Returns

NameTypeDescription
maxTokens_uint256The maximum number of tokens that can exist.

transferShares

Transfers a given amount of shares from the msg.sender to to.

function transferShares(address to, uint256 value) external returns (bool success_);

Parameters

NameTypeDescription
toaddressRecipient of the shares.
valueuint256Number of shares to transfer.

Returns

NameTypeDescription
success_boolIndicates whether the transfer was successfully executed.

transferSharesFrom

Transfers a given amount of shares from the from to to.

There should be sufficient allowance for the spender. Be mindful of the rebase logic. The allowance is in tokens. So, after a rebase, the same amount of shares will be worth a higher amount of tokens. In that case, the allowance of the initial approval will not be enough to transfer the new amount of tokens. This can also happen when your transaction is in the mempool and the rebase happens before your transaction. Also note that the amount of tokens deduced from the allowance is rounded up, so the convertToTokensRoundUp function should be used when converting shares into an allowance value.

function transferSharesFrom(address from, address to, uint256 value) external returns (bool success_);

Parameters

NameTypeDescription
fromaddressThe owner of the shares.
toaddressRecipient of the shares.
valueuint256Number of shares to transfer.

Returns

NameTypeDescription
success_boolIndicates whether the transfer was successfully executed.

burnShares

Destroys a value amount of shares from the caller, reducing the total supply.

function burnShares(uint256 value) external;

Parameters

NameTypeDescription
valueuint256Amount of shares to burn.

burnSharesFrom

Destroys a value amount of shares from account, deducting from the caller's allowance.

There should be sufficient allowance for the spender. Be mindful of the rebase logic. The allowance is in tokens. So, after a rebase, the same amount of shares will be worth a higher amount of tokens. In that case, the allowance of the initial approval will not be enough to transfer the new amount of tokens. This can also happen when your transaction is in the mempool and the rebase happens before your transaction. Also note that the amount of tokens deduced from the allowance is rounded up, so the convertToTokensRoundUp function should be used when converting shares into an allowance value.

function burnSharesFrom(address account, uint256 value) public;

Parameters

NameTypeDescription
accountaddressAccount to burn shares from.
valueuint256Amount of shares to burn.

mint

Mints new shares, providing a token value.

Caller must have the MINTER_ROLE.

function mint(address to, uint256 amount) external onlyOwner;

Parameters

NameTypeDescription
toaddressAccount to receive the new shares.
amountuint256Amount of tokens to mint, is internally converted to the proper shares amounts.

mintShares

Mints new shares, providing a share value.

Caller must have the MINTER_ROLE.

function mintShares(address to, uint256 amount) external onlyOwner returns (uint256 mintedTokens_);

Parameters

NameTypeDescription
toaddressAccount to receive the new shares.
amountuint256Amount of shares to mint.

Returns

NameTypeDescription
mintedTokens_uint256Amount of tokens that were minted (informational).

rebase

Decreases the global divisor, which effectively grows all balances and the total supply.

If the provided divisor is larger than or equal to the current divisor value, no rebase will happen If the new divisor is smaller than MIN_DIVISOR, the value will be clamped to MIN_DIVISOR. Caller must have the REBASER_ROLE.

function rebase(uint256) external pure returns (bool rebased_, uint256 oldDivisor_, bytes memory callbackResult_);

Parameters

NameTypeDescription
<none>uint256

Returns

NameTypeDescription
rebased_boolWhether a rebase happened.
oldDivisor_uint256The previous value of the divisor.
callbackResult_bytesThe result of the callback, if a rebase happened and a callback handler is defined.

setRebaseHandler

Sets the rebase handler address.

Emits a RebaseHandlerUpdated event. If set to the zero address, no handler will be called after a rebase. Caller must have the DEFAULT_ADMIN_ROLE.

function setRebaseHandler(IRebaseCallback) external pure;

Parameters

NameTypeDescription
<none>IRebaseCallback

Wusdn

Git Source

Inherits: ERC20Permit, IWusdn

The WUSDN token is a wrapped version of the USDN token. While USDN is a rebasing token that inflates user balances periodically, WUSDN provides stable balances by increasing in value instead of rebasing.

State Variables

NAME

The name of the WUSDN token.

string internal constant NAME = "Wrapped Ultimate Synthetic Delta Neutral";

SYMBOL

The symbol of the WUSDN token.

string internal constant SYMBOL = "WUSDN";

SHARES_RATIO

Returns the ratio used to convert USDN shares to WUSDN amounts.

This ratio is initialized in the constructor based on the maximum divisor of the USDN token.

uint256 public immutable SHARES_RATIO;

USDN

Returns the address of the USDN token.

IUsdn public immutable USDN;

Functions

constructor

constructor(IUsdn usdn) ERC20(NAME, SYMBOL) ERC20Permit(NAME);

Parameters

NameTypeDescription
usdnIUsdnThe address of the USDN token.

wrap

Wraps a given amount of USDN into WUSDN.

This function may use slightly less than usdnAmount due to rounding errors. For a more precise operation, use wrapShares.

function wrap(uint256 usdnAmount) external returns (uint256 wrappedAmount_);

Parameters

NameTypeDescription
usdnAmountuint256The amount of USDN to wrap.

Returns

NameTypeDescription
wrappedAmount_uint256The amount of WUSDN received.

wrap

Wraps a given amount of USDN into WUSDN.

This function may use slightly less than usdnAmount due to rounding errors. For a more precise operation, use wrapShares.

function wrap(uint256 usdnAmount, address to) external returns (uint256 wrappedAmount_);

Parameters

NameTypeDescription
usdnAmountuint256The amount of USDN to wrap.
toaddress

Returns

NameTypeDescription
wrappedAmount_uint256The amount of WUSDN received.

wrapShares

Wraps a given amount of USDN shares into WUSDN and sends it to a specified address.

function wrapShares(uint256 usdnShares, address to) external returns (uint256 wrappedAmount_);

Parameters

NameTypeDescription
usdnSharesuint256The amount of USDN shares to wrap.
toaddressThe address to receive the WUSDN.

Returns

NameTypeDescription
wrappedAmount_uint256The amount of WUSDN received.

unwrap

Unwraps a given amount of WUSDN into USDN.

function unwrap(uint256 wusdnAmount) external returns (uint256 usdnAmount_);

Parameters

NameTypeDescription
wusdnAmountuint256The amount of WUSDN to unwrap.

Returns

NameTypeDescription
usdnAmount_uint256The amount of USDN received.

unwrap

Unwraps a given amount of WUSDN into USDN.

function unwrap(uint256 wusdnAmount, address to) external returns (uint256 usdnAmount_);

Parameters

NameTypeDescription
wusdnAmountuint256The amount of WUSDN to unwrap.
toaddress

Returns

NameTypeDescription
usdnAmount_uint256The amount of USDN received.

previewWrap

Computes the amount of WUSDN that would be received for a given amount of USDN.

The actual amount received may differ slightly due to rounding errors. For a precise value, use previewWrapShares.

function previewWrap(uint256 usdnAmount) external view returns (uint256 wrappedAmount_);

Parameters

NameTypeDescription
usdnAmountuint256The amount of USDN to wrap.

Returns

NameTypeDescription
wrappedAmount_uint256The estimated amount of WUSDN that would be received.

previewWrapShares

Computes the amount of WUSDN that would be received for a given amount of USDN shares.

function previewWrapShares(uint256 usdnShares) external view returns (uint256 wrappedAmount_);

Parameters

NameTypeDescription
usdnSharesuint256The amount of USDN shares to wrap.

Returns

NameTypeDescription
wrappedAmount_uint256The amount of WUSDN that would be received.

redemptionRate

Returns the exchange rate between WUSDN and USDN.

function redemptionRate() external view returns (uint256 usdnAmount_);

Returns

NameTypeDescription
usdnAmount_uint256The amount of USDN that corresponds to 1 WUSDN.

previewUnwrap

Computes the amount of USDN that would be received for a given amount of WUSDN.

The actual amount received may differ slightly due to rounding errors. For a precise value, use previewUnwrapShares.

function previewUnwrap(uint256 wusdnAmount) external view returns (uint256 usdnAmount_);

Parameters

NameTypeDescription
wusdnAmountuint256The amount of WUSDN to unwrap.

Returns

NameTypeDescription
usdnAmount_uint256The estimated amount of USDN that would be received.

previewUnwrapShares

Computes the amount of USDN shares that would be received for a given amount of WUSDN.

function previewUnwrapShares(uint256 wusdnAmount) external view returns (uint256 usdnSharesAmount_);

Parameters

NameTypeDescription
wusdnAmountuint256The amount of WUSDN to unwrap.

Returns

NameTypeDescription
usdnSharesAmount_uint256The amount of USDN shares that would be received.

totalUsdnBalance

Returns the total amount of USDN held by the contract.

function totalUsdnBalance() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The total amount of USDN held by the contract.

totalUsdnShares

Returns the total amount of USDN shares held by the contract.

function totalUsdnShares() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The total amount of USDN shares held by the contract.

nonces

Returns the current nonce for owner. This value must be included whenever a signature is generated for {permit}. Every successful call to {permit} increases owner's nonce by one. This prevents a signature from being used multiple times.

function nonces(address owner) public view override(IERC20Permit, ERC20Permit) returns (uint256);

_wrap

Wraps a given USDN token amount into WUSDN.

The caller must have already approved the USDN contract to transfer the required amount of USDN. When calling this function, the transfer is always initiated from the msg.sender.

function _wrap(uint256 usdnAmount, address to) private returns (uint256 wrappedAmount_);

Parameters

NameTypeDescription
usdnAmountuint256The amount of USDN tokens to wrap.
toaddressThe address to receive the WUSDN.

Returns

NameTypeDescription
wrappedAmount_uint256The amount of WUSDN received.

_wrapShares

Wraps a given USDN shares amount into WUSDN.

The caller must have already approved the USDN contract to transfer the required amount of USDN shares. When calling this function, the transfer is always initiated from the msg.sender.

function _wrapShares(uint256 usdnShares, address to) private returns (uint256 wrappedAmount_);

Parameters

NameTypeDescription
usdnSharesuint256The amount of USDN shares to wrap.
toaddressThe address to receive the WUSDN.

Returns

NameTypeDescription
wrappedAmount_uint256The amount of WUSDN received.

_unwrap

Unwraps a given WUSDN token amount into USDN.

This function always burns WUSDN tokens from the msg.sender.

function _unwrap(uint256 wusdnAmount, address to) private returns (uint256 usdnAmount_);

Parameters

NameTypeDescription
wusdnAmountuint256The amount of WUSDN to unwrap.
toaddressThe address to receive the USDN.

Returns

NameTypeDescription
usdnAmount_uint256The amount of USDN received.

Contents

Contents

UsdnProtocolActionsLongLibrary

Git Source

Functions

initiateOpenPosition

See initiateOpenPosition.

function initiateOpenPosition(
    Types.InitiateOpenPositionParams memory params,
    bytes calldata currentPriceData,
    Types.PreviousActionsData calldata previousActionsData
) external returns (bool isInitiated_, Types.PositionId memory posId_);

validateOpenPosition

See validateOpenPosition.

function validateOpenPosition(
    address payable validator,
    bytes calldata openPriceData,
    Types.PreviousActionsData calldata previousActionsData
) external returns (Types.LongActionOutcome outcome_, Types.PositionId memory posId_);

initiateClosePosition

See initiateClosePosition.

function initiateClosePosition(
    Types.InitiateClosePositionParams memory params,
    bytes calldata currentPriceData,
    Types.PreviousActionsData calldata previousActionsData,
    bytes calldata delegationSignature
) external returns (Types.LongActionOutcome outcome_);

validateClosePosition

See validateClosePosition.

function validateClosePosition(
    address payable validator,
    bytes calldata closePriceData,
    Types.PreviousActionsData calldata previousActionsData
) external returns (Types.LongActionOutcome outcome_);

_validateOpenPositionWithAction

Validates an open position action.

function _validateOpenPositionWithAction(Types.PendingAction memory pending, bytes calldata priceData)
    public
    returns (bool isValidated_, bool isLiquidated_, Types.PositionId memory posId_);

Parameters

NameTypeDescription
pendingTypes.PendingActionThe pending action's data.
priceDatabytesThe current price data.

Returns

NameTypeDescription
isValidated_boolWhether the action is validated.
isLiquidated_boolWhether the pending action is liquidated.
posId_Types.PositionIdThe (potentially updated) position ID, or NO_POSITION_TICK in the tick field if the position was liquidated.

_initiateOpenPosition

Initiates an open position action.

Consult the current oracle middleware implementation to know the expected format for the price data, using the ProtocolAction's InitiateOpenPosition action. The price validation might require payment according to the return value of the validationCost function of the middleware. The position is immediately included in the protocol calculations with a temporary entry price (and thus leverage). The validation operation then updates the entry price and leverage with fresher data.

function _initiateOpenPosition(Types.InitiateOpenPositionParams memory params, bytes calldata currentPriceData)
    internal
    returns (Types.PositionId memory posId_, uint256 amountToRefund_, bool isInitiated_);

Parameters

NameTypeDescription
paramsTypes.InitiateOpenPositionParamsThe parameters for the open position initiation.
currentPriceDatabytesThe current price data.

Returns

NameTypeDescription
posId_Types.PositionIdThe unique index of the opened position.
amountToRefund_uint256If there are pending liquidations we'll refund the securityDepositValue, else we'll only refund the security deposit value of the stale pending action.
isInitiated_boolWhether the action is initiated.

_validateOpenPosition

Retrieves the pending action data of the owner, try to validate it and clear it if successful.

function _validateOpenPosition(address validator, bytes calldata priceData)
    internal
    returns (uint256 securityDepositValue_, bool isValidated_, bool isLiquidated_, Types.PositionId memory posId_);

Parameters

NameTypeDescription
validatoraddressThe address of the validator.
priceDatabytesThe price data for the pending action to validate.

Returns

NameTypeDescription
securityDepositValue_uint256The value of the security deposit to refund.
isValidated_boolWhether the action is validated.
isLiquidated_boolWhether the pending action is liquidated.
posId_Types.PositionIdThe (potentially updated) position ID, or NO_POSITION_TICK in the tick field if the position was liquidated.

_validateOpenPositionUpdateBalances

Updates the protocol balances during validateOpenPosition to reflect the new entry price of the position.

We need to adjust the balances because the position that was created during the initiateOpenPosition might have gained or lost some value, and we need to reflect that the position value is now newPosValue. Any potential PnL on that temporary position must be "cancelled" so that it doesn't affect the other positions and the vault.

function _validateOpenPositionUpdateBalances(uint256 newPosValue, uint256 oldPosValue) internal;

Parameters

NameTypeDescription
newPosValueuint256The new value of the position.
oldPosValueuint256The value of the position at the current price, using its old parameters.

_prepareValidateOpenPositionData

Updates protocol balances, liquidate positions if necessary, then validate the open position action.

function _prepareValidateOpenPositionData(Types.PendingAction memory pending, bytes calldata priceData)
    internal
    returns (Types.ValidateOpenPositionData memory data_, bool isLiquidated_);

Parameters

NameTypeDescription
pendingTypes.PendingActionThe pending action data.
priceDatabytesThe price data for the pending action.

Returns

NameTypeDescription
data_Types.ValidateOpenPositionDataThe ValidateOpenPositionData data structure.
isLiquidated_boolWhether the position is liquidated.

_initiateClosePosition

Initiates a close position action.

Consult the current oracle middleware implementation to know the expected format for the price data, using the ProtocolAction's InitiateClosePosition action. The price validation might require payment according to the return value of the validationCost function of the middleware. If the current tick version is greater than the tick version of the position (when it was opened), then the position has been liquidated and this function will return 0. The position is taken out of the tick and put in a pending state during this operation. Thus, calculations don't consider this position anymore. The exit price (and thus profit) is not yet set definitively and will be done during the validate action.

function _initiateClosePosition(
    Types.InitiateClosePositionParams memory params,
    bytes calldata currentPriceData,
    bytes calldata delegationSignature
) internal returns (uint256 amountToRefund_, bool isInitiated_, bool isLiquidated_);

Parameters

NameTypeDescription
paramsTypes.InitiateClosePositionParamsThe parameters for the close position initiation.
currentPriceDatabytesThe current price data.
delegationSignaturebytesAn EIP712 signature that proves the caller is authorized by the owner of the position to close it on their behalf.

Returns

NameTypeDescription
amountToRefund_uint256If there are pending liquidations we'll refund the securityDepositValue, else we'll only refund the security deposit value of the stale pending action.
isInitiated_boolWhether the action is initiated.
isLiquidated_boolWhether the position got liquidated by this call.

_validateClosePosition

Retrieves the pending action data of the validator, try to validate it and clear it if successful.

function _validateClosePosition(address validator, bytes calldata priceData)
    internal
    returns (uint256 securityDepositValue_, bool isValidated_, bool isLiquidated_);

Parameters

NameTypeDescription
validatoraddressThe validator of the pending action.
priceDatabytesThe price data for the validator's pending action.

Returns

NameTypeDescription
securityDepositValue_uint256The value of the security deposit of the pending action.
isValidated_boolWhether the action is validated.
isLiquidated_boolWhether the pending action is liquidated.

_validateClosePositionWithAction

Updates protocol balances, liquidate positions if necessary, then validate the close position action.

function _validateClosePositionWithAction(Types.PendingAction memory pending, bytes calldata priceData)
    internal
    returns (bool isValidated_, bool isLiquidated_);

Parameters

NameTypeDescription
pendingTypes.PendingActionThe pending action data.
priceDatabytesThe price data for the action to validate.

Returns

NameTypeDescription
isValidated_boolWhether the action is validated.
isLiquidated_boolWhether the pending action is liquidated.

Structs

ValidateClosePositionWithActionData

Data structure for the _validateClosePositionWithAction function.

struct ValidateClosePositionWithActionData {
    bool isLiquidationPending;
    uint128 priceWithFees;
    uint128 liquidationPrice;
    int256 positionValue;
}

Properties

NameTypeDescription
isLiquidationPendingboolWhether a liquidation is pending.
priceWithFeesuint128The price of the position with fees.
liquidationPriceuint128The liquidation price of the position.
positionValueint256The value of the position. The amount the user will receive when closing the position.

MaxLeverageData

Data structure for the _validateOpenPositionWithAction function.

struct MaxLeverageData {
    uint24 currentLiqPenalty;
    Types.PositionId newPosId;
    uint24 liquidationPenalty;
}

Properties

NameTypeDescription
currentLiqPenaltyuint24The current liquidation penalty parameter value.
newPosIdTypes.PositionIdThe new position id.
liquidationPenaltyuint24The liquidation penalty of the tick we are considering.

UsdnProtocolActionsUtilsLibrary

Git Source

Functions

liquidate

See liquidate.

function liquidate(bytes calldata currentPriceData) external returns (Types.LiqTickInfo[] memory liquidatedTicks_);

validateActionablePendingActions

See validateActionablePendingActions.

function validateActionablePendingActions(
    Types.PreviousActionsData calldata previousActionsData,
    uint256 maxValidations
) external returns (uint256 validatedActions_);

transferPositionOwnership

See transferPositionOwnership.

function transferPositionOwnership(
    Types.PositionId calldata posId,
    address newOwner,
    bytes calldata delegationSignature,
    bytes32 domainSeparatorV4
) external;

_checkImbalanceLimitWithdrawal

Checks and reverts if the withdrawn value breaks the imbalance limits.

function _checkImbalanceLimitWithdrawal(uint256 withdrawalValue, uint256 totalExpo) external view;

Parameters

NameTypeDescription
withdrawalValueuint256The withdrawal value in asset.
totalExpouint256The current total exposure of the long side.

_checkImbalanceLimitDeposit

Checks and reverts if the deposited value breaks the imbalance limits.

function _checkImbalanceLimitDeposit(uint256 depositValue) external view;

Parameters

NameTypeDescription
depositValueuint256The deposit value in asset.

getLongPosition

See getLongPosition.

function getLongPosition(Types.PositionId memory posId)
    public
    view
    returns (Types.Position memory pos_, uint24 liquidationPenalty_);

_prepareClosePositionData

Updates the protocol state, then prepares the data for the initiate close position action.

Reverts if the imbalance limit is reached, or if any checks in _checkInitiateClosePosition fail. Returns without creating a pending action if the position gets liquidated in this transaction or if there are still positions pending liquidation.

function _prepareClosePositionData(Types.PrepareInitiateClosePositionParams calldata params)
    public
    returns (Types.ClosePositionData memory data_, bool liquidated_);

Parameters

NameTypeDescription
paramsTypes.PrepareInitiateClosePositionParamsThe parameters for the _prepareClosePositionData function.

Returns

NameTypeDescription
data_Types.ClosePositionDataThe close position data.
liquidated_boolIndicates whether the position was liquidated.

_validateMultipleActionable

Validates multiple actionable pending actions.

function _validateMultipleActionable(Types.PreviousActionsData calldata previousActionsData, uint256 maxValidations)
    internal
    returns (uint256 validatedActions_, uint256 amountToRefund_);

Parameters

NameTypeDescription
previousActionsDataTypes.PreviousActionsDataThe data for the actions to validate (price and raw indices).
maxValidationsuint256The maximum number of validations to perform.

Returns

NameTypeDescription
validatedActions_uint256The number of actions successfully validated.
amountToRefund_uint256The total amount of security deposits to be refunded.

_isActionable

Checks whether a pending action is actionable, allowing any user to validate it and claim the security deposit.

Between initiateTimestamp and initiateTimestamp + lowLatencyDeadline, the validator receives the security deposit. Between initiateTimestamp + lowLatencyDelay and initiateTimestamp + lowLatencyDelay + onChainDeadline, the validator also receives the security deposit. Outside of those periods, the security deposit goes to the user validating the pending action.

function _isActionable(
    uint256 initiateTimestamp,
    uint256 lowLatencyDeadline,
    uint256 lowLatencyDelay,
    uint256 onChainDeadline
) internal view returns (bool actionable_);

Parameters

NameTypeDescription
initiateTimestampuint256The timestamp at which the action was initiated.
lowLatencyDeadlineuint256The deadline after which the action is actionable within a low latency oracle.
lowLatencyDelayuint256The amount of time the action can be validated with a low latency oracle.
onChainDeadlineuint256The deadline after which the action is actionable with an on-chain oracle.

Returns

NameTypeDescription
actionable_boolIndicates whether the pending action is actionable.

_checkImbalanceLimitClose

Checks the close vault imbalance limit state.

Ensures that the protocol does not imbalance more than the close limit on the vault side, otherwise revert.

function _checkImbalanceLimitClose(uint256 posTotalExpoToClose, uint256 posValueToClose) internal view;

Parameters

NameTypeDescription
posTotalExpoToCloseuint256The total exposure to remove from the position.
posValueToCloseuint256The value to remove from the position (and the long balance).

_checkInitiateClosePosition

Performs checks for the initiate close position action.

function _checkInitiateClosePosition(
    Types.Position memory pos,
    Types.PrepareInitiateClosePositionParams calldata params
) internal;

Parameters

NameTypeDescription
posTypes.PositionThe position to close.
paramsTypes.PrepareInitiateClosePositionParamsThe parameters for the _prepareClosePositionData function.

_assetToRemove

Calculates how much assets must be removed from the long balance due to a position closing.

The amount is bound by the amount of assets available on the long side.

function _assetToRemove(uint256 balanceLong, uint128 price, uint128 liqPriceWithoutPenalty, uint128 posExpo)
    internal
    pure
    returns (uint256 boundedPosValue_);

Parameters

NameTypeDescription
balanceLonguint256The balance of the long side.
priceuint128The price to use for the position value calculation.
liqPriceWithoutPenaltyuint128The liquidation price without penalty.
posExpouint128The total exposure to remove from the position.

Returns

NameTypeDescription
boundedPosValue_uint256The amount of assets to remove from the long balance.

_verifyInitiateCloseDelegation

Performs the initiateClosePosition EIP712 delegation signature verification.

Reverts if the function arguments don't match those included in the signature and if the signer isn't the owner of the position.

function _verifyInitiateCloseDelegation(Types.PrepareInitiateClosePositionParams calldata params, address positionOwner)
    internal;

Parameters

NameTypeDescription
paramsTypes.PrepareInitiateClosePositionParamsThe parameters for the _prepareClosePositionData function.
positionOwneraddressThe position owner.

_verifyTransferPositionOwnershipDelegation

Performs the transferPositionOwnership EIP712 delegation signature verification.

Reverts if the function arguments don't match those included in the signature and if the signer isn't the owner of the position.

function _verifyTransferPositionOwnershipDelegation(
    Types.PositionId calldata posId,
    address positionOwner,
    address newPositionOwner,
    bytes calldata delegationSignature,
    bytes32 domainSeparatorV4
) internal;

Parameters

NameTypeDescription
posIdTypes.PositionIdThe unique identifier of the position.
positionOwneraddressThe current position owner.
newPositionOwneraddressThe new position owner.
delegationSignaturebytesAn EIP712 signature that proves the caller is authorized by the owner of the position to transfer the ownership to a different address on his behalf.
domainSeparatorV4bytes32The domain separator v4.

Structs

ValidateMultipleActionableData

Data structure for the transient state of the _validateMultipleActionable function.

struct ValidateMultipleActionableData {
    Types.PendingAction pending;
    uint128 frontRawIndex;
    uint128 rawIndex;
    bool executed;
    bool liq;
}

Properties

NameTypeDescription
pendingTypes.PendingActionThe candidate pending action to validate.
frontRawIndexuint128The raw index of the front of the queue.
rawIndexuint128The raw index of the candidate pending action in the queue.
executedboolIndicates whether the pending action has been executed.
liqboolIndicates whether the pending action has been liquidated.

UsdnProtocolConstantsLibrary

Git Source

State Variables

LEVERAGE_DECIMALS

Number of decimals used for a position's leverage.

uint8 internal constant LEVERAGE_DECIMALS = 21;

FUNDING_RATE_DECIMALS

Number of decimals used for the funding rate.

uint8 internal constant FUNDING_RATE_DECIMALS = 18;

TOKENS_DECIMALS

Number of decimals used for tokens within the protocol (excluding the asset).

uint8 internal constant TOKENS_DECIMALS = 18;

LIQUIDATION_MULTIPLIER_DECIMALS

Number of decimals used for the fixed representation of the liquidation multiplier.

uint8 internal constant LIQUIDATION_MULTIPLIER_DECIMALS = 38;

FUNDING_SF_DECIMALS

Number of decimals in the scaling factor of the funding rate.

uint8 internal constant FUNDING_SF_DECIMALS = 3;

REBALANCER_MIN_LEVERAGE

Minimum leverage allowed for the rebalancer to open a position.

In edge cases where the rebalancer holds significantly more assets than the protocol, opening a position with the protocol's minimum leverage could cause a large overshoot of the target, potentially creating an even greater imbalance. To prevent this, the rebalancer can use leverage as low as the technical minimum (10 ** LEVERAGE_DECIMALS + 1).

uint256 internal constant REBALANCER_MIN_LEVERAGE = 10 ** LEVERAGE_DECIMALS + 1;

SDEX_BURN_ON_DEPOSIT_DIVISOR

Divisor for the ratio of USDN to SDEX burned on deposit.

uint256 internal constant SDEX_BURN_ON_DEPOSIT_DIVISOR = 1e8;

BPS_DIVISOR

Divisor for basis point (BPS) values.

uint256 internal constant BPS_DIVISOR = 10_000;

MAX_LIQUIDATION_ITERATION

Maximum number of tick liquidations that can be processed per call.

uint16 internal constant MAX_LIQUIDATION_ITERATION = 10;

NO_POSITION_TICK

Sentinel value indicating a PositionId that represents no position.

int24 internal constant NO_POSITION_TICK = type(int24).min;

DEAD_ADDRESS

Address holding the minimum supply of USDN and the first minimum long position.

address internal constant DEAD_ADDRESS = address(0xdead);

REMOVE_BLOCKED_PENDING_ACTIONS_DELAY

Delay after which a blocked pending action can be removed after _lowLatencyValidatorDeadline + _onChainValidatorDeadline.

uint16 internal constant REMOVE_BLOCKED_PENDING_ACTIONS_DELAY = 5 minutes;

MIN_USDN_SUPPLY

Minimum total supply of USDN allowed.

Upon the first deposit, this amount is sent to the dead address and becomes unrecoverable.

uint256 internal constant MIN_USDN_SUPPLY = 1000;

MIN_LONG_TRADING_EXPO_BPS

Minimum margin between total exposure and long balance.

Ensures the balance long does not increase in a way that causes the trading exposure to fall below this margin. If this occurs, the balance long is clamped to the total exposure minus the margin.

uint256 internal constant MIN_LONG_TRADING_EXPO_BPS = 100;

MIN_ACTIONABLE_PENDING_ACTIONS_ITER

Minimum iterations when searching for actionable pending actions in getActionablePendingActions.

uint256 internal constant MIN_ACTIONABLE_PENDING_ACTIONS_ITER = 20;

MIN_VALIDATION_DEADLINE

Minimum validation deadline for validators.

uint256 internal constant MIN_VALIDATION_DEADLINE = 60;

MAX_VALIDATION_DEADLINE

Maximum validation deadline for validators.

uint256 internal constant MAX_VALIDATION_DEADLINE = 1 days;

MAX_LIQUIDATION_PENALTY

Maximum liquidation penalty allowed.

uint256 internal constant MAX_LIQUIDATION_PENALTY = 1500;

MAX_SAFETY_MARGIN_BPS

Maximum safety margin allowed in basis points.

uint256 internal constant MAX_SAFETY_MARGIN_BPS = 2000;

MAX_EMA_PERIOD

Maximum EMA (Exponential Moving Average) period allowed.

uint256 internal constant MAX_EMA_PERIOD = 90 days;

MAX_POSITION_FEE_BPS

Maximum position fee allowed in basis points.

uint256 internal constant MAX_POSITION_FEE_BPS = 2000;

MAX_VAULT_FEE_BPS

Maximum vault fee allowed in basis points.

uint256 internal constant MAX_VAULT_FEE_BPS = 2000;

MAX_SDEX_REWARDS_RATIO_BPS

Maximum ratio of SDEX rewards allowed in basis points.

uint256 internal constant MAX_SDEX_REWARDS_RATIO_BPS = 1000;

MAX_LEVERAGE

Maximum leverage allowed.

uint256 internal constant MAX_LEVERAGE = 100 * 10 ** LEVERAGE_DECIMALS;

MAX_SECURITY_DEPOSIT

Maximum security deposit allowed.

uint256 internal constant MAX_SECURITY_DEPOSIT = 5 ether;

MAX_PROTOCOL_FEE_BPS

Maximum protocol fee allowed in basis points.

uint16 internal constant MAX_PROTOCOL_FEE_BPS = 3000;

INITIATE_CLOSE_TYPEHASH

EIP712 typehash for initiateClosePosition.

Used within EIP712 messages for domain-specific signing, enabling recovery of the signer via ECDSA-recover.

bytes32 internal constant INITIATE_CLOSE_TYPEHASH = keccak256(
    "InitiateClosePositionDelegation(bytes32 posIdHash,uint128 amountToClose,uint256 userMinPrice,address to,uint256 deadline,address positionOwner,address positionCloser,uint256 nonce)"
);

TRANSFER_POSITION_OWNERSHIP_TYPEHASH

EIP712 typehash for transferPositionOwnership.

Used within EIP712 messages for domain-specific signing, enabling recovery of the signer via ECDSA-recover.

bytes32 internal constant TRANSFER_POSITION_OWNERSHIP_TYPEHASH = keccak256(
    "TransferPositionOwnershipDelegation(bytes32 posIdHash,address positionOwner,address newPositionOwner,address delegatedAddress,uint256 nonce)"
);

SET_EXTERNAL_ROLE

Role signature for setting external contracts.

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

CRITICAL_FUNCTIONS_ROLE

Role signature for performing critical protocol actions.

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

SET_PROTOCOL_PARAMS_ROLE

Role signature for setting protocol parameters.

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

SET_USDN_PARAMS_ROLE

Role signature for setting USDN parameters.

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

SET_OPTIONS_ROLE

Role signature for configuring protocol options with minimal impact.

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

PROXY_UPGRADE_ROLE

Role signature for upgrading the protocol implementation.

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

PAUSER_ROLE

Role signature for pausing the protocol.

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

UNPAUSER_ROLE

Role signature for unpausing the protocol.

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

ADMIN_SET_EXTERNAL_ROLE

Admin role for managing the SET_EXTERNAL_ROLE.

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

ADMIN_CRITICAL_FUNCTIONS_ROLE

Admin role for managing the CRITICAL_FUNCTIONS_ROLE.

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

ADMIN_SET_PROTOCOL_PARAMS_ROLE

Admin role for managing the SET_PROTOCOL_PARAMS_ROLE.

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

ADMIN_SET_USDN_PARAMS_ROLE

Admin role for managing the SET_USDN_PARAMS_ROLE.

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

ADMIN_SET_OPTIONS_ROLE

Admin role for managing the SET_OPTIONS_ROLE.

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

ADMIN_PROXY_UPGRADE_ROLE

Admin role for managing the PROXY_UPGRADE_ROLE.

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

ADMIN_PAUSER_ROLE

Admin role for managing the PAUSER_ROLE.

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

ADMIN_UNPAUSER_ROLE

Admin role for managing the UNPAUSER_ROLE.

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

UsdnProtocolCoreLibrary

Git Source

Functions

initialize

See initialize.

function initialize(uint128 depositAmount, uint128 longAmount, uint128 desiredLiqPrice, bytes calldata currentPriceData)
    external;

removeBlockedPendingAction

See removeBlockedPendingAction.

function removeBlockedPendingAction(address validator, address payable to) external;

removeBlockedPendingActionNoCleanup

See removeBlockedPendingActionNoCleanup.

function removeBlockedPendingActionNoCleanup(address validator, address payable to) external;

_createClosePendingAction

Prepares the pending action struct for the close position action and add it to the queue.

function _createClosePendingAction(
    address to,
    address validator,
    Types.PositionId memory posId,
    uint128 amountToClose,
    uint64 securityDepositValue,
    Types.ClosePositionData memory data
) external returns (uint256 amountToRefund_);

Parameters

NameTypeDescription
toaddressThe address that will receive the assets.
validatoraddressThe validator for the pending action.
posIdTypes.PositionIdThe unique identifier of the position.
amountToCloseuint128The amount of collateral to remove from the position's amount.
securityDepositValueuint64The value of the security deposit for the newly created pending action.
dataTypes.ClosePositionDataThe close position data.

Returns

NameTypeDescription
amountToRefund_uint256The security deposit value of a stale pending action.

_createWithdrawalPendingAction

Prepares the pending action struct for a withdrawal and adds it to the queue.

function _createWithdrawalPendingAction(
    address to,
    address validator,
    uint152 usdnShares,
    uint64 securityDepositValue,
    Vault.WithdrawalData memory data
) external returns (uint256 amountToRefund_);

Parameters

NameTypeDescription
toaddressThe recipient of the assets.
validatoraddressThe address that is supposed to validate the withdrawal and receive the security deposit.
usdnSharesuint152The amount of USDN shares to burn.
securityDepositValueuint64The value of the security deposit for the newly created pending action.
dataVault.WithdrawalDataThe withdrawal action data.

Returns

NameTypeDescription
amountToRefund_uint256Refund The security deposit value of a stale pending action.

getUserPendingAction

See getUserPendingAction.

function getUserPendingAction(address validator) external view returns (Types.PendingAction memory action_);

funding

See funding.

function funding(uint128 timestamp)
    external
    view
    returns (int256 funding_, int256 fundingPerDay_, int256 oldLongExpo_);

longAssetAvailableWithFunding

Gets the predicted value of the long balance for the given asset price and timestamp.

The effects of the funding and any PnL of the long positions since the last contract state update is taken into account, as well as the fees. If the provided timestamp is older than the last state update, the function reverts with UsdnProtocolTimestampTooOld. The value cannot be below 0.

function longAssetAvailableWithFunding(uint128 currentPrice, uint128 timestamp)
    public
    view
    returns (uint256 available_, int256 fee_);

Parameters

NameTypeDescription
currentPriceuint128The given asset price.
timestampuint128The timestamp corresponding to the given price.

Returns

NameTypeDescription
available_uint256The long balance value in assets.
fee_int256The protocol fees in asset units, either positive or negative.

longTradingExpoWithFunding

See longTradingExpoWithFunding.

function longTradingExpoWithFunding(uint128 currentPrice, uint128 timestamp) public view returns (uint256 expo_);

_checkOpenPositionLeverage

Checks if the position's leverage is in the authorized range of values.

function _checkOpenPositionLeverage(uint128 adjustedPrice, uint128 liqPriceWithoutPenalty, uint256 userMaxLeverage)
    public
    view;

Parameters

NameTypeDescription
adjustedPriceuint128The adjusted price of the asset.
liqPriceWithoutPenaltyuint128The liquidation price of the position without the liquidation penalty.
userMaxLeverageuint256The maximum leverage allowed by the user for the newly created position.

_createOpenPendingAction

Prepares the pending action struct for an open position and adds it to the queue.

function _createOpenPendingAction(
    address to,
    address validator,
    uint64 securityDepositValue,
    Types.InitiateOpenPositionData memory data
) public returns (uint256 amountToRefund_);

Parameters

NameTypeDescription
toaddressThe address that will be the owner of the position.
validatoraddressThe address which is supposed to validate the position and receive the security deposit.
securityDepositValueuint64The value of the security deposit for the newly created pending action.
dataTypes.InitiateOpenPositionDataThe open position action data.

Returns

NameTypeDescription
amountToRefund_uint256The security deposit value of a stale pending action, if any was removed.

_applyPnlAndFunding

Computes the profits and losses on the long side, calculates the funding, applies protocol fees, updates the liquidation multiplier and determines the temporary new balances for each side.

This function updates the state of _lastPrice, _lastUpdateTimestamp, _lastFunding, but does not update the balances. This is left to the caller.

function _applyPnlAndFunding(uint128 currentPrice, uint128 timestamp)
    public
    returns (Types.ApplyPnlAndFundingData memory data_);

Parameters

NameTypeDescription
currentPriceuint128The current price.
timestampuint128The timestamp of the current price.

Returns

NameTypeDescription
data_Types.ApplyPnlAndFundingDataThe data containing the temporary long balance, the temporary vault balance, the last price and a flag indicating if the price is recent.

_removeStalePendingAction

Removes the pending action from the queue if its tick version doesn't match the current tick version, indicating that the tick was liquidated.

This is only applicable to ValidateOpenPosition pending actions.

function _removeStalePendingAction(address validator) public returns (uint256 securityDepositValue_);

Parameters

NameTypeDescription
validatoraddressThe address associated with the pending action.

Returns

NameTypeDescription
securityDepositValue_uint256The security deposit value of the removed stale pending action.

_addPendingAction

Adds a pending action to the queue and removes a possible stale pending action.

Reverts if there is already a pending action for this user.

function _addPendingAction(address validator, Types.PendingAction memory action)
    public
    returns (uint256 amountToRefund_);

Parameters

NameTypeDescription
validatoraddressThe address which is supposed to validate the position and receive the security deposit.
actionTypes.PendingActionThe pending action struct.

Returns

NameTypeDescription
amountToRefund_uint256The security deposit value of a stale pending action, if any was removed.

_removeBlockedPendingAction

Removes a blocked pending action and performs the minimal amount of cleanup necessary.

This function should only be called by the owner of the protocol, it serves as an escape hatch if a pending action ever gets stuck due to something reverting unexpectedly. From the user action timestamp, the caller must wait at least REMOVE_BLOCKED_PENDING_ACTIONS_DELAY after both _lowLatencyValidatorDeadline and _onChainValidatorDeadline.

function _removeBlockedPendingAction(uint128 rawIndex, address payable to, bool cleanup) public;

Parameters

NameTypeDescription
rawIndexuint128The raw index of the pending action in the queue.
toaddress payableThe recipient of the funds, which may include security deposit, assets and USDN tokens.
cleanupboolIf true, will attempt to perform more cleanup at the risk of reverting. Always try true first.

_saveNewPosition

Saves a new long position in the protocol, adjusting the tick data and global variables.

This method does not update the long balance.

function _saveNewPosition(int24 tick, Types.Position memory long, uint24 liquidationPenalty)
    public
    returns (uint256 tickVersion_, uint256 index_, HugeUint.Uint512 memory liqMultiplierAccumulator_);

Parameters

NameTypeDescription
tickint24The tick to hold the new position.
longTypes.PositionThe position to save.
liquidationPenaltyuint24The liquidation penalty for the tick.

Returns

NameTypeDescription
tickVersion_uint256The version of the tick.
index_uint256The index of the position in the tick array.
liqMultiplierAccumulator_HugeUint.Uint512The updated liquidation multiplier accumulator.

_getPendingActionOrRevert

Gets the pending action for a validator.

Reverts if there is no pending action for the validator.

function _getPendingActionOrRevert(address validator)
    public
    view
    returns (Types.PendingAction memory action_, uint128 rawIndex_);

Parameters

NameTypeDescription
validatoraddressThe address which is supposed to validate the position and receive the security deposit.

Returns

NameTypeDescription
action_Types.PendingActionThe pending action struct.
rawIndex_uint128The raw index of the pending action in the queue.

_fundingAsset

Gets the predicted value of the funding (in asset units) since the last state update for the given timestamp.

If the provided timestamp is older than the last state update, the result will be zero.

function _fundingAsset(uint128 timestamp, int256 ema)
    internal
    view
    returns (int256 fundingAsset_, int256 fundingPerDay_);

Parameters

NameTypeDescription
timestampuint128The targeted timestamp.
emaint256The EMA of the funding rate.

Returns

NameTypeDescription
fundingAsset_int256The number of asset tokens of funding (with asset decimals).
fundingPerDay_int256The funding rate (per day) with FUNDING_RATE_DECIMALS decimals.

_updateEMA

Updates the Exponential Moving Average (EMA) of the funding rate (per day).

This function is called every time the protocol state is updated. All required checks are done in the caller function _applyPnlAndFunding. If the number of seconds elapsed is greater than or equal to the EMA period, the EMA is updated to the last funding value.

function _updateEMA(int256 fundingPerDay, uint128 secondsElapsed) internal;

Parameters

NameTypeDescription
fundingPerDayint256The funding rate per day that was just calculated for the elapsed period.
secondsElapseduint128The number of seconds elapsed since the last protocol action.

_calculateFee

Calculates the protocol fee and apply it to the funding asset amount.

The funding factor is only adjusted by the fee rate when the funding is negative (vault pays to the long side).

function _calculateFee(int256 fundAsset) internal returns (int256 fee_, int256 fundAssetWithFee_);

Parameters

NameTypeDescription
fundAssetint256The funding asset amount to be used for the fee calculation.

Returns

NameTypeDescription
fee_int256The absolute value of the calculated fee.
fundAssetWithFee_int256The updated funding asset amount after applying the fee.

_createInitialDeposit

Creates the initial deposit.

To be called from initialize.

function _createInitialDeposit(uint128 amount, uint128 price) internal;

Parameters

NameTypeDescription
amountuint128The initial deposit amount.
priceuint128The current asset price.

_createInitialPosition

Creates the initial long position.

To be called from initialize.

function _createInitialPosition(uint128 amount, uint128 price, int24 tick, uint128 totalExpo) internal;

Parameters

NameTypeDescription
amountuint128The initial position amount.
priceuint128The current asset price.
tickint24The tick corresponding where the position should be stored.
totalExpouint128The total expo of the position.

_getPendingAction

Gets the possible pending action for a validator.

Checks for the presence of a pending action for a validator, compares action_.action to Types.ProtocolAction.None. There is a pending action only if the action is different from Types.ProtocolAction.None.

function _getPendingAction(address validator)
    internal
    view
    returns (Types.PendingAction memory action_, uint128 rawIndex_);

Parameters

NameTypeDescription
validatoraddressThe address of the pending action which is supposed to validate the position and receive the security deposit.

Returns

NameTypeDescription
action_Types.PendingActionThe pending action struct if any, otherwise a zero-initialized struct.
rawIndex_uint128The raw index of the pending action in the queue.

_checkInitImbalance

Checks if the initialize parameters lead to a balanced protocol.

Reverts if the imbalance is exceeded for the deposit or open long actions.

function _checkInitImbalance(uint128 positionTotalExpo, uint128 longAmount, uint128 depositAmount) internal view;

Parameters

NameTypeDescription
positionTotalExpouint128The total expo of the deployer's long position.
longAmountuint128The amount (collateral) of the deployer's long position.
depositAmountuint128The amount of assets for the deployer's deposit.

_fundingPerDay

Computes the funding rate per day and the old long exposure.

function _fundingPerDay(int256 ema) internal view returns (int256 fundingPerDay_, int256 oldLongExpo_);

Parameters

NameTypeDescription
emaint256The EMA of the funding rate per day.

Returns

NameTypeDescription
fundingPerDay_int256The funding rate per day with FUNDING_RATE_DECIMALS decimals.
oldLongExpo_int256The old long trading expo.

_funding

Computes the funding value, funding rate value and the old long exposure.

Reverts if timestamp < s._lastUpdateTimestamp.

function _funding(uint128 timestamp, int256 ema)
    internal
    view
    returns (int256 funding_, int256 fundingPerDay_, int256 oldLongExpo_);

Parameters

NameTypeDescription
timestampuint128The current timestamp.
emaint256The EMA of the funding rate per day.

Returns

NameTypeDescription
funding_int256The funding (proportion of long trading expo that needs to be transferred from one side to the other) with FUNDING_RATE_DECIMALS decimals. If positive, long side pays to vault side, otherwise it's the opposite.
fundingPerDay_int256The funding rate (per day) with FUNDING_RATE_DECIMALS decimals.
oldLongExpo_int256The old long trading expo.

_calcEMA

Calculates the new Exponential Moving Average.

function _calcEMA(int256 fundingPerDay, uint128 secondsElapsed, uint128 emaPeriod, int256 previousEMA)
    internal
    pure
    returns (int256 newEMA_);

Parameters

NameTypeDescription
fundingPerDayint256The funding per day.
secondsElapseduint128The number of seconds elapsed to be taken into account.
emaPerioduint128The current EMA period.
previousEMAint256The previous EMA value.

Returns

NameTypeDescription
newEMA_int256The new EMA value.

_calcMaxLongBalance

Calculates the maximum value of the long balance for the provided total expo.

function _calcMaxLongBalance(uint256 totalExpo) internal pure returns (uint256 maxLongBalance_);

Parameters

NameTypeDescription
totalExpouint256The total expo of the long side of the protocol.

Returns

NameTypeDescription
maxLongBalance_uint256The maximum value the long balance can reach.

UsdnProtocolLongLibrary

Git Source

Functions

getPositionValue

See getPositionValue.

function getPositionValue(Types.PositionId calldata posId, uint128 price, uint128 timestamp)
    external
    view
    returns (int256 value_);

getEffectiveTickForPrice

See getEffectiveTickForPrice.

function getEffectiveTickForPrice(uint128 price) external view returns (int24 tick_);

minTick

See minTick.

function minTick() public view returns (int24 tick_);

getTickLiquidationPenalty

See getTickLiquidationPenalty.

function getTickLiquidationPenalty(int24 tick) public view returns (uint24 liquidationPenalty_);

getEffectiveTickForPrice

See getEffectiveTickForPrice.

function getEffectiveTickForPrice(
    uint128 price,
    uint256 assetPrice,
    uint256 longTradingExpo,
    HugeUint.Uint512 memory accumulator,
    int24 tickSpacing
) public pure returns (int24 tick_);

_applyPnlAndFundingAndLiquidate

Applies PnL, funding, and liquidates positions if necessary.

If there were any liquidations, it sends the rewards to the msg.sender.

function _applyPnlAndFundingAndLiquidate(
    uint256 neutralPrice,
    uint256 timestamp,
    uint16 iterations,
    Types.ProtocolAction action,
    bytes calldata priceData
) public returns (Types.LiqTickInfo[] memory liquidatedTicks_, bool isLiquidationPending_);

Parameters

NameTypeDescription
neutralPriceuint256The neutral price for the asset.
timestampuint256The timestamp at which the operation is performed.
iterationsuint16The number of iterations for the liquidation process.
actionTypes.ProtocolActionThe type of action that is being performed by the user.
priceDatabytesThe data given to the oracle middleware corresponding to neutralPrice.

Returns

NameTypeDescription
liquidatedTicks_Types.LiqTickInfo[]Information about the liquidated ticks.
isLiquidationPending_boolIf there are remaining ticks that can be liquidated.

_prepareInitiateOpenPositionData

Prepares the data for the initiateOpenPosition function.

function _prepareInitiateOpenPositionData(Types.PrepareInitiateOpenPositionParams calldata params)
    public
    returns (Types.InitiateOpenPositionData memory data_);

Parameters

NameTypeDescription
paramsTypes.PrepareInitiateOpenPositionParamsThe parameters for the _prepareInitiateOpenPositionData function.

Returns

NameTypeDescription
data_Types.InitiateOpenPositionDataThe transient data for the open position action.

_removeAmountFromPosition

Removes amountToRemove from position pos then updates the tick data and the position.

This method does not update the long balance. If the amount to remove is greater than or equal to the position's total amount, the position is deleted instead.

function _removeAmountFromPosition(
    int24 tick,
    uint256 index,
    Types.Position memory pos,
    uint128 amountToRemove,
    uint128 totalExpoToRemove
) public returns (HugeUint.Uint512 memory liqMultiplierAccumulator_);

Parameters

NameTypeDescription
tickint24The tick the position is in.
indexuint256Index of the position in the tick array.
posTypes.PositionThe position to remove the amount from.
amountToRemoveuint128The amount to remove from the position.
totalExpoToRemoveuint128The total exposure to remove from the position.

Returns

NameTypeDescription
liqMultiplierAccumulator_HugeUint.Uint512The updated liquidation multiplier accumulator.

_getTickFromDesiredLiqPrice

Computes the tick number with penalty and liquidation price without penalty from the desired liquidation price.

This function first calculates a tick for the desired liquidation price (no rounding), then adds the penalty to the tick and rounds down to the nearest tick spacing. Then it subtracts the penalty from the final tick and calculates the corresponding liquidation price.

function _getTickFromDesiredLiqPrice(uint128 desiredLiqPriceWithoutPenalty, uint24 liquidationPenalty)
    public
    view
    returns (int24 tickWithPenalty_, uint128 liqPriceWithoutPenalty_);

Parameters

NameTypeDescription
desiredLiqPriceWithoutPenaltyuint128The desired liquidation price without penalty.
liquidationPenaltyuint24The liquidation penalty.

Returns

NameTypeDescription
tickWithPenalty_int24The tick number including the liquidation penalty.
liqPriceWithoutPenalty_uint128The liquidation price without penalty.

_getTickFromDesiredLiqPrice

Computes the tick number with penalty and liquidation price without penalty from the desired liquidation price and protocol state.

This function first calculates a tick for the desired liquidation price (no rounding), then adds the penalty to the tick and rounds down to the nearest tick spacing. Then it subtracts the penalty from the final tick and calculates the corresponding liquidation price.

function _getTickFromDesiredLiqPrice(
    uint128 desiredLiqPriceWithoutPenalty,
    uint256 assetPrice,
    uint256 longTradingExpo,
    HugeUint.Uint512 memory accumulator,
    int24 tickSpacing,
    uint24 liquidationPenalty
) public pure returns (int24 tickWithPenalty_, uint128 liqPriceWithoutPenalty_);

Parameters

NameTypeDescription
desiredLiqPriceWithoutPenaltyuint128The desired liquidation price without penalty.
assetPriceuint256The current price of the asset.
longTradingExpouint256The trading exposure of the long side (total exposure - balance long).
accumulatorHugeUint.Uint512The liquidation multiplier accumulator.
tickSpacingint24The tick spacing.
liquidationPenaltyuint24The liquidation penalty.

Returns

NameTypeDescription
tickWithPenalty_int24The tick number including the liquidation penalty.
liqPriceWithoutPenalty_uint128The liquidation price without penalty.

_getTickFromDesiredLiqPrice

Computes the tick number with penalty and liquidation price without penalty from the desired liquidation price and a fixed precision version of the liquidation multiplier accumulator.

This function first calculates a tick for the desired liquidation price (no rounding), then adds the penalty to the tick and rounds down to the nearest tick spacing. Then it subtracts the penalty from the final tick and calculates the corresponding liquidation price.

function _getTickFromDesiredLiqPrice(
    uint128 desiredLiqPriceWithoutPenalty,
    uint256 liqMultiplier,
    int24 tickSpacing,
    uint24 liquidationPenalty
) public pure returns (int24 tickWithPenalty_, uint128 liqPriceWithoutPenalty_);

Parameters

NameTypeDescription
desiredLiqPriceWithoutPenaltyuint128The desired liquidation price without penalty.
liqMultiplieruint256The liquidation price multiplier (with LIQUIDATION_MULTIPLIER_DECIMALS decimals).
tickSpacingint24The tick spacing.
liquidationPenaltyuint24The liquidation penalty.

Returns

NameTypeDescription
tickWithPenalty_int24The tick number including the liquidation penalty.
liqPriceWithoutPenalty_uint128The liquidation price without penalty.

_findHighestPopulatedTick

Finds the highest tick that contains at least one position.

If there are no ticks with a position left, returns minTick.

function _findHighestPopulatedTick(int24 searchStart) public view returns (int24 tick_);

Parameters

NameTypeDescription
searchStartint24The tick to start searching from.

Returns

NameTypeDescription
tick_int24The highest tick at or below searchStart.

_usdnRebase

Checks if a USDN rebase is required and adjust the divisor if needed.

Only call this function after _applyPnlAndFunding has been called to update the balances.

function _usdnRebase(uint128 assetPrice) internal returns (bool rebased_, bytes memory callbackResult_);

Parameters

NameTypeDescription
assetPriceuint128The current price of the underlying asset.

Returns

NameTypeDescription
rebased_boolWhether a rebase was performed.
callbackResult_bytesThe rebase callback result, if any.

_sendRewardsToLiquidator

Sends rewards to the liquidator.

Should still emit an event if liquidationRewards = 0 to better keep track of those anomalies as rewards for those will be managed off-chain.

function _sendRewardsToLiquidator(
    Types.LiqTickInfo[] memory liquidatedTicks,
    uint256 currentPrice,
    bool rebased,
    Types.RebalancerAction rebalancerAction,
    Types.ProtocolAction action,
    bytes memory rebaseCallbackResult,
    bytes memory priceData
) internal;

Parameters

NameTypeDescription
liquidatedTicksTypes.LiqTickInfo[]Information about the liquidated ticks.
currentPriceuint256The current price of the asset.
rebasedboolWhether a USDN rebase was performed.
rebalancerActionTypes.RebalancerActionThe rebalancer action that was performed.
actionTypes.ProtocolActionThe protocol action that triggered liquidations.
rebaseCallbackResultbytesThe rebase callback result, if any.
priceDatabytesThe data given to the oracle middleware to get a price.

_triggerRebalancer

Triggers the rebalancer if the imbalance on the long side is too high. It will close the rebalancer's position (if there is one) and open a new one with the pending assets, the value of the previous position and the liquidation bonus (if available) with a leverage that would fill enough trading exposure to reach the desired imbalance, up to the max leverages.

Only call this function after liquidations are performed to have a non-zero remainingCollateral value. Will return the provided long and vault balances if no rebalancer is set or if the imbalance is not high enough. If remainingCollateral is negative, the rebalancer bonus will be 0.

function _triggerRebalancer(uint128 lastPrice, uint256 longBalance, uint256 vaultBalance, int256 remainingCollateral)
    internal
    returns (uint256 longBalance_, uint256 vaultBalance_, Types.RebalancerAction action_);

Parameters

NameTypeDescription
lastPriceuint128The last price used to update the protocol.
longBalanceuint256The balance of the long side.
vaultBalanceuint256The balance of the vault side.
remainingCollateralint256The collateral remaining after the liquidations.

Returns

NameTypeDescription
longBalance_uint256The updated long balance not saved into storage yet.
vaultBalance_uint256The updated vault balance not saved into storage yet.
action_Types.RebalancerActionThe action performed by this function.

_flashOpenPosition

Immediately opens a position with the given price.

Should only be used to open the rebalancer's position.

function _flashOpenPosition(
    address user,
    uint128 lastPrice,
    int24 tick,
    uint128 posTotalExpo,
    uint24 liquidationPenalty,
    uint128 amount
) internal returns (Types.PositionId memory posId_);

Parameters

NameTypeDescription
useraddressThe address of the rebalancer.
lastPriceuint128The last price used to update the protocol.
tickint24The tick the position should be opened in.
posTotalExpouint128The total exposure of the position.
liquidationPenaltyuint24The liquidation penalty of the tick.
amountuint128The amount of collateral in the position.

Returns

NameTypeDescription
posId_Types.PositionIdThe ID of the position that was created.

_flashClosePosition

Immediately closes a position with the given price.

Should only be used to close the rebalancer's position.

function _flashClosePosition(Types.PositionId memory posId, uint128 lastPrice, Types.CachedProtocolState memory cache)
    internal
    returns (int256 positionValue_);

Parameters

NameTypeDescription
posIdTypes.PositionIdThe ID of the position to close.
lastPriceuint128The last price used to update the protocol.
cacheTypes.CachedProtocolStateThe cached state of the protocol, will be updated during this call.

Returns

NameTypeDescription
positionValue_int256The value of the closed position.

_liquidatePositions

Liquidates positions that have a liquidation price lower than the current price.

function _liquidatePositions(uint256 currentPrice, uint16 iteration, int256 tempLongBalance, int256 tempVaultBalance)
    internal
    returns (Types.LiquidationsEffects memory effects_);

Parameters

NameTypeDescription
currentPriceuint256The current price of the asset.
iterationuint16The maximum number of ticks to liquidate (minimum is 1).
tempLongBalanceint256The temporary long balance as calculated when applying the PnL and funding.
tempVaultBalanceint256The temporary vault balance as calculated when applying the PnL and funding.

Returns

NameTypeDescription
effects_Types.LiquidationsEffectsThe effects of the liquidations on the protocol.

_updateStateAfterLiquidation

Updates the state of the contract according to the liquidation effects.

function _updateStateAfterLiquidation(LiquidationData memory data, Types.LiquidationsEffects memory effects) internal;

Parameters

NameTypeDescription
dataLiquidationDataThe liquidation data, which gets mutated by the function.
effectsTypes.LiquidationsEffectsThe effects of the liquidations.

_checkImbalanceLimitOpen

Checks and reverts if the position's trading exposure exceeds the imbalance limits.

function _checkImbalanceLimitOpen(
    uint256 openTotalExpoValue,
    uint256 collateralAmount,
    uint256 collateralAmountAfterFees
) internal view;

Parameters

NameTypeDescription
openTotalExpoValueuint256The total exposure of the position to open.
collateralAmountuint256The amount of collateral of the position.
collateralAmountAfterFeesuint256The amount of collateral of the position after fees.

_calcRebalancerPositionTick

Calculates the tick of the rebalancer position to open.

The returned tick must give a leverage higher than or equal to the minimum leverage of the protocol and lower than or equal to the rebalancer and USDN protocol leverages (lowest of the 2).

function _calcRebalancerPositionTick(
    uint128 lastPrice,
    uint128 positionAmount,
    uint256 rebalancerMaxLeverage,
    Types.CachedProtocolState memory cache
) internal view returns (Types.RebalancerPositionData memory posData_);

Parameters

NameTypeDescription
lastPriceuint128The last price used to update the protocol.
positionAmountuint128The amount of assets in the position.
rebalancerMaxLeverageuint256The maximum leverage supported by the rebalancer.
cacheTypes.CachedProtocolStateThe cached protocol state values.

Returns

NameTypeDescription
posData_Types.RebalancerPositionDataThe tick, total exposure and liquidation penalty for the rebalancer position.

_checkSafetyMargin

Checks and reverts if the leverage of a position exceeds the safety margin.

function _checkSafetyMargin(uint128 currentPrice, uint128 liquidationPrice) internal view;

Parameters

NameTypeDescription
currentPriceuint128The current price of the asset.
liquidationPriceuint128The liquidation price of the position.

_getTickLiquidationPenalty

Retrieves the liquidation penalty assigned to the given tickHash.

If there are no positions in it, returns the current setting from storage.

function _getTickLiquidationPenalty(bytes32 tickHash) internal view returns (uint24 liquidationPenalty_);

Parameters

NameTypeDescription
tickHashbytes32The tick hash (hashed tick number + version).

Returns

NameTypeDescription
liquidationPenalty_uint24The liquidation penalty (in tick spacing units).

_calcTickFromBitmapIndex

Converts the given bitmap index to a tick number using the stored tick spacing.

function _calcTickFromBitmapIndex(uint256 index) internal view returns (int24 tick_);

Parameters

NameTypeDescription
indexuint256The index into the bitmap.

Returns

NameTypeDescription
tick_int24The tick corresponding to the index, a multiple of the tick spacing.

_unadjustPrice

Calculates the unadjusted price of a position's liquidation price, which can be used to find the corresponding tick.

function _unadjustPrice(uint256 price, uint256 assetPrice, uint256 longTradingExpo, HugeUint.Uint512 memory accumulator)
    internal
    pure
    returns (uint256 unadjustedPrice_);

Parameters

NameTypeDescription
priceuint256An adjusted liquidation price (taking into account the effects of funding).
assetPriceuint256The current price of the asset.
longTradingExpouint256The trading exposure of the long side (total exposure - balance long).
accumulatorHugeUint.Uint512The liquidation multiplier accumulator.

Returns

NameTypeDescription
unadjustedPrice_uint256The unadjusted price of price.

_unadjustPrice

Calculates the unadjusted price of a position's liquidation price, which can be used to find the corresponding tick, with a fixed precision representation of the liquidation multiplier.

function _unadjustPrice(uint256 price, uint256 liqMultiplier) internal pure returns (uint256 unadjustedPrice_);

Parameters

NameTypeDescription
priceuint256An adjusted liquidation price (taking into account the effects of funding).
liqMultiplieruint256The liquidation price multiplier, with LIQUIDATION_MULTIPLIER_DECIMALS decimals.

Returns

NameTypeDescription
unadjustedPrice_uint256The unadjusted price for the liquidation price.

_tickValue

Calculates the value of a tick, knowing its contained total exposure and the current asset price.

function _tickValue(
    int24 tick,
    uint256 currentPrice,
    uint256 longTradingExpo,
    HugeUint.Uint512 memory accumulator,
    Types.TickData memory tickData
) internal pure returns (int256 value_);

Parameters

NameTypeDescription
tickint24The tick number.
currentPriceuint256The current price of the asset.
longTradingExpouint256The trading exposure of the long side.
accumulatorHugeUint.Uint512The liquidation multiplier accumulator.
tickDataTypes.TickDataThe aggregated data of the tick.

Returns

NameTypeDescription
value_int256The amount of asset tokens the tick is worth.

_calcLiqPriceFromTradingExpo

Calculates the liquidation price without penalty of a position to reach a certain trading exposure.

If the sum of amount and tradingExpo equals 0, reverts.

function _calcLiqPriceFromTradingExpo(uint128 currentPrice, uint128 amount, uint256 tradingExpo)
    internal
    pure
    returns (uint128 liqPrice_);

Parameters

NameTypeDescription
currentPriceuint128The price of the asset.
amountuint128The amount of asset used as collateral.
tradingExpouint256The trading exposure.

Returns

NameTypeDescription
liqPrice_uint128The liquidation price without penalty.

_calcTickFromBitmapIndex

Converts a bitmap index to a tick number using the provided tick spacing.

function _calcTickFromBitmapIndex(uint256 index, int24 tickSpacing) internal pure returns (int24 tick_);

Parameters

NameTypeDescription
indexuint256The index into the bitmap.
tickSpacingint24The tick spacing to use.

Returns

NameTypeDescription
tick_int24The tick corresponding to the index, a multiple of tickSpacing.

_handleNegativeBalances

Handles negative balances by transferring assets from one side to the other.

Balances are unsigned integers and can't be negative. In theory, this can not happen anymore because we have more precise calculations with the liqMultiplierAccumulator compared to the old liquidationMultiplier.

function _handleNegativeBalances(int256 tempLongBalance, int256 tempVaultBalance)
    internal
    pure
    returns (uint256 longBalance_, uint256 vaultBalance_);

Parameters

NameTypeDescription
tempLongBalanceint256The temporary long balance after liquidations
tempVaultBalanceint256The temporary vault balance after liquidations

Returns

NameTypeDescription
longBalance_uint256The new long balance after rebalancing
vaultBalance_uint256The new vault balance after rebalancing

_calcImbalanceOpenBps

Calculates the current imbalance for the open action checks.

If the value is positive, the long trading exposure is larger than the vault trading exposure. In case of an empty vault balance, returns int256.max since the resulting imbalance would be infinity.

function _calcImbalanceOpenBps(int256 vaultExpo, int256 longBalance, uint256 totalExpo)
    internal
    pure
    returns (int256 imbalanceBps_);

Parameters

NameTypeDescription
vaultExpoint256The vault exposure (including the pending vault balance and the fees of the position to open).
longBalanceint256The balance of the long side (including the long position to open).
totalExpouint256The total exposure of the long side (including the long position to open).

Returns

NameTypeDescription
imbalanceBps_int256The imbalance (in basis points).

_unadjustedPriceToTick

Calculates the tick corresponding to an unadjusted price, without rounding to the tick spacing.

function _unadjustedPriceToTick(uint256 unadjustedPrice) internal pure returns (int24 tick_);

Parameters

NameTypeDescription
unadjustedPriceuint256The unadjusted price.

Returns

NameTypeDescription
tick_int24The tick number, bound by MIN_TICK.

_roundTickDown

Rounds a tick down to a multiple of the tick spacing.

The function is bound by minTick, so the first tick which is a multiple of the tick spacing and greater than or equal to MIN_TICK.

function _roundTickDown(int24 tick, int24 tickSpacing) internal pure returns (int24 roundedTick_);

Parameters

NameTypeDescription
tickint24The tick number.
tickSpacingint24The tick spacing.

Returns

NameTypeDescription
roundedTick_int24The rounded tick number.

_roundTickDownWithPenalty

Rounds the given tick down to a multiple of the tick spacing .

The result will always be above MIN_TICK + liquidationPenalty.

function _roundTickDownWithPenalty(int24 tickWithPenalty, int24 tickSpacing, uint24 liqPenalty)
    internal
    pure
    returns (int24 roundedTick_);

Parameters

NameTypeDescription
tickWithPenaltyint24The tick number with the liquidation penalty.
tickSpacingint24The tick spacing.
liqPenaltyuint24The liquidation penalty.

Returns

NameTypeDescription
roundedTick_int24The rounded tick number.

_getEffectiveTickForPriceNoRounding

Calculates the effective tick for a given price without rounding to the tick spacing.

function _getEffectiveTickForPriceNoRounding(
    uint128 price,
    uint256 assetPrice,
    uint256 longTradingExpo,
    HugeUint.Uint512 memory accumulator
) internal pure returns (int24 tick_);

Parameters

NameTypeDescription
priceuint128The price to be adjusted.
assetPriceuint256The current asset price.
longTradingExpouint256The long trading exposure.
accumulatorHugeUint.Uint512The liquidation multiplier accumulator.

Returns

NameTypeDescription
tick_int24The tick number.

_getEffectiveTickForPriceNoRounding

Calculates the effective tick for a given price without rounding to the tick spacing with a fixed precision representation of the liquidation multiplier.

function _getEffectiveTickForPriceNoRounding(uint128 price, uint256 liqMultiplier)
    internal
    pure
    returns (int24 tick_);

Parameters

NameTypeDescription
priceuint128The price to be adjusted.
liqMultiplieruint256The liquidation price multiplier (with LIQUIDATION_MULTIPLIER_DECIMALS decimals).

Returns

NameTypeDescription
tick_int24The tick number.

_calcRebaseTotalSupply

Calculates the required USDN total supply to reach targetPrice.

function _calcRebaseTotalSupply(uint256 vaultBalance, uint128 assetPrice, uint128 targetPrice, uint8 assetDecimals)
    internal
    pure
    returns (uint256 totalSupply_);

Parameters

NameTypeDescription
vaultBalanceuint256The balance of the vault.
assetPriceuint128The price of the underlying asset.
targetPriceuint128The target USDN price to reach.
assetDecimalsuint8The number of decimals of the asset.

Returns

NameTypeDescription
totalSupply_uint256The required total supply to achieve targetPrice.

Structs

LiquidationData

Structure to hold the temporary data during liquidations.

struct LiquidationData {
    int256 tempLongBalance;
    int256 tempVaultBalance;
    int24 currentTick;
    int24 iTick;
    uint256 totalExpoToRemove;
    uint256 accumulatorValueToRemove;
    uint256 longTradingExpo;
    uint256 currentPrice;
    HugeUint.Uint512 accumulator;
    bool isLiquidationPending;
}

Properties

NameTypeDescription
tempLongBalanceint256The updated long balance not saved into storage yet.
tempVaultBalanceint256The updated vault balance not saved into storage yet.
currentTickint24The current tick (corresponding to the current asset price).
iTickint24Tick iterator index.
totalExpoToRemoveuint256The total exposure to remove due to liquidations.
accumulatorValueToRemoveuint256The value to remove from the liquidation multiplier accumulator due to liquidations.
longTradingExpouint256The long trading exposure.
currentPriceuint256The current price of the asset.
accumulatorHugeUint.Uint512The liquidation multiplier accumulator before liquidations.
isLiquidationPendingboolWhether some ticks are still populated above the current price (left to liquidate).

ApplyPnlAndFundingAndLiquidateData

Data structure for the _applyPnlAndFundingAndLiquidate function.

struct ApplyPnlAndFundingAndLiquidateData {
    int256 tempLongBalance;
    int256 tempVaultBalance;
    uint128 lastPrice;
    bool rebased;
    bytes callbackResult;
    Types.RebalancerAction rebalancerAction;
}

Properties

NameTypeDescription
tempLongBalanceint256The updated long balance not saved into storage yet.
tempVaultBalanceint256The updated vault balance not saved into storage yet.
lastPriceuint128The last price used to update the protocol.
rebasedboolA boolean indicating if the USDN token was rebased.
callbackResultbytesThe result of the USDN rebase callback.
rebalancerActionTypes.RebalancerActionThe action performed by the _triggerRebalancer function.

TriggerRebalancerData

Data structure for the _triggerRebalancer function.

struct TriggerRebalancerData {
    uint128 positionAmount;
    uint256 rebalancerMaxLeverage;
    Types.PositionId rebalancerPosId;
    uint128 positionValue;
}

Properties

NameTypeDescription
positionAmountuint128The amount of assets in the rebalancer's position.
rebalancerMaxLeverageuint256The maximum leverage of the rebalancer.
rebalancerPosIdTypes.PositionIdThe ID of the rebalancer's position.
positionValueuint128The value of the rebalancer's position.

UsdnProtocolSettersLibrary

Git Source

Functions

setOracleMiddleware

See setOracleMiddleware.

function setOracleMiddleware(IBaseOracleMiddleware newOracleMiddleware) external;

setLiquidationRewardsManager

See setLiquidationRewardsManager.

function setLiquidationRewardsManager(IBaseLiquidationRewardsManager newLiquidationRewardsManager) external;

setRebalancer

See setRebalancer.

function setRebalancer(IBaseRebalancer newRebalancer) external;

setFeeCollector

See setFeeCollector.

function setFeeCollector(address newFeeCollector) external;

setValidatorDeadlines

See setValidatorDeadlines.

function setValidatorDeadlines(uint128 newLowLatencyValidatorDeadline, uint128 newOnChainValidatorDeadline) external;

setMinLeverage

See setMinLeverage.

function setMinLeverage(uint256 newMinLeverage) external;

setMaxLeverage

See setMaxLeverage.

function setMaxLeverage(uint256 newMaxLeverage) external;

setLiquidationPenalty

See setLiquidationPenalty.

function setLiquidationPenalty(uint24 newLiquidationPenalty) external;

setEMAPeriod

See setEMAPeriod.

function setEMAPeriod(uint128 newEMAPeriod) external;

setFundingSF

See setFundingSF.

function setFundingSF(uint256 newFundingSF) external;

setProtocolFeeBps

See setProtocolFeeBps.

function setProtocolFeeBps(uint16 newProtocolFeeBps) external;

setPositionFeeBps

See setPositionFeeBps.

function setPositionFeeBps(uint16 newPositionFee) external;

setVaultFeeBps

See setVaultFeeBps.

function setVaultFeeBps(uint16 newVaultFee) external;

setSdexRewardsRatioBps

See setSdexRewardsRatioBps.

function setSdexRewardsRatioBps(uint16 newRewards) external;

setRebalancerBonusBps

See setRebalancerBonusBps.

function setRebalancerBonusBps(uint16 newBonus) external;

setSdexBurnOnDepositRatio

See setSdexBurnOnDepositRatio.

function setSdexBurnOnDepositRatio(uint256 highestPossibleValue, uint64 newRatio) external;

setSecurityDepositValue

See setSecurityDepositValue.

function setSecurityDepositValue(uint64 securityDepositValue) external;

setExpoImbalanceLimits

See setExpoImbalanceLimits.

function setExpoImbalanceLimits(
    uint256 newOpenLimitBps,
    uint256 newDepositLimitBps,
    uint256 newWithdrawalLimitBps,
    uint256 newCloseLimitBps,
    uint256 newRebalancerCloseLimitBps,
    int256 newLongImbalanceTargetBps
) external;

setMinLongPosition

See setMinLongPosition.

function setMinLongPosition(uint256 highestPossibleValue, uint256 newMinLongPosition) external;

setSafetyMarginBps

See setSafetyMarginBps.

function setSafetyMarginBps(uint256 newSafetyMarginBps) external;

setLiquidationIteration

See setLiquidationIteration.

function setLiquidationIteration(uint16 newLiquidationIteration) external;

setFeeThreshold

See setFeeThreshold.

function setFeeThreshold(uint256 newFeeThreshold) external;

setTargetUsdnPrice

See setTargetUsdnPrice.

function setTargetUsdnPrice(uint128 newPrice) external;

setUsdnRebaseThreshold

See setUsdnRebaseThreshold.

function setUsdnRebaseThreshold(uint128 newThreshold) external;

setInitialStorage

Set the initial storage during the initialization of the protocol.

function setInitialStorage(Types.InitStorage calldata initStorage) external;

Parameters

NameTypeDescription
initStorageTypes.InitStorageThe initialization parameters struct.

UsdnProtocolUtilsLibrary

Git Source

A library of utility functions for the USDN protocol. This library is not intended to be deployed as an external library.

All functions in this library must be marked as "internal".

State Variables

STORAGE_MAIN

Constant representing the storage slot for the protocol main storage.

Calculated as: keccak256(abi.encode(uint256(keccak256("UsdnProtocol.storage.main")) - 1)) & ~bytes32(uint256(0xff))

bytes32 private constant STORAGE_MAIN = 0xd143a936a6a372725e12535db83a2cfabcb3715dfd88bc350da3399604dc9700;

Functions

_getMainStorage

Gets the main storage pointer.

function _getMainStorage() internal pure returns (Types.Storage storage s_);

Returns

NameTypeDescription
s_Types.StorageThe pointer to the main storage structure.

_refundExcessEther

Refunds excess Ether to prevent unintended locking of funds.

function _refundExcessEther(uint256 securityDepositValue, uint256 amountToRefund, uint256 balanceBefore) internal;

Parameters

NameTypeDescription
securityDepositValueuint256The security deposit for the current action (zero for validation actions).
amountToRefunduint256The amount to refund to the user: the security deposit when executing an action for another user, and/or the initialization security deposit in the case of a validation action.
balanceBeforeuint256The contract's balance before the action.

_refundEther

Refunds Ether to a specified address.

function _refundEther(uint256 amount, address payable to) internal;

Parameters

NameTypeDescription
amountuint256The amount of Ether to refund.
toaddress payableThe address receiving the refund.

_checkPendingFee

Distributes the protocol fee to the fee collector if the pending amount exceeds the threshold.

Attempts to invoke the feeCollectorCallback function on the fee collector if supported.

function _checkPendingFee() internal;

_getOraclePrice

Gets and validate the oracle price for a specified action and timestamp.

function _getOraclePrice(Types.ProtocolAction action, uint256 timestamp, bytes32 actionId, bytes calldata priceData)
    internal
    returns (PriceInfo memory price_);

Parameters

NameTypeDescription
actionTypes.ProtocolActionThe protocol action being performed.
timestampuint256The timestamp for which the price is queried.
actionIdbytes32The unique identifier of the action.
priceDatabytesThe encoded oracle price data.

Returns

NameTypeDescription
price_PriceInfoThe validated price information.

_clearPendingAction

Clears the pending action of a user.

function _clearPendingAction(address user, uint128 rawIndex) internal;

Parameters

NameTypeDescription
useraddressThe user's address.
rawIndexuint128The rawIndex of the pending action in the queue.

_longAssetAvailable

Calculates the long balance, including unreflected PnL (excluding funding).

This function uses the latest total exposure, balance, and stored price as reference values. It adjusts the balance by adding the PnL resulting from the price change.

function _longAssetAvailable(uint128 currentPrice) internal view returns (int256 available_);

Parameters

NameTypeDescription
currentPriceuint128The current price of the asset.

Returns

NameTypeDescription
available_int256The updated balance on the long side.

_tickHash

Calculates the hash of the given tick number and its current version.

function _tickHash(int24 tick) internal view returns (bytes32 hash_, uint256 version_);

Parameters

NameTypeDescription
tickint24The tick number.

Returns

NameTypeDescription
hash_bytes32The hash of the tick.
version_uint256The version of the tick.

_calcBitmapIndexFromTick

Calculates the corresponding index of the given tick in the Bitmap, based on the storage tick spacing.

function _calcBitmapIndexFromTick(int24 tick) internal view returns (uint256 index_);

Parameters

NameTypeDescription
tickint24The tick number, a multiple of the tick spacing.

Returns

NameTypeDescription
index_uint256The index into the Bitmap.

_getEffectivePriceForTick

Gets the effective price, accounting for funding, for a given tick.

function _getEffectivePriceForTick(int24 tick) internal view returns (uint128 price_);

Parameters

NameTypeDescription
tickint24The tick number.

Returns

NameTypeDescription
price_uint128The effective price for the tick.

_tickHash

Generates a hash based on the tick and a version.

function _tickHash(int24 tick, uint256 version) internal pure returns (bytes32);

Parameters

NameTypeDescription
tickint24The tick number.
versionuint256The tick version.

Returns

NameTypeDescription
<none>bytes32The hash value.

_toInt256

Converts a uint128 to an int256.

function _toInt256(uint128 x) internal pure returns (int256);

Parameters

NameTypeDescription
xuint128The uint128 value to convert.

Returns

NameTypeDescription
<none>int256The resulting int256 value.

_positionValueOptimized

Optimized position value calculation when posTotalExpo is known to be a uint128 and currentPrice is guaranteed to be above liqPriceWithoutPenalty.

function _positionValueOptimized(uint128 posTotalExpo, uint128 currentPrice, uint128 liqPriceWithoutPenalty)
    internal
    pure
    returns (uint256 posValue_);

Parameters

NameTypeDescription
posTotalExpouint128The total exposure of the position.
currentPriceuint128The current asset price.
liqPriceWithoutPenaltyuint128The liquidation price without penalty.

Returns

NameTypeDescription
posValue_uint256The calculated position value.

_calcTickWithoutPenalty

Calculates the tick number without considering the liquidation penalty.

function _calcTickWithoutPenalty(int24 tick, uint24 liquidationPenalty) internal pure returns (int24 tick_);

Parameters

NameTypeDescription
tickint24The tick number that holds the position.
liquidationPenaltyuint24The liquidation penalty, measured in ticks.

Returns

NameTypeDescription
tick_int24The tick number adjusted to exclude the liquidation penalty.

_getLiquidationPrice

Calculates the theoretical liquidation price of a position using its entry price and leverage.

function _getLiquidationPrice(uint128 startPrice, uint128 leverage) internal pure returns (uint128 price_);

Parameters

NameTypeDescription
startPriceuint128The entry price of the position.
leverageuint128The leverage of the position.

Returns

NameTypeDescription
price_uint128The computed liquidation price.

_getLeverage

Calculates the leverage of a position using its entry price and liquidation price.

The calculation does not take into account the liquidation penalty.

function _getLeverage(uint128 startPrice, uint128 liquidationPrice) internal pure returns (uint256 leverage_);

Parameters

NameTypeDescription
startPriceuint128The entry price of the position.
liquidationPriceuint128The price at which the position would be liquidated.

Returns

NameTypeDescription
leverage_uint256The computed leverage value.

_convertLongPendingAction

Converts the given LongPendingAction to a PendingAction.

function _convertLongPendingAction(Types.LongPendingAction memory action)
    internal
    pure
    returns (Types.PendingAction memory pendingAction_);

Parameters

NameTypeDescription
actionTypes.LongPendingActionThe long pending action.

Returns

NameTypeDescription
pendingAction_Types.PendingActionThe converted untyped pending action.

_convertWithdrawalPendingAction

Converts the given WithdrawalPendingAction to a PendingAction.

function _convertWithdrawalPendingAction(Types.WithdrawalPendingAction memory action)
    internal
    pure
    returns (Types.PendingAction memory pendingAction_);

Parameters

NameTypeDescription
actionTypes.WithdrawalPendingActionThe withdrawal pending action.

Returns

NameTypeDescription
pendingAction_Types.PendingActionThe converted untyped pending action.

_convertDepositPendingAction

Converts the given DepositPendingAction to a PendingAction.

function _convertDepositPendingAction(Types.DepositPendingAction memory action)
    internal
    pure
    returns (Types.PendingAction memory pendingAction_);

Parameters

NameTypeDescription
actionTypes.DepositPendingActionThe deposit pending action.

Returns

NameTypeDescription
pendingAction_Types.PendingActionThe converted untyped pending action.

_toLongPendingAction

Converts the given PendingAction to a LongPendingAction.

function _toLongPendingAction(Types.PendingAction memory action)
    internal
    pure
    returns (Types.LongPendingAction memory longAction_);

Parameters

NameTypeDescription
actionTypes.PendingActionThe untyped pending action.

Returns

NameTypeDescription
longAction_Types.LongPendingActionThe converted long pending action.

_toDepositPendingAction

Converts the given PendingAction to a DepositPendingAction.

function _toDepositPendingAction(Types.PendingAction memory action)
    internal
    pure
    returns (Types.DepositPendingAction memory vaultAction_);

Parameters

NameTypeDescription
actionTypes.PendingActionThe untyped pending action.

Returns

NameTypeDescription
vaultAction_Types.DepositPendingActionThe converted deposit pending action.

_toWithdrawalPendingAction

Converts the given PendingAction to a WithdrawalPendingAction.

function _toWithdrawalPendingAction(Types.PendingAction memory action)
    internal
    pure
    returns (Types.WithdrawalPendingAction memory vaultAction_);

Parameters

NameTypeDescription
actionTypes.PendingActionThe untyped pending action.

Returns

NameTypeDescription
vaultAction_Types.WithdrawalPendingActionThe converted withdrawal pending action.

_calcBitmapIndexFromTick

Calculates the corresponding index of the given tick in the Bitmap, based on the specified tick spacing.

function _calcBitmapIndexFromTick(int24 tick, int24 tickSpacing) internal pure returns (uint256 index_);

Parameters

NameTypeDescription
tickint24The tick, which must be a multiple of tickSpacing.
tickSpacingint24The tick spacing to use.

Returns

NameTypeDescription
index_uint256The corresponding index into the Bitmap.

_mergeWithdrawalAmountParts

Merges the two parts of the withdrawal amount (USDN shares) stored in the WithdrawalPendingAction.

function _mergeWithdrawalAmountParts(uint24 sharesLSB, uint128 sharesMSB) internal pure returns (uint256 usdnShares_);

Parameters

NameTypeDescription
sharesLSBuint24The lower 24 bits of the USDN shares.
sharesMSBuint128The higher bits of the USDN shares.

Returns

NameTypeDescription
usdnShares_uint256The amount of USDN shares.

_longAssetAvailable

Calculates the updated balance of the long side, considering unreflected PnL (excluding funding).

function _longAssetAvailable(uint256 totalExpo, uint256 balanceLong, uint128 newPrice, uint128 oldPrice)
    internal
    pure
    returns (int256 available_);

Parameters

NameTypeDescription
totalExpouint256The total exposure of the long side.
balanceLonguint256The previous balance of the long side.
newPriceuint128The updated price of the asset.
oldPriceuint128The previous price used to calculate the prior balance.

Returns

NameTypeDescription
available_int256The updated balance of the long side.

_calcImbalanceCloseBps

Calculates the imbalance between the vault and long sides.

A positive value indicates the long trading exposure is smaller than the vault's. If the trading exposure is equal to 0, the imbalance is infinite and int256.max is returned.

function _calcImbalanceCloseBps(int256 vaultBalance, int256 longBalance, uint256 totalExpo)
    internal
    pure
    returns (int256 imbalanceBps_);

Parameters

NameTypeDescription
vaultBalanceint256The balance of the vault.
longBalanceint256The balance of the long side.
totalExpouint256The total exposure of the long side.

Returns

NameTypeDescription
imbalanceBps_int256The imbalance, expressed in basis points.

_calcPositionTotalExpo

Calculates the total exposure of a position.

Reverts if startPrice <= liquidationPrice.

function _calcPositionTotalExpo(uint128 amount, uint128 startPrice, uint128 liquidationPrice)
    internal
    pure
    returns (uint128 totalExpo_);

Parameters

NameTypeDescription
amountuint128The amount of assets used as collateral.
startPriceuint128The asset price when the position was created.
liquidationPriceuint128The liquidation price of the position.

Returns

NameTypeDescription
totalExpo_uint128The total exposure of the position.

_positionValue

Calculates the value of a position based on its liquidation price and the current asset price.

function _positionValue(uint128 positionTotalExpo, uint128 currentPrice, uint128 liqPriceWithoutPenalty)
    internal
    pure
    returns (int256 value_);

Parameters

NameTypeDescription
positionTotalExpouint128The total exposure of the position.
currentPriceuint128The current price of the asset.
liqPriceWithoutPenaltyuint128The liquidation price of the position without the liquidation penalty.

Returns

NameTypeDescription
value_int256The position's value. Negative values indicate bad debt.

_calcFixedPrecisionMultiplier

Calculates a fixed-precision representation of the liquidation price multiplier.

function _calcFixedPrecisionMultiplier(uint256 assetPrice, uint256 longTradingExpo, HugeUint.Uint512 memory accumulator)
    internal
    pure
    returns (uint256 multiplier_);

Parameters

NameTypeDescription
assetPriceuint256The current price of the asset.
longTradingExpouint256The trading exposure of the long side.
accumulatorHugeUint.Uint512The liquidation multiplier accumulator.

Returns

NameTypeDescription
multiplier_uint256The liquidation price multiplier.

_adjustPrice

Variant of _adjustPrice when a fixed precision representation of the liquidation multiplier is known.

function _adjustPrice(uint256 unadjustedPrice, uint256 liqMultiplier) internal pure returns (uint128 price_);

Parameters

NameTypeDescription
unadjustedPriceuint256The unadjusted price for the tick.
liqMultiplieruint256The liquidation price multiplier.

Returns

NameTypeDescription
price_uint128The adjusted price for the tick.

_calcMintUsdnShares

Calculates the amount of USDN shares to mint for a given amount of assets.

function _calcMintUsdnShares(uint256 amount, uint256 vaultBalance, uint256 usdnTotalShares)
    internal
    pure
    returns (uint256 toMint_);

Parameters

NameTypeDescription
amountuint256The amount of assets to be converted into USDN.
vaultBalanceuint256The current balance of the vault.
usdnTotalSharesuint256The total supply of USDN shares.

Returns

NameTypeDescription
toMint_uint256The amount of USDN shares to mint.

_calcSdexToBurn

Calculates the amount of SDEX tokens to burn when minting USDN tokens.

The result is rounded up to ensure at least 1 wei of SDEX is burned.

function _calcSdexToBurn(uint256 usdnAmount, uint64 sdexBurnRatio) internal pure returns (uint256 sdexToBurn_);

Parameters

NameTypeDescription
usdnAmountuint256The amount of USDN to be minted.
sdexBurnRatiouint64The ratio of SDEX burned per minted USDN.

Returns

NameTypeDescription
sdexToBurn_uint256The amount of SDEX tokens to burn.

_calcActionId

Calculates a unique identifier for a pending action.

This identifier can be used by the oracle middleware to link an Initiate call with the corresponding Validate call.

function _calcActionId(address validator, uint128 initiateTimestamp) internal pure returns (bytes32 actionId_);

Parameters

NameTypeDescription
validatoraddressThe address of the validator.
initiateTimestampuint128The timestamp of the Initiate action.

Returns

NameTypeDescription
actionId_bytes32The unique action ID.

_calcAmountToWithdraw

Calculates the amount of assets received when burning USDN shares, accounting for fees.

function _calcAmountToWithdraw(
    uint256 usdnShares,
    uint256 vaultAvailableBalance,
    uint256 usdnSharesTotalSupply,
    uint256 feeBps
) internal pure returns (uint256 expectedAssetsAmount_);

Parameters

NameTypeDescription
usdnSharesuint256The amount of USDN shares to burn.
vaultAvailableBalanceuint256The available amount of assets in the vault.
usdnSharesTotalSupplyuint256The total supply of USDN shares.
feeBpsuint256The fee in basis points.

Returns

NameTypeDescription
expectedAssetsAmount_uint256The expected amount of assets to be received after deducting fees.

_vaultAssetAvailable

Calculates the available balance in the vault for a given price, excluding funding effects.

function _vaultAssetAvailable(
    uint256 totalExpo,
    uint256 balanceVault,
    uint256 balanceLong,
    uint128 newPrice,
    uint128 oldPrice
) internal pure returns (int256 available_);

Parameters

NameTypeDescription
totalExpouint256The total long exposure.
balanceVaultuint256The previous balance of the vault.
balanceLonguint256The previous balance of the long side.
newPriceuint128The updated price.
oldPriceuint128The price used when the previous balances were calculated.

Returns

NameTypeDescription
available_int256The available balance in the vault.

_adjustPrice

Adjusts the tick price by accounting for the effects of funding.

function _adjustPrice(
    uint256 unadjustedPrice,
    uint256 assetPrice,
    uint256 longTradingExpo,
    HugeUint.Uint512 memory accumulator
) internal pure returns (uint128 price_);

Parameters

NameTypeDescription
unadjustedPriceuint256The tick's unadjusted price.
assetPriceuint256The current price of the asset.
longTradingExpouint256The trading exposure of the long side.
accumulatorHugeUint.Uint512The liquidation multiplier accumulator.

Returns

NameTypeDescription
price_uint128The adjusted tick price.

_transferCallback

Invokes a callback on the msg.sender to transfer assets and verifies that they were received.

function _transferCallback(IERC20Metadata token, uint256 amount, address to) internal;

Parameters

NameTypeDescription
tokenIERC20MetadataThe ERC-20 token to transfer.
amountuint256The amount of tokens to transfer.
toaddressThe recipient's address.

_usdnTransferCallback

Invokes a callback on the msg.sender to transfer USDN shares and verifies that they were received.

function _usdnTransferCallback(IUsdn usdn, uint256 shares) internal;

Parameters

NameTypeDescription
usdnIUsdnThe address of the USDN token contract.
sharesuint256The amount of USDN shares to transfer.

_getEffectivePriceForTick

Calculates the effective price for a tick, adjusted for funding effects.

function _getEffectivePriceForTick(
    int24 tick,
    uint256 assetPrice,
    uint256 longTradingExpo,
    HugeUint.Uint512 memory accumulator
) internal pure returns (uint128 price_);

Parameters

NameTypeDescription
tickint24The tick number.
assetPriceuint256The current price of the asset.
longTradingExpouint256The trading exposure of the long side.
accumulatorHugeUint.Uint512The liquidation multiplier accumulator.

Returns

NameTypeDescription
price_uint128The adjusted price for the tick.

_getEffectivePriceForTick

Variant of _getEffectivePriceForTick when a fixed precision representation of the liquidation multiplier is known.

function _getEffectivePriceForTick(int24 tick, uint256 liqMultiplier) internal pure returns (uint128 price_);

Parameters

NameTypeDescription
tickint24The tick number.
liqMultiplieruint256The liquidation price multiplier.

Returns

NameTypeDescription
price_uint128The adjusted price for the tick.

UsdnProtocolVaultLibrary

Git Source

Functions

initiateDeposit

See initiateDeposit.

function initiateDeposit(
    uint128 amount,
    uint256 sharesOutMin,
    address to,
    address payable validator,
    uint256 deadline,
    bytes calldata currentPriceData,
    Types.PreviousActionsData calldata previousActionsData
) external returns (bool success_);

validateDeposit

See validateDeposit.

function validateDeposit(
    address payable validator,
    bytes calldata depositPriceData,
    Types.PreviousActionsData calldata previousActionsData
) external returns (bool success_);

initiateWithdrawal

See initiateWithdrawal.

function initiateWithdrawal(
    uint152 usdnShares,
    uint256 amountOutMin,
    address to,
    address payable validator,
    uint256 deadline,
    bytes calldata currentPriceData,
    Types.PreviousActionsData calldata previousActionsData
) external returns (bool success_);

validateWithdrawal

See validateWithdrawal.

function validateWithdrawal(
    address payable validator,
    bytes calldata withdrawalPriceData,
    Types.PreviousActionsData calldata previousActionsData
) external returns (bool success_);

getActionablePendingActions

See getActionablePendingActions.

function getActionablePendingActions(address currentUser, uint256 lookAhead, uint256 maxIter)
    external
    view
    returns (Types.PendingAction[] memory actions_, uint128[] memory rawIndices_);

usdnPrice

See usdnPrice.

function usdnPrice(uint128 currentPrice) external view returns (uint256 price_);

usdnPrice

See usdnPrice.

function usdnPrice(uint128 currentPrice, uint128 timestamp) public view returns (uint256 price_);

vaultAssetAvailableWithFunding

See vaultAssetAvailableWithFunding.

function vaultAssetAvailableWithFunding(uint128 currentPrice, uint128 timestamp)
    public
    view
    returns (uint256 available_);

_executePendingActionOrRevert

Executes the first actionable pending action.

Will revert if the corresponding price data is invalid.

function _executePendingActionOrRevert(Types.PreviousActionsData calldata data)
    public
    returns (uint256 securityDepositValue_);

Parameters

NameTypeDescription
dataTypes.PreviousActionsDataThe price data and corresponding raw indices.

Returns

NameTypeDescription
securityDepositValue_uint256The security deposit value of the executed action.

_executePendingAction

Executes the first actionable pending action and reports the outcome.

function _executePendingAction(Types.PreviousActionsData calldata data)
    public
    returns (bool success_, bool executed_, bool liquidated_, uint256 securityDepositValue_);

Parameters

NameTypeDescription
dataTypes.PreviousActionsDataThe price data and corresponding raw indices.

Returns

NameTypeDescription
success_boolWhether the price data is valid.
executed_boolWhether the pending action was executed (false if the queue has no actionable item).
liquidated_boolWhether the position corresponding to the pending action was liquidated.
securityDepositValue_uint256The security deposit value of the executed action.

_getActionablePendingAction

This is the mutating version of getActionablePendingActions, where empty items at the front of the list are removed.

function _getActionablePendingAction() internal returns (Types.PendingAction memory action_, uint128 rawIndex_);

Returns

NameTypeDescription
action_Types.PendingActionThe first actionable pending action if any, otherwise a struct with all fields set to zero and ProtocolAction's None action.
rawIndex_uint128The raw index in the queue for the returned pending action, or zero if empty.

_prepareInitiateDepositData

Prepares the data for the initiateDeposit function.

Updates the protocol's balances if the price is fresh.

function _prepareInitiateDepositData(
    address validator,
    uint128 amount,
    uint256 sharesOutMin,
    bytes calldata currentPriceData
) internal returns (InitiateDepositData memory data_);

Parameters

NameTypeDescription
validatoraddressThe address that is supposed to validate the deposit and receive the security deposit.
amountuint128The amount of asset to deposit.
sharesOutMinuint256The minimum amount of USDN shares to receive.
currentPriceDatabytesThe current price data.

Returns

NameTypeDescription
data_InitiateDepositDataThe transient data for the deposit action.

_createDepositPendingAction

Prepares the pending action struct for a deposit and adds it to the queue.

function _createDepositPendingAction(
    address to,
    address validator,
    uint64 securityDepositValue,
    uint128 amount,
    InitiateDepositData memory data
) internal returns (uint256 amountToRefund_);

Parameters

NameTypeDescription
toaddressThe recipient of the minted USDN.
validatoraddressThe address that is supposed to validate the deposit and receive the security deposit.
securityDepositValueuint64The value of the security deposit for the newly created pending action.
amountuint128The amount of assets to deposit (before fees).
dataInitiateDepositDataThe deposit action data.

Returns

NameTypeDescription
amountToRefund_uint256The security deposit value of a stale pending action.

_initiateDeposit

Attempts to initiate a deposit of assets into the vault to mint USDN.

Consults the current oracle middleware implementation to know the expected format for the price data, using the ProtocolAction's InitiateDeposit action. The price validation might require payment according to the return value of the validationCost function of the middleware.

function _initiateDeposit(InitiateDepositParams memory params, bytes calldata currentPriceData)
    internal
    returns (uint256 amountToRefund_, bool isInitiated_);

Parameters

NameTypeDescription
paramsInitiateDepositParamsThe parameters for the deposit.
currentPriceDatabytesThe current price data.

Returns

NameTypeDescription
amountToRefund_uint256If there are pending liquidations we'll refund the securityDepositValue, else we'll only refund the security deposit value of the stale pending action.
isInitiated_boolWhether the action is initiated.

_validateDeposit

Attempts to validate the deposit pending action assigned to the given validator.

If successful, the pending action will be cleared from the queue.

function _validateDeposit(address validator, bytes calldata priceData)
    internal
    returns (uint256 securityDepositValue_, bool isValidated_);

Parameters

NameTypeDescription
validatoraddressThe address that is supposed to validate the deposit and receive the security deposit.
priceDatabytesThe price data for the pending action to validate.

Returns

NameTypeDescription
securityDepositValue_uint256The value of the security deposit to refund.
isValidated_boolWhether the action is validated.

_validateDepositWithAction

Attempts to validate the given deposit pending action.

function _validateDepositWithAction(Types.PendingAction memory pending, bytes calldata priceData)
    internal
    returns (bool isValidated_);

Parameters

NameTypeDescription
pendingTypes.PendingActionThe pending action to validate.
priceDatabytesThe corresponding price data.

Returns

NameTypeDescription
isValidated_boolWhether the action is validated.

_prepareWithdrawalData

Prepares the data for the initiateWithdrawal function.

Updates the protocol's balances if the price is fresh.

function _prepareWithdrawalData(
    address validator,
    uint152 usdnShares,
    uint256 amountOutMin,
    bytes calldata currentPriceData
) internal returns (WithdrawalData memory data_);

Parameters

NameTypeDescription
validatoraddressThe address that is supposed to validate the withdrawal and receive the security deposit.
usdnSharesuint152The amount of USDN shares to burn.
amountOutMinuint256The estimated minimum amount of assets to receive.
currentPriceDatabytesThe current price data.

Returns

NameTypeDescription
data_WithdrawalDataThe transient data for the withdrawal action.

_initiateWithdrawal

Initiates a withdrawal of assets from the vault by providing USDN tokens.

Consults the current oracle middleware implementation to know the expected format for the price data, using the ProtocolAction's InitiateWithdrawal action. The price validation might require payment according to the return value of the validationCost function of the middleware.

function _initiateWithdrawal(WithdrawalParams memory params, bytes calldata currentPriceData)
    internal
    returns (uint256 amountToRefund_, bool isInitiated_);

Parameters

NameTypeDescription
paramsWithdrawalParamsThe parameters for the withdrawal.
currentPriceDatabytesThe current price data.

Returns

NameTypeDescription
amountToRefund_uint256If there are pending liquidations we'll refund the sent security deposit, else we'll only refund the security deposit value of the stale pending action.
isInitiated_boolWhether the action is initiated.

_validateWithdrawal

Attempts to validate the withdrawal pending action assigned to the given validator.

If successful, the pending action will be cleared from the queue.

function _validateWithdrawal(address validator, bytes calldata priceData)
    internal
    returns (uint256 securityDepositValue_, bool isValidated_);

Parameters

NameTypeDescription
validatoraddressThe address that is supposed to validate the withdrawal and receive the security deposit.
priceDatabytesThe corresponding price data.

Returns

NameTypeDescription
securityDepositValue_uint256The value of the security deposit.
isValidated_boolWhether the action is validated.

_validateWithdrawalWithAction

Attempts to validate the given withdrawal pending action.

function _validateWithdrawalWithAction(Types.PendingAction memory pending, bytes calldata priceData)
    internal
    returns (bool isValidated_);

Parameters

NameTypeDescription
pendingTypes.PendingActionThe pending action data.
priceDatabytesThe current price data.

Returns

NameTypeDescription
isValidated_boolWhether the action is validated.

_isActionable

Checks whether a pending action is actionable, i.e any user can validate it and retrieve the security deposit.

Between initiateTimestamp and initiateTimestamp + lowLatencyDeadline, the validator receives the security deposit. Between initiateTimestamp + lowLatencyDelay and initiateTimestamp + lowLatencyDelay + onChainDeadline, the validator also receives the security deposit. Outside of those periods, the security deposit goes to the user validating the pending action.

function _isActionable(
    uint256 initiateTimestamp,
    uint256 lowLatencyDeadline,
    uint256 lowLatencyDelay,
    uint256 onChainDeadline
) internal view returns (bool actionable_);

Parameters

NameTypeDescription
initiateTimestampuint256The timestamp at which the action was initiated.
lowLatencyDeadlineuint256The deadline after which the action is actionable with a low latency oracle.
lowLatencyDelayuint256The amount of time the action can be validated with a low latency oracle.
onChainDeadlineuint256The deadline after which the action is actionable with an on-chain oracle.

Returns

NameTypeDescription
actionable_boolWhether the pending action is actionable.

_vaultAssetAvailable

Calculates the available balance in the vault if the price moves to currentPrice.

The funding is not taken into account.

function _vaultAssetAvailable(uint128 currentPrice) internal view returns (int256 available_);

Parameters

NameTypeDescription
currentPriceuint128The current or predicted price.

Returns

NameTypeDescription
available_int256The available balance in the vault.

_calcUsdnPrice

Calculates the price of the USDN token as a function of its total supply, the vault balance and the underlying asset price.

function _calcUsdnPrice(uint256 vaultBalance, uint128 assetPrice, uint256 usdnTotalSupply, uint8 assetDecimals)
    internal
    pure
    returns (uint256 price_);

Parameters

NameTypeDescription
vaultBalanceuint256The vault balance.
assetPriceuint128The price of the asset.
usdnTotalSupplyuint256The total supply of the USDN token.
assetDecimalsuint8The number of decimals of the underlying asset.

Returns

NameTypeDescription
price_uint256The price of the USDN token.

_calcWithdrawalAmountLSB

Calculates the lower 24 bits of the withdrawal amount (USDN shares).

function _calcWithdrawalAmountLSB(uint152 usdnShares) internal pure returns (uint24 sharesLSB_);

Parameters

NameTypeDescription
usdnSharesuint152The amount of USDN shares.

Returns

NameTypeDescription
sharesLSB_uint24The 24 least significant bits of the USDN shares.

_calcWithdrawalAmountMSB

Calculates the higher 128 bits of the withdrawal amount (USDN shares).

function _calcWithdrawalAmountMSB(uint152 usdnShares) internal pure returns (uint128 sharesMSB_);

Parameters

NameTypeDescription
usdnSharesuint152The amount of USDN shares.

Returns

NameTypeDescription
sharesMSB_uint128The 128 most significant bits of the USDN shares.

Structs

InitiateDepositParams

Parameters for the internal _initiateDeposit function. The user's input for the minimum amount of shares to receive is not guaranteed due to the price difference between the initiate and validate actions.

struct InitiateDepositParams {
    address user;
    address to;
    address validator;
    uint128 amount;
    uint256 sharesOutMin;
    uint64 securityDepositValue;
}

Properties

NameTypeDescription
useraddressThe address of the user initiating the deposit.
toaddressThe recipient of the USDN tokens.
validatoraddressThe address that is supposed to validate the deposit and receive the security deposit.
amountuint128The amount of assets to deposit.
sharesOutMinuint256The minimum amount of USDN shares to receive.
securityDepositValueuint64The value of the security deposit for the newly created deposit.

InitiateDepositData

Structure to hold the transient data during _initiateDeposit.

struct InitiateDepositData {
    uint128 lastPrice;
    bool isLiquidationPending;
    uint16 feeBps;
    uint256 totalExpo;
    uint256 balanceLong;
    uint256 balanceVault;
    uint256 usdnTotalShares;
    uint256 sdexToBurn;
}

Properties

NameTypeDescription
lastPriceuint128The last known price of the asset.
isLiquidationPendingboolWhether some liquidations still need to be performed.
feeBpsuint16The vault deposit fee (in basis points).
totalExpouint256The total exposure of the long side.
balanceLonguint256The balance of the long side.
balanceVaultuint256The balance of the vault including the funding.
usdnTotalSharesuint256Total minted shares of USDN.
sdexToBurnuint256The required amount of SDEX to burn for the deposit.

WithdrawalParams

Parameters for the internal _initiateWithdrawal function.

struct WithdrawalParams {
    address user;
    address to;
    address validator;
    uint152 usdnShares;
    uint256 amountOutMin;
    uint64 securityDepositValue;
}

Properties

NameTypeDescription
useraddressThe address of the user initiating the withdrawal.
toaddressThe recipient of the assets.
validatoraddressThe address that is supposed to validate the withdrawal and receive the security deposit.
usdnSharesuint152The amount of USDN shares to withdraw.
amountOutMinuint256The minimum amount of assets to receive.
securityDepositValueuint64The value of the security deposit for the newly created withdrawal.

WithdrawalData

Structure to hold the transient data during _initiateWithdrawal.

struct WithdrawalData {
    uint256 usdnTotalShares;
    uint256 totalExpo;
    uint256 balanceLong;
    uint256 balanceVault;
    uint256 withdrawalAmountAfterFees;
    uint128 lastPrice;
    uint16 feeBps;
    bool isLiquidationPending;
}

Properties

NameTypeDescription
usdnTotalSharesuint256The total supply of USDN shares.
totalExpouint256The current total exposure.
balanceLonguint256The balance of the long side.
balanceVaultuint256The balance of the vault including the funding.
withdrawalAmountAfterFeesuint256The predicted amount of assets that will be withdrawn after fees.
lastPriceuint128The last known price of the asset.
feeBpsuint16The vault deposit fee (in basis points).
isLiquidationPendingboolWhether some liquidations still need to be performed.

UsdnProtocolActions

Git Source

Inherits: IUsdnProtocolActions, InitializableReentrancyGuard, PausableUpgradeable, EIP712Upgradeable

Functions

initiateOpenPosition

Initiates an open position action.

Consult the current oracle middleware for price data format and possible oracle fee. Requires _securityDepositValue to be included in the transaction value. In case of pending liquidations, this function will not initiate the position (isInitiated_ would be false). The user's input for price and leverage is not guaranteed due to the price difference between the initiate and validate actions.

function initiateOpenPosition(
    uint128 amount,
    uint128 desiredLiqPrice,
    uint128 userMaxPrice,
    uint256 userMaxLeverage,
    address to,
    address payable validator,
    uint256 deadline,
    bytes calldata currentPriceData,
    PreviousActionsData calldata previousActionsData
) external payable whenNotPaused initializedAndNonReentrant returns (bool isInitiated_, PositionId memory posId_);

Parameters

NameTypeDescription
amountuint128The amount of assets to deposit.
desiredLiqPriceuint128The desired liquidation price, including the penalty.
userMaxPriceuint128The user's wanted maximum price at which the position can be opened.
userMaxLeverageuint256The user's wanted maximum leverage for the new position.
toaddressThe address that will owns of the position.
validatoraddress payableThe address that is supposed to validate the opening and receive the security deposit. If not an EOA, it must be a contract that implements a receive function.
deadlineuint256The deadline for initiating the open position.
currentPriceDatabytesThe price data used for temporary leverage and entry price computations.
previousActionsDataPreviousActionsDataThe data needed to validate actionable pending actions.

Returns

NameTypeDescription
isInitiated_boolWhether the position was successfully initiated. If false, the security deposit was refunded
posId_PositionIdThe unique position identifier. If the position was not initiated, the tick number will be NO_POSITION_TICK.

validateOpenPosition

Validates a pending open position action.

Consult the current oracle middleware for price data format and possible oracle fee. It is possible for this operation to change the tick, tick version and index of the position, in which case we emit the LiquidationPriceUpdated event. This function always sends the security deposit to the validator. So users wanting to earn the corresponding security deposit must use validateActionablePendingActions. In case liquidations are pending (outcome_ == LongActionOutcome.PendingLiquidations), the pending action will not be removed from the queue, and the user will have to try again. In case the position was liquidated by this call (outcome_ == LongActionOutcome.Liquidated), this function will refund the security deposit and remove the pending action from the queue.

function validateOpenPosition(
    address payable validator,
    bytes calldata openPriceData,
    PreviousActionsData calldata previousActionsData
)
    external
    payable
    whenNotPaused
    initializedAndNonReentrant
    returns (LongActionOutcome outcome_, PositionId memory posId_);

Parameters

NameTypeDescription
validatoraddress payableThe address associated with the pending open position. If not an EOA, it must be a contract that implements a receive function.
openPriceDatabytesThe price data for the pending open position.
previousActionsDataPreviousActionsDataThe data needed to validate actionable pending actions.

Returns

NameTypeDescription
outcome_LongActionOutcomeThe effect on the pending action (processed, liquidated, or pending liquidations).
posId_PositionIdThe position ID after validation (or NO_POSITION_TICK if liquidated).

initiateClosePosition

Initiates a close position action.

Consult the current oracle middleware for price data format and possible oracle fee. Requires _securityDepositValue to be included in the transaction value. If the current tick version is greater than the tick version of the position (when it was opened), then the position has been liquidated and the transaction will revert. In case liquidations are pending (outcome_ == LongActionOutcome.PendingLiquidations), the pending action will not be removed from the queue, and the user will have to try again. In case the position was liquidated by this call (outcome_ == LongActionOutcome.Liquidated), this function will refund the security deposit and remove the pending action from the queue. The user's input for the price is not guaranteed due to the price difference between the initiate and validate actions.

function initiateClosePosition(
    PositionId calldata posId,
    uint128 amountToClose,
    uint256 userMinPrice,
    address to,
    address payable validator,
    uint256 deadline,
    bytes calldata currentPriceData,
    PreviousActionsData calldata previousActionsData,
    bytes calldata delegationSignature
) external payable whenNotPaused initializedAndNonReentrant returns (LongActionOutcome outcome_);

Parameters

NameTypeDescription
posIdPositionIdThe unique identifier of the position to close.
amountToCloseuint128The amount of collateral to remove.
userMinPriceuint256The user's wanted minimum price for closing the position.
toaddressThe address that will receive the assets.
validatoraddress payableThe address that is supposed to validate the closing and receive the security deposit. If not an EOA, it must be a contract that implements a receive function.
deadlineuint256The deadline for initiating the close position.
currentPriceDatabytesThe price data for temporary calculations.
previousActionsDataPreviousActionsDataThe data needed to validate actionable pending actions.
delegationSignaturebytesOptional EIP712 signature for delegated action.

Returns

NameTypeDescription
outcome_LongActionOutcomeThe effect on the pending action (processed, liquidated, or pending liquidations).

validateClosePosition

Validates a pending close position action.

Consult the current oracle middleware for price data format and possible oracle fee. This function calculates the final exit price, determines the profit of the long position, and performs the payout. This function always sends the security deposit to the validator. So users wanting to earn the corresponding security deposit must use validateActionablePendingActions. In case liquidations are pending (outcome_ == LongActionOutcome.PendingLiquidations), the pending action will not be removed from the queue, and the user will have to try again. In case the position was liquidated by this call (outcome_ == LongActionOutcome.Liquidated), this function will refund the security deposit and remove the pending action from the queue.

function validateClosePosition(
    address payable validator,
    bytes calldata closePriceData,
    PreviousActionsData calldata previousActionsData
) external payable whenNotPaused initializedAndNonReentrant returns (LongActionOutcome outcome_);

Parameters

NameTypeDescription
validatoraddress payableThe address associated with the pending close position. If not an EOA, it must be a contract that implements a receive function.
closePriceDatabytesThe price data for the pending close position action.
previousActionsDataPreviousActionsDataThe data required to validate actionable pending actions.

Returns

NameTypeDescription
outcome_LongActionOutcomeThe outcome of the action (processed, liquidated, or pending liquidations).

initiateDeposit

Initiates a deposit of assets into the vault to mint USDN.

Consult the current oracle middleware for price data format and possible oracle fee. Requires _securityDepositValue to be included in the transaction value. In case liquidations are pending, this function might not initiate the deposit, and success_ would be false. The user's input for the shares is not guaranteed due to the price difference between the initiate and validate actions.

function initiateDeposit(
    uint128 amount,
    uint256 sharesOutMin,
    address to,
    address payable validator,
    uint256 deadline,
    bytes calldata currentPriceData,
    PreviousActionsData calldata previousActionsData
) external payable whenNotPaused initializedAndNonReentrant returns (bool success_);

Parameters

NameTypeDescription
amountuint128The amount of assets to deposit.
sharesOutMinuint256The minimum amount of USDN shares to receive.
toaddressThe address that will receive the USDN tokens.
validatoraddress payableThe address that is supposed to validate the deposit and receive the security deposit. If not an EOA, it must be a contract that implements a receive function.
deadlineuint256The deadline for initiating the deposit.
currentPriceDatabytesThe current price data.
previousActionsDataPreviousActionsDataThe data required to validate actionable pending actions.

Returns

NameTypeDescription
success_boolIndicates whether the deposit was successfully initiated.

validateDeposit

Validates a pending deposit action.

Consult the current oracle middleware for price data format and possible oracle fee. This function always sends the security deposit to the validator. So users wanting to earn the corresponding security deposit must use validateActionablePendingActions. If liquidations are pending, the validation may fail, and success_ would be false.

function validateDeposit(
    address payable validator,
    bytes calldata depositPriceData,
    PreviousActionsData calldata previousActionsData
) external payable whenNotPaused initializedAndNonReentrant returns (bool success_);

Parameters

NameTypeDescription
validatoraddress payableThe address associated with the pending deposit action. If not an EOA, it must be a contract that implements a receive function.
depositPriceDatabytesThe price data for the pending deposit action.
previousActionsDataPreviousActionsDataThe data required to validate actionable pending actions.

Returns

NameTypeDescription
success_boolIndicates whether the deposit was successfully validated.

initiateWithdrawal

Initiates a withdrawal of assets from the vault using USDN tokens.

Consult the current oracle middleware for price data format and possible oracle fee. Requires _securityDepositValue to be included in the transaction value. Note that in case liquidations are pending, this function might not initiate the withdrawal, and success_ would be false. The user's input for the minimum amount is not guaranteed due to the price difference between the initiate and validate actions.

function initiateWithdrawal(
    uint152 usdnShares,
    uint256 amountOutMin,
    address to,
    address payable validator,
    uint256 deadline,
    bytes calldata currentPriceData,
    PreviousActionsData calldata previousActionsData
) external payable whenNotPaused initializedAndNonReentrant returns (bool success_);

Parameters

NameTypeDescription
usdnSharesuint152The amount of USDN shares to burn.
amountOutMinuint256The minimum amount of assets to receive.
toaddressThe address that will receive the assets.
validatoraddress payableThe address that is supposed to validate the withdrawal and receive the security deposit. If not an EOA, it must be a contract that implements a receive function.
deadlineuint256The deadline for initiating the withdrawal.
currentPriceDatabytesThe current price data.
previousActionsDataPreviousActionsDataThe data required to validate actionable pending actions.

Returns

NameTypeDescription
success_boolIndicates whether the withdrawal was successfully initiated.

validateWithdrawal

Validates a pending withdrawal action.

Consult the current oracle middleware for price data format and possible oracle fee. This function always sends the security deposit to the validator. So users wanting to earn the corresponding security deposit must use validateActionablePendingActions. In case liquidations are pending, this function might not validate the withdrawal, and success_ would be false.

function validateWithdrawal(
    address payable validator,
    bytes calldata withdrawalPriceData,
    PreviousActionsData calldata previousActionsData
) external payable whenNotPaused initializedAndNonReentrant returns (bool success_);

Parameters

NameTypeDescription
validatoraddress payableThe address associated with the pending withdrawal action. If not an EOA, it must be a contract that implements a receive function.
withdrawalPriceDatabytesThe price data for the pending withdrawal action.
previousActionsDataPreviousActionsDataThe data required to validate actionable pending actions.

Returns

NameTypeDescription
success_boolIndicates whether the withdrawal was successfully validated.

liquidate

Liquidates positions based on the provided asset price.

Consult the current oracle middleware for price data format and possible oracle fee. Each tick is liquidated in constant time. The tick version is incremented for each liquidated tick.

function liquidate(bytes calldata currentPriceData)
    external
    payable
    whenNotPaused
    initializedAndNonReentrant
    returns (LiqTickInfo[] memory liquidatedTicks_);

Parameters

NameTypeDescription
currentPriceDatabytesThe price data.

Returns

NameTypeDescription
liquidatedTicks_LiqTickInfo[]Information about the liquidated ticks.

validateActionablePendingActions

Manually validates actionable pending actions.

Consult the current oracle middleware for price data format and possible oracle fee. The timestamp for each pending action is calculated by adding the OracleMiddleware.validationDelay to its initiation timestamp.

function validateActionablePendingActions(PreviousActionsData calldata previousActionsData, uint256 maxValidations)
    external
    payable
    whenNotPaused
    initializedAndNonReentrant
    returns (uint256 validatedActions_);

Parameters

NameTypeDescription
previousActionsDataPreviousActionsDataThe data required to validate actionable pending actions.
maxValidationsuint256The maximum number of actionable pending actions to validate. At least one validation will be performed.

Returns

NameTypeDescription
validatedActions_uint256The number of successfully validated actions.

transferPositionOwnership

Transfers the ownership of a position to another address.

This function reverts if the caller is not the position owner, if the position does not exist, or if the new owner's address is the zero address. If the new owner is a contract that implements the IOwnershipCallback interface, its ownershipCallback function will be invoked after the transfer.

function transferPositionOwnership(PositionId calldata posId, address newOwner, bytes calldata delegationSignature)
    external
    whenNotPaused
    initializedAndNonReentrant;

Parameters

NameTypeDescription
posIdPositionIdThe unique identifier of the position.
newOwneraddressThe address of the new position owner.
delegationSignaturebytesAn optional EIP712 signature to authorize the transfer on the owner's behalf.

domainSeparatorV4

Retrieves the domain separator used in EIP-712 signatures.

function domainSeparatorV4() external view returns (bytes32);

Returns

NameTypeDescription
<none>bytes32domainSeparatorV4_ The domain separator compliant with EIP-712.

UsdnProtocolCore

Git Source

Inherits: IUsdnProtocolCore, InitializableReentrancyGuard, AccessControlDefaultAdminRulesUpgradeable

Functions

initialize

Initializes the protocol by making an initial deposit and creating the first long position.

This function can only be called once. No other user actions can be performed until the protocol is initialized.

function initialize(uint128 depositAmount, uint128 longAmount, uint128 desiredLiqPrice, bytes calldata currentPriceData)
    external
    payable
    protocolInitializer
    onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
depositAmountuint128The amount of assets to deposit.
longAmountuint128The amount of assets for the long position.
desiredLiqPriceuint128The desired liquidation price for the long position, excluding the liquidation penalty.
currentPriceDatabytesThe encoded current price data.

funding

Computes the predicted funding value since the last state update for the specified timestamp.

The funding value, when multiplied by the long trading exposure, represents the asset balance to be transferred to the vault side, or to the long side if the value is negative. Reverts with UsdnProtocolTimestampTooOld if the given timestamp is older than the last state update.

function funding(uint128 timestamp)
    external
    view
    returns (int256 funding_, int256 fundingPerDay_, int256 oldLongExpo_);

Parameters

NameTypeDescription
timestampuint128The timestamp to use for the computation.

Returns

NameTypeDescription
funding_int256The funding magnitude (with FUNDING_RATE_DECIMALS decimals) since the last update timestamp.
fundingPerDay_int256The funding rate per day (with FUNDING_RATE_DECIMALS decimals).
oldLongExpo_int256The long trading exposure recorded at the last state update.

UsdnProtocolFallback

Git Source

Inherits: IUsdnProtocolFallback, IUsdnProtocolErrors, IUsdnProtocolEvents, InitializableReentrancyGuard, PausableUpgradeable, AccessControlDefaultAdminRulesUpgradeable

State Variables

MAX_SDEX_BURN_RATIO

The highest value allowed for the ratio of SDEX to burn per minted USDN on deposit.

uint256 internal immutable MAX_SDEX_BURN_RATIO;

MAX_MIN_LONG_POSITION

The highest value allowed for the minimum long position setting.

uint256 internal immutable MAX_MIN_LONG_POSITION;

Functions

constructor

constructor(uint256 maxSdexBurnRatio, uint256 maxMinLongPosition);

Parameters

NameTypeDescription
maxSdexBurnRatiouint256The value of MAX_SDEX_BURN_RATIO.
maxMinLongPositionuint256The value of MAX_MIN_LONG_POSITION.

getActionablePendingActions

Retrieves the list of pending actions that must be validated by the next user action in the protocol.

If this function returns a non-empty list of pending actions, then the next user action MUST include the corresponding list of price update data and raw indices as the last parameter. The user that processes those pending actions will receive the corresponding security deposit.

function getActionablePendingActions(address currentUser, uint256 lookAhead, uint256 maxIter)
    external
    view
    returns (PendingAction[] memory actions_, uint128[] memory rawIndices_);

Parameters

NameTypeDescription
currentUseraddressThe address of the user that will submit the price signatures for third-party actions validations. This is used to filter out their actions from the returned list.
lookAheaduint256Additionally to pending actions which are actionable at this moment block.timestamp, the function will also return pending actions which will be actionable lookAhead seconds later. It is recommended to use a non-zero value in order to account for the interval where the validation transaction will be pending. A value of 30 seconds should already account for most situations and avoid reverts in case an action becomes actionable after a user submits their transaction.
maxIteruint256The maximum number of iterations when looking through the queue to find actionable pending actions. This value will be clamped to [MIN_ACTIONABLE_PENDING_ACTIONS_ITER,_pendingActionsQueue.length()].

Returns

NameTypeDescription
actions_PendingAction[]The pending actions if any, otherwise an empty array.
rawIndices_uint128[]The raw indices of the actionable pending actions in the queue if any, otherwise an empty array. Each entry corresponds to the action in the actions_ array, at the same index.

getUserPendingAction

Retrieves the pending action with user as the given validator.

function getUserPendingAction(address user) external view returns (PendingAction memory action_);

Parameters

NameTypeDescription
useraddressThe user's address.

Returns

NameTypeDescription
action_PendingActionThe pending action if any, otherwise a struct with all fields set to zero and ProtocolAction.None.

tickHash

Computes the hash generated from the given tick number and version.

function tickHash(int24 tick, uint256 version) external pure returns (bytes32 hash_);

Parameters

NameTypeDescription
tickint24The tick number.
versionuint256The tick version.

Returns

NameTypeDescription
hash_bytes32The hash of the given tick number and version.

getEffectivePriceForTick

Computes the liquidation price of the given tick number, taking into account the effects of funding.

Uses the values from storage for the various variables. Note that ticks that are not a multiple of the tick spacing cannot contain a long position.

function getEffectivePriceForTick(int24 tick) external view returns (uint128 price_);

Parameters

NameTypeDescription
tickint24The tick number.

Returns

NameTypeDescription
price_uint128The liquidation price.

getEffectivePriceForTick

Computes the liquidation price of the given tick number, taking into account the effects of funding.

Uses the values from storage for the various variables. Note that ticks that are not a multiple of the tick spacing cannot contain a long position.

function getEffectivePriceForTick(
    int24 tick,
    uint256 assetPrice,
    uint256 longTradingExpo,
    HugeUint.Uint512 memory accumulator
) external pure returns (uint128 price_);

Parameters

NameTypeDescription
tickint24The tick number.
assetPriceuint256
longTradingExpouint256
accumulatorHugeUint.Uint512

Returns

NameTypeDescription
price_uint128The liquidation price.

previewDeposit

Computes an estimate of USDN tokens to be minted and SDEX tokens to be burned when depositing.

The result is a rough estimate and does not take into account rebases and liquidations.

function previewDeposit(uint256 amount, uint128 price, uint128 timestamp)
    external
    view
    returns (uint256 usdnSharesExpected_, uint256 sdexToBurn_);

Parameters

NameTypeDescription
amountuint256The amount of assets to deposit.
priceuint128The current/projected price of the asset.
timestampuint128The timestamp corresponding to price.

Returns

NameTypeDescription
usdnSharesExpected_uint256The amount of USDN shares to be minted.
sdexToBurn_uint256The amount of SDEX tokens to be burned.

previewWithdraw

Computes an estimate of the amount of assets received when withdrawing.

The result is a rough estimate and does not take into account rebases and liquidations.

function previewWithdraw(uint256 usdnShares, uint128 price, uint128 timestamp)
    external
    view
    returns (uint256 assetExpected_);

Parameters

NameTypeDescription
usdnSharesuint256The amount of USDN shares to use in the withdrawal.
priceuint128The current/projected price of the asset.
timestampuint128The The timestamp corresponding to price.

Returns

NameTypeDescription
assetExpected_uint256The expected amount of assets to be received.

burnSdex

Sends the accumulated SDEX token fees to the dead address. This function can be called by anyone.

function burnSdex() external whenNotPaused initializedAndNonReentrant;

refundSecurityDeposit

Refunds the security deposit to the given validator if it has a liquidated initiated long position.

The security deposit is always sent to the validator even if the pending action is actionable.

function refundSecurityDeposit(address payable validator) external whenNotPaused initializedAndNonReentrant;

Parameters

NameTypeDescription
validatoraddress payableThe address of the validator (must be payable as it will receive some native currency).

removeBlockedPendingAction

Removes a stuck pending action and performs the minimal amount of cleanup necessary.

This function can only be called by the owner of the protocol, it serves as an escape hatch if a pending action ever gets stuck due to something internal reverting unexpectedly. It will not refund any fees or burned SDEX.

function removeBlockedPendingAction(address validator, address payable to)
    external
    onlyRole(Constants.CRITICAL_FUNCTIONS_ROLE)
    initializedAndNonReentrant;

Parameters

NameTypeDescription
validatoraddressThe address of the validator of the stuck pending action.
toaddress payableWhere the retrieved funds should be sent (security deposit, assets, usdn). Must be payable.

removeBlockedPendingActionNoCleanup

Removes a stuck pending action with no cleanup.

This function can only be called by the owner of the protocol, it serves as an escape hatch if a pending action ever gets stuck due to something internal reverting unexpectedly. Always try to use removeBlockedPendingAction first, and only call this function if the other one fails. It will not refund any fees or burned SDEX.

function removeBlockedPendingActionNoCleanup(address validator, address payable to)
    external
    onlyRole(Constants.CRITICAL_FUNCTIONS_ROLE);

Parameters

NameTypeDescription
validatoraddressThe address of the validator of the stuck pending action.
toaddress payableWhere the retrieved funds should be sent (security deposit, assets, usdn). Must be payable.

removeBlockedPendingAction

Removes a stuck pending action and performs the minimal amount of cleanup necessary.

This function can only be called by the owner of the protocol, it serves as an escape hatch if a pending action ever gets stuck due to something internal reverting unexpectedly. It will not refund any fees or burned SDEX.

function removeBlockedPendingAction(uint128 rawIndex, address payable to)
    external
    onlyRole(Constants.CRITICAL_FUNCTIONS_ROLE)
    initializedAndNonReentrant;

Parameters

NameTypeDescription
rawIndexuint128
toaddress payableWhere the retrieved funds should be sent (security deposit, assets, usdn). Must be payable.

removeBlockedPendingActionNoCleanup

Removes a stuck pending action with no cleanup.

This function can only be called by the owner of the protocol, it serves as an escape hatch if a pending action ever gets stuck due to something internal reverting unexpectedly. Always try to use removeBlockedPendingAction first, and only call this function if the other one fails. It will not refund any fees or burned SDEX.

function removeBlockedPendingActionNoCleanup(uint128 rawIndex, address payable to)
    external
    onlyRole(Constants.CRITICAL_FUNCTIONS_ROLE);

Parameters

NameTypeDescription
rawIndexuint128
toaddress payableWhere the retrieved funds should be sent (security deposit, assets, usdn). Must be payable.

getTickSpacing

The number of ticks between usable ticks. Only tick numbers that are a multiple of the tick spacing can be used for storing long positions.

A tick spacing of 1 is equivalent to a 0.01% increase in price between ticks. A tick spacing of 100 is. equivalent to a ~1.005% increase in price between ticks.

function getTickSpacing() external view returns (int24 tickSpacing_);

Returns

NameTypeDescription
tickSpacing_int24The tick spacing.

getAsset

Gets the address of the protocol's underlying asset (ERC20 token).

function getAsset() external view returns (IERC20Metadata asset_);

Returns

NameTypeDescription
asset_IERC20MetadataThe address of the asset token.

getSdex

Gets the address of the SDEX ERC20 token.

function getSdex() external view returns (IERC20Metadata sdex_);

Returns

NameTypeDescription
sdex_IERC20MetadataThe address of the SDEX token.

getPriceFeedDecimals

Gets the number of decimals of the asset's price feed.

function getPriceFeedDecimals() external view returns (uint8 decimals_);

Returns

NameTypeDescription
decimals_uint8The number of decimals of the asset's price feed.

getAssetDecimals

Gets the number of decimals of the underlying asset token.

function getAssetDecimals() external view returns (uint8 decimals_);

Returns

NameTypeDescription
decimals_uint8The number of decimals of the asset token.

getUsdn

Gets the address of the USDN ERC20 token.

function getUsdn() external view returns (IUsdn usdn_);

Returns

NameTypeDescription
usdn_IUsdnThe address of USDN ERC20 token.

getUsdnMinDivisor

Gets the MIN_DIVISOR constant of the USDN token.

Check the USDN contract for more information.

function getUsdnMinDivisor() external view returns (uint256 minDivisor_);

Returns

NameTypeDescription
minDivisor_uint256The MIN_DIVISOR constant of the USDN token.

getOracleMiddleware

Gets the oracle middleware contract.

function getOracleMiddleware() external view returns (IBaseOracleMiddleware oracleMiddleware_);

Returns

NameTypeDescription
oracleMiddleware_IBaseOracleMiddlewareThe address of the oracle middleware contract.

getLiquidationRewardsManager

Gets the liquidation rewards manager contract.

function getLiquidationRewardsManager()
    external
    view
    returns (IBaseLiquidationRewardsManager liquidationRewardsManager_);

Returns

NameTypeDescription
liquidationRewardsManager_IBaseLiquidationRewardsManagerThe address of the liquidation rewards manager contract.

getRebalancer

Gets the rebalancer contract.

function getRebalancer() external view returns (IBaseRebalancer rebalancer_);

Returns

NameTypeDescription
rebalancer_IBaseRebalancerThe address of the rebalancer contract.

getMinLeverage

Gets the lowest leverage that can be used to open a long position.

function getMinLeverage() external view returns (uint256 minLeverage_);

Returns

NameTypeDescription
minLeverage_uint256The minimum leverage (with LEVERAGE_DECIMALS decimals).

getMaxLeverage

Gets the highest leverage that can be used to open a long position.

A position can have a leverage a bit higher than this value under specific conditions involving a change to the liquidation penalty setting.

function getMaxLeverage() external view returns (uint256 maxLeverage_);

Returns

NameTypeDescription
maxLeverage_uint256The maximum leverage value (with LEVERAGE_DECIMALS decimals).

getLowLatencyValidatorDeadline

Gets the deadline of the exclusivity period for the validator of a pending action with a low-latency oracle.

After this deadline, any user can validate the action with the low-latency oracle until the OracleMiddleware's _lowLatencyDelay, and retrieve the security deposit for the pending action.

function getLowLatencyValidatorDeadline() external view returns (uint128 deadline_);

Returns

NameTypeDescription
deadline_uint128The low-latency validation deadline of a validator (in seconds).

getOnChainValidatorDeadline

Gets the deadline of the exclusivity period for the validator to confirm their action with the on-chain oracle.

After this deadline, any user can validate the pending action with the on-chain oracle and retrieve its security deposit.

function getOnChainValidatorDeadline() external view returns (uint128 deadline_);

Returns

NameTypeDescription
deadline_uint128The on-chain validation deadline of a validator (in seconds)

getLiquidationPenalty

Gets the liquidation penalty applied to the liquidation price when opening a position.

function getLiquidationPenalty() external view returns (uint24 liquidationPenalty_);

Returns

NameTypeDescription
liquidationPenalty_uint24The liquidation penalty (in ticks).

getSafetyMarginBps

Gets the safety margin for the liquidation price of newly open positions.

function getSafetyMarginBps() external view returns (uint256 safetyMarginBps_);

Returns

NameTypeDescription
safetyMarginBps_uint256The safety margin (in basis points).

getLiquidationIteration

Gets the number of tick liquidations to perform when attempting to liquidate positions during user actions.

function getLiquidationIteration() external view returns (uint16 iterations_);

Returns

NameTypeDescription
iterations_uint16The number of iterations for liquidations during user actions.

getEMAPeriod

Gets the time frame for the EMA calculations.

The EMA is set to the last funding rate when the time elapsed between 2 actions is greater than this value.

function getEMAPeriod() external view returns (uint128 period_);

Returns

NameTypeDescription
period_uint128The time frame of the EMA (in seconds).

getFundingSF

Gets the scaling factor (SF) of the funding rate.

function getFundingSF() external view returns (uint256 scalingFactor_);

Returns

NameTypeDescription
scalingFactor_uint256The scaling factor (with FUNDING_SF_DECIMALS decimals).

getProtocolFeeBps

Gets the fee taken by the protocol during the application of funding.

function getProtocolFeeBps() external view returns (uint16 feeBps_);

Returns

NameTypeDescription
feeBps_uint16The fee applied to the funding (in basis points).

getPositionFeeBps

Gets the fee applied when a long position is opened or closed.

function getPositionFeeBps() external view returns (uint16 feeBps_);

Returns

NameTypeDescription
feeBps_uint16The fee applied to a long position (in basis points).

getVaultFeeBps

Gets the fee applied during a vault deposit or withdrawal.

function getVaultFeeBps() external view returns (uint16 feeBps_);

Returns

NameTypeDescription
feeBps_uint16The fee applied to a vault action (in basis points).

getSdexRewardsRatioBps

Gets the rewards ratio given to the caller when burning SDEX tokens.

function getSdexRewardsRatioBps() external view returns (uint16 rewardsBps_);

Returns

NameTypeDescription
rewardsBps_uint16The rewards ratio (in basis points).

getRebalancerBonusBps

Gets the part of the remaining collateral given as a bonus to the Rebalancer upon liquidation of a tick.

function getRebalancerBonusBps() external view returns (uint16 bonusBps_);

Returns

NameTypeDescription
bonusBps_uint16The fraction of the remaining collateral for the Rebalancer bonus (in basis points).

getSdexBurnOnDepositRatio

Gets the ratio of SDEX tokens to burn per minted USDN.

function getSdexBurnOnDepositRatio() external view returns (uint64 ratio_);

Returns

NameTypeDescription
ratio_uint64The ratio (to be divided by SDEX_BURN_ON_DEPOSIT_DIVISOR).

getSecurityDepositValue

Gets the amount of native tokens used as security deposit when opening a new position.

function getSecurityDepositValue() external view returns (uint64 securityDeposit_);

Returns

NameTypeDescription
securityDeposit_uint64The amount of assets to use as a security deposit (in ether).

getFeeThreshold

Gets the threshold to reach to send accumulated fees to the fee collector.

function getFeeThreshold() external view returns (uint256 threshold_);

Returns

NameTypeDescription
threshold_uint256The amount of accumulated fees to reach (in _assetDecimals).

getFeeCollector

Gets the address of the fee collector.

function getFeeCollector() external view returns (address feeCollector_);

Returns

NameTypeDescription
feeCollector_addressThe address of the fee collector.

getMiddlewareValidationDelay

Returns the amount of time to wait before an action can be validated.

This is also the amount of time to add to the initiate action timestamp to fetch the correct price data to validate said action with a low-latency oracle.

function getMiddlewareValidationDelay() external view returns (uint256 delay_);

Returns

NameTypeDescription
delay_uint256The validation delay (in seconds).

getTargetUsdnPrice

Gets the nominal (target) price of USDN.

function getTargetUsdnPrice() external view returns (uint128 price_);

Returns

NameTypeDescription
price_uint128The price of the USDN token after a rebase (in _priceFeedDecimals).

getUsdnRebaseThreshold

Gets the USDN token price above which a rebase should occur.

function getUsdnRebaseThreshold() external view returns (uint128 threshold_);

Returns

NameTypeDescription
threshold_uint128The rebase threshold (in _priceFeedDecimals).

getMinLongPosition

Gets the minimum collateral amount when opening a long position.

function getMinLongPosition() external view returns (uint256 minLongPosition_);

Returns

NameTypeDescription
minLongPosition_uint256The minimum amount (with _assetDecimals).

getLastFundingPerDay

Gets the value of the funding rate at the last timestamp (getLastUpdateTimestamp).

function getLastFundingPerDay() external view returns (int256 lastFunding_);

Returns

NameTypeDescription
lastFunding_int256The last value of the funding rate (per day) with FUNDING_RATE_DECIMALS decimals.

getLastPrice

Gets the neutral price of the asset used during the last update of the vault and long balances.

function getLastPrice() external view returns (uint128 lastPrice_);

Returns

NameTypeDescription
lastPrice_uint128The most recent known price of the asset (in _priceFeedDecimals).

getLastUpdateTimestamp

Gets the timestamp of the last time a fresh price was provided.

function getLastUpdateTimestamp() external view returns (uint128 lastTimestamp_);

Returns

NameTypeDescription
lastTimestamp_uint128The timestamp of the last update.

getPendingProtocolFee

Gets the fees that were accumulated by the contract and are yet to be sent to the fee collector (in _assetDecimals).

function getPendingProtocolFee() external view returns (uint256 protocolFees_);

Returns

NameTypeDescription
protocolFees_uint256The amount of accumulated fees still in the contract.

getBalanceVault

Gets the amount of assets backing the USDN token.

function getBalanceVault() external view returns (uint256 balanceVault_);

Returns

NameTypeDescription
balanceVault_uint256The amount of assets on the vault side (in _assetDecimals).

getPendingBalanceVault

Gets the pending balance updates due to pending vault actions.

function getPendingBalanceVault() external view returns (int256 pendingBalanceVault_);

Returns

NameTypeDescription
pendingBalanceVault_int256The unreflected balance change due to pending vault actions (in _assetDecimals).

getEMA

Gets the exponential moving average of the funding rate per day.

function getEMA() external view returns (int256 ema_);

Returns

NameTypeDescription
ema_int256The exponential moving average of the funding rate per day.

getBalanceLong

Gets the summed value of all the currently open long positions at _lastUpdateTimestamp.

function getBalanceLong() external view returns (uint256 balanceLong_);

Returns

NameTypeDescription
balanceLong_uint256The balance of the long side (in _assetDecimals).

getTotalExpo

Gets the total exposure of all currently open long positions.

function getTotalExpo() external view returns (uint256 totalExpo_);

Returns

NameTypeDescription
totalExpo_uint256The total exposure of the longs (in _assetDecimals).

getLiqMultiplierAccumulator

Gets the accumulator used to calculate the liquidation multiplier.

function getLiqMultiplierAccumulator() external view returns (HugeUint.Uint512 memory accumulator_);

Returns

NameTypeDescription
accumulator_HugeUint.Uint512The liquidation multiplier accumulator.

getTickVersion

Gets the current version of the given tick.

function getTickVersion(int24 tick) external view returns (uint256 tickVersion_);

Parameters

NameTypeDescription
tickint24The tick number.

Returns

NameTypeDescription
tickVersion_uint256The version of the tick.

getTickData

Gets the tick data for the current tick version.

function getTickData(int24 tick) external view returns (TickData memory tickData_);

Parameters

NameTypeDescription
tickint24The tick number.

Returns

NameTypeDescription
tickData_TickDataThe tick data.

getCurrentLongPosition

Gets the long position at the provided tick and index.

function getCurrentLongPosition(int24 tick, uint256 index) external view returns (Position memory position_);

Parameters

NameTypeDescription
tickint24The tick number.
indexuint256The position index.

Returns

NameTypeDescription
position_PositionThe long position.

getHighestPopulatedTick

Gets the highest tick that has an open position.

function getHighestPopulatedTick() external view returns (int24 tick_);

Returns

NameTypeDescription
tick_int24The highest populated tick.

getTotalLongPositions

Gets the total number of long positions currently open.

function getTotalLongPositions() external view returns (uint256 totalLongPositions_);

Returns

NameTypeDescription
totalLongPositions_uint256The number of long positions.

getDepositExpoImbalanceLimitBps

Gets the expo imbalance limit when depositing assets (in basis points).

function getDepositExpoImbalanceLimitBps() external view returns (int256 depositExpoImbalanceLimitBps_);

Returns

NameTypeDescription
depositExpoImbalanceLimitBps_int256The deposit expo imbalance limit.

getWithdrawalExpoImbalanceLimitBps

Gets the expo imbalance limit when withdrawing assets (in basis points).

function getWithdrawalExpoImbalanceLimitBps() external view returns (int256 withdrawalExpoImbalanceLimitBps_);

Returns

NameTypeDescription
withdrawalExpoImbalanceLimitBps_int256The withdrawal expo imbalance limit.

getOpenExpoImbalanceLimitBps

Gets the expo imbalance limit when opening a position (in basis points).

function getOpenExpoImbalanceLimitBps() external view returns (int256 openExpoImbalanceLimitBps_);

Returns

NameTypeDescription
openExpoImbalanceLimitBps_int256The open expo imbalance limit.

getCloseExpoImbalanceLimitBps

Gets the expo imbalance limit when closing a position (in basis points).

function getCloseExpoImbalanceLimitBps() external view returns (int256 closeExpoImbalanceLimitBps_);

Returns

NameTypeDescription
closeExpoImbalanceLimitBps_int256The close expo imbalance limit.

getRebalancerCloseExpoImbalanceLimitBps

Returns the limit of the imbalance in bps to close the rebalancer position.

function getRebalancerCloseExpoImbalanceLimitBps()
    external
    view
    returns (int256 rebalancerCloseExpoImbalanceLimitBps_);

Returns

NameTypeDescription
rebalancerCloseExpoImbalanceLimitBps_int256The limit of the imbalance in bps to close the rebalancer position.

getLongImbalanceTargetBps

Returns the imbalance desired on the long side after the creation of a rebalancer position.

The creation of the rebalancer position aims for this target but does not guarantee reaching it.

function getLongImbalanceTargetBps() external view returns (int256 longImbalanceTargetBps_);

Returns

NameTypeDescription
longImbalanceTargetBps_int256targetLongImbalance_ The target long imbalance.

getFallbackAddress

Gets the address of the fallback contract.

function getFallbackAddress() external view returns (address fallback_);

Returns

NameTypeDescription
fallback_addressThe address of the fallback contract.

isPaused

Gets the pause status of the USDN protocol.

function isPaused() external view returns (bool isPaused_);

Returns

NameTypeDescription
isPaused_boolTrue if it's paused, false otherwise.

getNonce

Gets the nonce a user can use to generate a delegation signature.

This is to prevent replay attacks when using an eip712 delegation signature.

function getNonce(address user) external view returns (uint256 nonce_);

Parameters

NameTypeDescription
useraddressThe address of the user.

Returns

NameTypeDescription
nonce_uint256The user's nonce.

setOracleMiddleware

Replaces the OracleMiddleware contract with a new implementation.

Cannot be the 0 address.

function setOracleMiddleware(IBaseOracleMiddleware newOracleMiddleware)
    external
    onlyRole(Constants.SET_EXTERNAL_ROLE);

Parameters

NameTypeDescription
newOracleMiddlewareIBaseOracleMiddlewareThe address of the new contract.

setLiquidationRewardsManager

Replaces the LiquidationRewardsManager contract with a new implementation.

Cannot be the 0 address.

function setLiquidationRewardsManager(IBaseLiquidationRewardsManager newLiquidationRewardsManager)
    external
    onlyRole(Constants.SET_EXTERNAL_ROLE);

Parameters

NameTypeDescription
newLiquidationRewardsManagerIBaseLiquidationRewardsManagerThe address of the new contract.

setRebalancer

Replaces the Rebalancer contract with a new implementation.

function setRebalancer(IBaseRebalancer newRebalancer) external onlyRole(Constants.SET_EXTERNAL_ROLE);

Parameters

NameTypeDescription
newRebalancerIBaseRebalancerThe address of the new contract.

setFeeCollector

Sets the fee collector address.

Cannot be the zero address.

function setFeeCollector(address newFeeCollector) external onlyRole(Constants.SET_EXTERNAL_ROLE);

Parameters

NameTypeDescription
newFeeCollectoraddressThe address of the fee collector.

setValidatorDeadlines

Sets the new deadlines of the exclusivity period for the validator to confirm its action and get its security deposit back.

function setValidatorDeadlines(uint128 newLowLatencyValidatorDeadline, uint128 newOnChainValidatorDeadline)
    external
    onlyRole(Constants.CRITICAL_FUNCTIONS_ROLE);

Parameters

NameTypeDescription
newLowLatencyValidatorDeadlineuint128The new exclusivity deadline for low-latency validation (offset from initiate timestamp).
newOnChainValidatorDeadlineuint128The new exclusivity deadline for on-chain validation (offset from initiate timestamp + oracle middleware's low latency delay).

setMinLeverage

Sets the new minimum leverage for a position.

function setMinLeverage(uint256 newMinLeverage) external onlyRole(Constants.SET_PROTOCOL_PARAMS_ROLE);

Parameters

NameTypeDescription
newMinLeverageuint256The new minimum leverage.

setMaxLeverage

Sets the new maximum leverage for a position.

function setMaxLeverage(uint256 newMaxLeverage) external onlyRole(Constants.SET_PROTOCOL_PARAMS_ROLE);

Parameters

NameTypeDescription
newMaxLeverageuint256The new maximum leverage.

setLiquidationPenalty

Sets the new liquidation penalty (in ticks).

function setLiquidationPenalty(uint24 newLiquidationPenalty) external onlyRole(Constants.SET_PROTOCOL_PARAMS_ROLE);

Parameters

NameTypeDescription
newLiquidationPenaltyuint24The new liquidation penalty.

setEMAPeriod

Sets the new exponential moving average period of the funding rate.

function setEMAPeriod(uint128 newEMAPeriod) external onlyRole(Constants.SET_PROTOCOL_PARAMS_ROLE);

Parameters

NameTypeDescription
newEMAPerioduint128The new EMA period.

setFundingSF

Sets the new scaling factor (SF) of the funding rate.

function setFundingSF(uint256 newFundingSF) external onlyRole(Constants.SET_PROTOCOL_PARAMS_ROLE);

Parameters

NameTypeDescription
newFundingSFuint256The new scaling factor (SF) of the funding rate.

setProtocolFeeBps

Sets the protocol fee.

Fees are charged when the funding is applied (Example: 50 bps -> 0.5%).

function setProtocolFeeBps(uint16 newProtocolFeeBps) external onlyRole(Constants.SET_PROTOCOL_PARAMS_ROLE);

Parameters

NameTypeDescription
newProtocolFeeBpsuint16

setPositionFeeBps

Sets the position fee.

function setPositionFeeBps(uint16 newPositionFee) external onlyRole(Constants.SET_PROTOCOL_PARAMS_ROLE);

Parameters

NameTypeDescription
newPositionFeeuint16The new position fee (in basis points).

setVaultFeeBps

Sets the vault fee.

function setVaultFeeBps(uint16 newVaultFee) external onlyRole(Constants.SET_PROTOCOL_PARAMS_ROLE);

Parameters

NameTypeDescription
newVaultFeeuint16The new vault fee (in basis points).

setSdexRewardsRatioBps

Sets the rewards ratio given to the caller when burning SDEX tokens.

function setSdexRewardsRatioBps(uint16 newRewardsBps) external onlyRole(Constants.SET_PROTOCOL_PARAMS_ROLE);

Parameters

NameTypeDescription
newRewardsBpsuint16The new rewards ratio (in basis points).

setRebalancerBonusBps

Sets the rebalancer bonus.

function setRebalancerBonusBps(uint16 newBonus) external onlyRole(Constants.SET_PROTOCOL_PARAMS_ROLE);

Parameters

NameTypeDescription
newBonusuint16The bonus (in basis points).

setSdexBurnOnDepositRatio

Sets the ratio of SDEX tokens to burn per minted USDN.

As this parameter highly depends on the value of the USDN token, the max value for newRatio is given as a constructor argument when the UsdnProtocolFallback contract is deployed and is stored in an immutable variable.

function setSdexBurnOnDepositRatio(uint64 newRatio) external onlyRole(Constants.SET_PROTOCOL_PARAMS_ROLE);

Parameters

NameTypeDescription
newRatiouint64The new ratio.

setSecurityDepositValue

Sets the security deposit value.

The maximum value of the security deposit is 2^64 - 1 = 18446744073709551615 = 18.4 ethers.

function setSecurityDepositValue(uint64 securityDepositValue) external onlyRole(Constants.SET_PROTOCOL_PARAMS_ROLE);

Parameters

NameTypeDescription
securityDepositValueuint64The security deposit value. This value cannot be greater than MAX_SECURITY_DEPOSIT.

setExpoImbalanceLimits

Sets the imbalance limits (in basis point).

newLongImbalanceTargetBps needs to be lower than newCloseLimitBps and higher than the additive inverse of newWithdrawalLimitBps.

function setExpoImbalanceLimits(
    uint256 newOpenLimitBps,
    uint256 newDepositLimitBps,
    uint256 newWithdrawalLimitBps,
    uint256 newCloseLimitBps,
    uint256 newRebalancerCloseLimitBps,
    int256 newLongImbalanceTargetBps
) external onlyRole(Constants.SET_PROTOCOL_PARAMS_ROLE);

Parameters

NameTypeDescription
newOpenLimitBpsuint256The new open limit.
newDepositLimitBpsuint256The new deposit limit.
newWithdrawalLimitBpsuint256The new withdrawal limit.
newCloseLimitBpsuint256The new close limit.
newRebalancerCloseLimitBpsuint256The new rebalancer close limit.
newLongImbalanceTargetBpsint256The new target imbalance limit for the long side. A positive value will target below equilibrium, a negative one will target above equilibrium. If negative, the rebalancerCloseLimit will be useless since the minimum value is 1.

setMinLongPosition

Sets the minimum long position size.

This value is used to prevent users from opening positions that are too small and not worth liquidating. As this parameter highly depends on the value of the underlying asset, the max value for newMinLongPosition is given as a constructor argument when the UsdnProtocolFallback contract is deployed, and is stored in an immutable variable.

function setMinLongPosition(uint256 newMinLongPosition) external onlyRole(Constants.SET_PROTOCOL_PARAMS_ROLE);

Parameters

NameTypeDescription
newMinLongPositionuint256The new minimum long position size (with _assetDecimals).

setSafetyMarginBps

Sets the new safety margin for the liquidation price of newly open positions.

function setSafetyMarginBps(uint256 newSafetyMarginBps) external onlyRole(Constants.SET_OPTIONS_ROLE);

Parameters

NameTypeDescription
newSafetyMarginBpsuint256The new safety margin (in basis points).

setLiquidationIteration

Sets the new number of liquidations iteration for user actions.

function setLiquidationIteration(uint16 newLiquidationIteration) external onlyRole(Constants.SET_OPTIONS_ROLE);

Parameters

NameTypeDescription
newLiquidationIterationuint16The new number of liquidation iteration.

setFeeThreshold

Sets the minimum amount of fees to be collected before they can be withdrawn.

function setFeeThreshold(uint256 newFeeThreshold) external onlyRole(Constants.SET_OPTIONS_ROLE);

Parameters

NameTypeDescription
newFeeThresholduint256The minimum amount of fees to be collected before they can be withdrawn.

setTargetUsdnPrice

Sets the target USDN price.

When a rebase of USDN occurs, it will bring the price back down to this value.

function setTargetUsdnPrice(uint128 newPrice) external onlyRole(Constants.SET_USDN_PARAMS_ROLE);

Parameters

NameTypeDescription
newPriceuint128The new target price (with _priceFeedDecimals). This value cannot be greater than _usdnRebaseThreshold.

setUsdnRebaseThreshold

Sets the USDN rebase threshold.

When the price of USDN exceeds this value, a rebase will be triggered.

function setUsdnRebaseThreshold(uint128 newThreshold) external onlyRole(Constants.SET_USDN_PARAMS_ROLE);

Parameters

NameTypeDescription
newThresholduint128The new threshold value (with _priceFeedDecimals). This value cannot be smaller than _targetUsdnPrice or greater than uint128(2 * 10 ** s._priceFeedDecimals)

pause

Pauses related USDN protocol functions.

Pauses simultaneously all initiate/validate, refundSecurityDeposit and transferPositionOwnership functions. Before pausing, this function will call _applyPnlAndFunding with _lastPrice and the current timestamp. This is done to stop the funding rate from accumulating while the protocol is paused. Be sure to call unpause to update _lastUpdateTimestamp when unpausing.

function pause() external onlyRole(Constants.PAUSER_ROLE);

pauseSafe

Pauses related USDN protocol functions without applying PnLs and the funding.

Pauses simultaneously all initiate/validate, refundSecurityDeposit and transferPositionOwnership functions. This safe version will not call _applyPnlAndFunding before pausing.

function pauseSafe() external onlyRole(Constants.PAUSER_ROLE);

unpause

Unpauses related USDN protocol functions.

Unpauses simultaneously all initiate/validate, refundSecurityDeposit and transferPositionOwnership functions. This function will set _lastUpdateTimestamp to the current timestamp to prevent any funding during the pause. Only meant to be called after a pause call.

function unpause() external onlyRole(Constants.UNPAUSER_ROLE);

unpauseSafe

Unpauses related USDN protocol functions without updating _lastUpdateTimestamp.

Unpauses simultaneously all initiate/validate, refundSecurityDeposit and transferPositionOwnership functions. This safe version will not set _lastUpdateTimestamp to the current timestamp.

function unpauseSafe() external onlyRole(Constants.UNPAUSER_ROLE);

UsdnProtocolImpl

Git Source

Inherits: IUsdnProtocolImpl, UsdnProtocolActions, UsdnProtocolCore, UsdnProtocolVault, UsdnProtocolLong, UUPSUpgradeable

Functions

constructor

Note: oz-upgrades-unsafe-allow: constructor

constructor();

initializeStorage

Initializes the protocol's storage with the given values.

This function should be called on deployment when creating the proxy. It can only be called once.

function initializeStorage(InitStorage calldata initStorage) public reinitializer(2);

Parameters

NameTypeDescription
initStorageInitStorageThe initial storage values. Any call with a function signature not present in this contract will be delegated to the fallback contract.

_authorizeUpgrade

Verifies that the caller is allowed to upgrade the protocol.

*Function that should revert when msg.sender is not authorized to upgrade the contract. Called by {upgradeToAndCall}. Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.

function _authorizeUpgrade(address) internal onlyOwner {}
```*


```solidity
function _authorizeUpgrade(address implementation) internal override onlyRole(Constants.PROXY_UPGRADE_ROLE);

Parameters

NameTypeDescription
implementationaddressThe address of the new implementation contract.

_delegate

Delegates the call to the fallback contract.

function _delegate(address protocolFallbackAddr) internal;

Parameters

NameTypeDescription
protocolFallbackAddraddressThe address of the fallback contract.

fallback

Delegates the call to the fallback contract if the function signature contained in the transaction data does not match any function in the implementation contract.

fallback() external;

UsdnProtocolLong

Git Source

Inherits: IUsdnProtocolLong

Functions

minTick

Gets the value of the lowest usable tick, taking into account the tick spacing.

Note that the effective minimum tick of a newly open long position also depends on the minimum allowed leverage value and the current value of the liquidation price multiplier.

function minTick() external view returns (int24 tick_);

Returns

NameTypeDescription
tick_int24The lowest usable tick.

getLiqPriceFromDesiredLiqPrice

Gets the liquidation price from a desired one by taking into account the tick rounding.

function getLiqPriceFromDesiredLiqPrice(
    uint128 desiredLiqPriceWithoutPenalty,
    uint256 assetPrice,
    uint256 longTradingExpo,
    HugeUint.Uint512 memory accumulator,
    int24 tickSpacing,
    uint24 liquidationPenalty
) external pure returns (uint128 liqPrice_);

Parameters

NameTypeDescription
desiredLiqPriceWithoutPenaltyuint128The desired liquidation price without the penalty.
assetPriceuint256The current price of the asset.
longTradingExpouint256The trading exposition of the long side.
accumulatorHugeUint.Uint512The liquidation multiplier accumulator.
tickSpacingint24The tick spacing.
liquidationPenaltyuint24The liquidation penalty set on the tick.

Returns

NameTypeDescription
liqPrice_uint128The new liquidation price without the penalty.

getPositionValue

Gets the value of a long position when the asset price is equal to the given price, at the given timestamp.

If the current price is smaller than the liquidation price of the position without the liquidation penalty, then the value of the position is negative.

function getPositionValue(PositionId calldata posId, uint128 price, uint128 timestamp)
    external
    view
    returns (int256 value_);

Parameters

NameTypeDescription
posIdPositionIdThe unique position identifier.
priceuint128The asset price.
timestampuint128The timestamp of the price.

Returns

NameTypeDescription
value_int256The position value in assets.

getEffectiveTickForPrice

Gets the tick number corresponding to a given price, accounting for funding effects.

Uses the stored parameters for calculation.

function getEffectiveTickForPrice(uint128 price) external view returns (int24 tick_);

Parameters

NameTypeDescription
priceuint128The asset price.

Returns

NameTypeDescription
tick_int24The tick number, a multiple of the tick spacing.

getEffectiveTickForPrice

Gets the tick number corresponding to a given price, accounting for funding effects.

Uses the stored parameters for calculation.

function getEffectiveTickForPrice(
    uint128 price,
    uint256 assetPrice,
    uint256 longTradingExpo,
    HugeUint.Uint512 memory accumulator,
    int24 tickSpacing
) external pure returns (int24 tick_);

Parameters

NameTypeDescription
priceuint128The asset price.
assetPriceuint256
longTradingExpouint256
accumulatorHugeUint.Uint512
tickSpacingint24

Returns

NameTypeDescription
tick_int24The tick number, a multiple of the tick spacing.

getTickLiquidationPenalty

Retrieves the liquidation penalty assigned to the given tick if there are positions in it, otherwise retrieve the current setting value from storage.

function getTickLiquidationPenalty(int24 tick) external view returns (uint24 liquidationPenalty_);

Parameters

NameTypeDescription
tickint24The tick number.

Returns

NameTypeDescription
liquidationPenalty_uint24The liquidation penalty, in tick spacing units.

getLongPosition

Gets a long position identified by its tick, tick version and index.

function getLongPosition(PositionId memory posId)
    external
    view
    returns (Position memory pos_, uint24 liquidationPenalty_);

Parameters

NameTypeDescription
posIdPositionIdThe unique position identifier.

Returns

NameTypeDescription
pos_PositionThe position data.
liquidationPenalty_uint24The liquidation penalty for that position.

longAssetAvailableWithFunding

Gets the predicted value of the long balance for the given asset price and timestamp.

The effects of the funding and any PnL of the long positions since the last contract state update is taken into account, as well as the fees. If the provided timestamp is older than the last state update, the function reverts with UsdnProtocolTimestampTooOld. The value cannot be below 0.

function longAssetAvailableWithFunding(uint128 currentPrice, uint128 timestamp)
    external
    view
    returns (uint256 available_);

Parameters

NameTypeDescription
currentPriceuint128The given asset price.
timestampuint128The timestamp corresponding to the given price.

Returns

NameTypeDescription
available_uint256The long balance value in assets.

longTradingExpoWithFunding

Gets the predicted value of the long trading exposure for the given asset price and timestamp.

The effects of the funding and any profit or loss of the long positions since the last contract state update is taken into account. If the provided timestamp is older than the last state update, the function reverts with UsdnProtocolTimestampTooOld. The value cannot be below 0.

function longTradingExpoWithFunding(uint128 currentPrice, uint128 timestamp) external view returns (uint256 expo_);

Parameters

NameTypeDescription
currentPriceuint128The given asset price.
timestampuint128The timestamp corresponding to the given price.

Returns

NameTypeDescription
expo_uint256The long trading exposure value in assets.

UsdnProtocolVault

Git Source

Inherits: IUsdnProtocolVault

Functions

usdnPrice

Calculates the predicted USDN token price based on the given asset price and timestamp.

The effects of the funding and the PnL of the long positions since the last contract state update are taken into account.

function usdnPrice(uint128 currentPrice, uint128 timestamp) external view returns (uint256 price_);

Parameters

NameTypeDescription
currentPriceuint128The current or predicted asset price.
timestampuint128The timestamp corresponding to currentPrice.

Returns

NameTypeDescription
price_uint256The predicted USDN token price.

usdnPrice

Calculates the predicted USDN token price based on the given asset price and timestamp.

The effects of the funding and the PnL of the long positions since the last contract state update are taken into account.

function usdnPrice(uint128 currentPrice) external view returns (uint256 price_);

Parameters

NameTypeDescription
currentPriceuint128The current or predicted asset price.

Returns

NameTypeDescription
price_uint256The predicted USDN token price.

vaultAssetAvailableWithFunding

Gets the amount of assets in the vault for the given asset price and timestamp.

The effects of the funding, the PnL of the long positions and the accumulated fees since the last contract state update are taken into account, but not liquidations. If the provided timestamp is older than the last state update, the function reverts with UsdnProtocolTimestampTooOld.

function vaultAssetAvailableWithFunding(uint128 currentPrice, uint128 timestamp)
    external
    view
    returns (uint256 available_);

Parameters

NameTypeDescription
currentPriceuint128The current or predicted asset price.
timestampuint128The timestamp corresponding to currentPrice (must not be earlier than _lastUpdateTimestamp).

Returns

NameTypeDescription
available_uint256The available vault balance (cannot be less than 0).

Contents

Contents

IBaseLiquidationRewardsManager

Git Source

This interface exposes the only function used by the UsdnProtocol.

Future implementations of the rewards manager must implement this interface without modifications.

Functions

getLiquidationRewards

Computes the amount of assets to reward a liquidator.

function getLiquidationRewards(
    Types.LiqTickInfo[] calldata liquidatedTicks,
    uint256 currentPrice,
    bool rebased,
    Types.RebalancerAction rebalancerAction,
    Types.ProtocolAction action,
    bytes calldata rebaseCallbackResult,
    bytes calldata priceData
) external view returns (uint256 assetRewards_);

Parameters

NameTypeDescription
liquidatedTicksTypes.LiqTickInfo[]Information about the liquidated ticks.
currentPriceuint256The current price of the asset.
rebasedboolIndicates whether a USDN rebase was performed.
rebalancerActionTypes.RebalancerActionThe action performed by the _triggerRebalancer function.
actionTypes.ProtocolActionThe type of protocol action that triggered the liquidation.
rebaseCallbackResultbytesThe result of the rebase callback, if any.
priceDatabytesThe oracle price data, if any. This can be used to differentiate rewards based on the oracle used to provide the liquidation price.

Returns

NameTypeDescription
assetRewards_uint256The amount of asset tokens to reward the liquidator.

ILiquidationRewardsManager

Git Source

Inherits: IBaseLiquidationRewardsManager, ILiquidationRewardsManagerErrorsEventsTypes

Interface for managing liquidation rewards within the protocol.

Functions

BPS_DIVISOR

Gets the denominator used for the reward multipliers.

function BPS_DIVISOR() external pure returns (uint32);

Returns

NameTypeDescription
<none>uint32The BPS divisor.

BASE_GAS_COST

Gets the fixed gas amount used as a base for transaction cost computations.

Stored as a uint256 to prevent overflow during gas usage computations.

function BASE_GAS_COST() external pure returns (uint256);

Returns

NameTypeDescription
<none>uint256The base gas cost.

MAX_GAS_USED_PER_TICK

Gets the maximum allowable gas usage per liquidated tick.

function MAX_GAS_USED_PER_TICK() external pure returns (uint256);

Returns

NameTypeDescription
<none>uint256The maximum gas used per tick.

MAX_OTHER_GAS_USED

Gets the maximum allowable gas usage for all other computations.

function MAX_OTHER_GAS_USED() external pure returns (uint256);

Returns

NameTypeDescription
<none>uint256The maximum gas used for additional computations.

MAX_REBASE_GAS_USED

Gets the maximum allowable gas usage for rebase operations.

function MAX_REBASE_GAS_USED() external pure returns (uint256);

Returns

NameTypeDescription
<none>uint256The maximum gas used for rebase operations.

MAX_REBALANCER_GAS_USED

Gets the maximum allowable gas usage for triggering the optional rebalancer.

function MAX_REBALANCER_GAS_USED() external pure returns (uint256);

Returns

NameTypeDescription
<none>uint256The maximum gas used for the optional rebalancer trigger.

getRewardsParameters

Retrieves the current parameters used for reward calculations.

function getRewardsParameters() external view returns (RewardsParameters memory);

Returns

NameTypeDescription
<none>RewardsParametersrewardsParameters_ A struct containing the rewards parameters.

setRewardsParameters

Updates the parameters used for calculating liquidation rewards.

function setRewardsParameters(
    uint32 gasUsedPerTick,
    uint32 otherGasUsed,
    uint32 rebaseGasUsed,
    uint32 rebalancerGasUsed,
    uint64 baseFeeOffset,
    uint16 gasMultiplierBps,
    uint16 positionBonusMultiplierBps,
    uint128 fixedReward,
    uint128 maxReward
) external;

Parameters

NameTypeDescription
gasUsedPerTickuint32The gas consumed per tick for liquidation.
otherGasUseduint32The gas consumed for all additional computations.
rebaseGasUseduint32The gas consumed for optional USDN rebase operation.
rebalancerGasUseduint32The gas consumed for the optional rebalancer trigger.
baseFeeOffsetuint64An offset added to the block's base gas fee.
gasMultiplierBpsuint16The multiplier for the gas usage (in BPS).
positionBonusMultiplierBpsuint16Multiplier for position size bonus (in BPS).
fixedRewarduint128A fixed reward amount (in native currency, converted to wstETH).
maxRewarduint128The maximum allowable reward amount (in native currency, converted to wstETH).

ILiquidationRewardsManagerErrorsEventsTypes

Git Source

Interface defining events, structs, and errors for the LiquidationRewardsManager.

Events

RewardsParametersUpdated

The rewards parameters are updated.

event RewardsParametersUpdated(
    uint32 gasUsedPerTick,
    uint32 otherGasUsed,
    uint32 rebaseGasUsed,
    uint32 rebalancerGasUsed,
    uint64 baseFeeOffset,
    uint16 gasMultiplierBps,
    uint16 positionBonusMultiplierBps,
    uint128 fixedReward,
    uint128 maxReward
);

Parameters

NameTypeDescription
gasUsedPerTickuint32The amount of gas consumed per tick for liquidation.
otherGasUseduint32The gas consumed for all additional computations.
rebaseGasUseduint32The gas consumed for optional USDN rebase operation.
rebalancerGasUseduint32The gas consumed for the optional rebalancer trigger.
baseFeeOffsetuint64An offset added to the block's base gas fee.
gasMultiplierBpsuint16The multiplier for the gas usage (in BPS).
positionBonusMultiplierBpsuint16The multiplier for position size bonus (in BPS).
fixedRewarduint128A fixed reward amount (in native currency, converted to wstETH).
maxRewarduint128The maximum allowable reward amount (in native currency, converted to wstETH).

Errors

LiquidationRewardsManagerGasUsedPerTickTooHigh

The gasUsedPerTick parameter exceeds the allowable limit.

error LiquidationRewardsManagerGasUsedPerTickTooHigh(uint256 value);

Parameters

NameTypeDescription
valueuint256The given value.

LiquidationRewardsManagerOtherGasUsedTooHigh

The otherGasUsed parameter exceeds the allowable limit.

error LiquidationRewardsManagerOtherGasUsedTooHigh(uint256 value);

Parameters

NameTypeDescription
valueuint256The given value.

LiquidationRewardsManagerRebaseGasUsedTooHigh

The rebaseGasUsed parameter exceeds the allowable limit.

error LiquidationRewardsManagerRebaseGasUsedTooHigh(uint256 value);

Parameters

NameTypeDescription
valueuint256The given value.

LiquidationRewardsManagerRebalancerGasUsedTooHigh

The rebalancerGasUsed parameter exceeds the allowable limit.

error LiquidationRewardsManagerRebalancerGasUsedTooHigh(uint256 value);

Parameters

NameTypeDescription
valueuint256The given value.

LiquidationRewardsManagerMaxRewardTooLow

The maxReward parameter is below the allowable minimum.

error LiquidationRewardsManagerMaxRewardTooLow(uint256 value);

Parameters

NameTypeDescription
valueuint256The given value.

Structs

RewardsParameters

The parameters used for calculating rewards.

struct RewardsParameters {
    uint32 gasUsedPerTick;
    uint32 otherGasUsed;
    uint32 rebaseGasUsed;
    uint32 rebalancerGasUsed;
    uint64 baseFeeOffset;
    uint16 gasMultiplierBps;
    uint16 positionBonusMultiplierBps;
    uint128 fixedReward;
    uint128 maxReward;
}

Properties

NameTypeDescription
gasUsedPerTickuint32The gas consumed per tick for liquidation.
otherGasUseduint32The gas consumed for all additional computations.
rebaseGasUseduint32The gas consumed for optional USDN rebase operation.
rebalancerGasUseduint32The gas consumed for the optional rebalancer trigger.
baseFeeOffsetuint64An offset added to the block's base gas fee.
gasMultiplierBpsuint16The multiplier for the gas usage (in BPS).
positionBonusMultiplierBpsuint16The multiplier for position size bonus (in BPS).
fixedRewarduint128A fixed reward amount (in native currency, converted to wstETH).
maxRewarduint128The maximum allowable reward amount (in native currency, converted to wstETH).

Contents

IBaseOracleMiddleware

Git Source

This interface exposes the only functions used or required by the USDN Protocol.

Any current or future implementation of the oracle middleware must be compatible with this interface without any modification.

Functions

parseAndValidatePrice

Parse and validate data and returns the corresponding price data.

The data format is specific to the middleware and is simply forwarded from the user transaction's calldata. A fee amounting to exactly validationCost (with the same data and action) must be sent or the transaction will revert.

function parseAndValidatePrice(
    bytes32 actionId,
    uint128 targetTimestamp,
    Types.ProtocolAction action,
    bytes calldata data
) external payable returns (PriceInfo memory result_);

Parameters

NameTypeDescription
actionIdbytes32A unique identifier for the current action. This identifier can be used to link an Initiate call with the corresponding Validate call.
targetTimestampuint128The target timestamp for validating the price data. For validation actions, this is the timestamp of the initiation.
actionTypes.ProtocolActionType of action for which the price is requested. The middleware may use this to alter the validation of the price or the returned price.
databytesThe data to be used to communicate with oracles, the format varies from middleware to middleware and can be different depending on the action.

Returns

NameTypeDescription
result_PriceInfoThe price and timestamp as PriceInfo.

getValidationDelay

Gets the required delay (in seconds) between the moment an action is initiated and the timestamp of the price data used to validate that action.

function getValidationDelay() external view returns (uint256 delay_);

Returns

NameTypeDescription
delay_uint256The validation delay.

getLowLatencyDelay

Gets The maximum amount of time (in seconds) after initiation during which a low-latency price oracle can be used for validation.

function getLowLatencyDelay() external view returns (uint16 delay_);

Returns

NameTypeDescription
delay_uint16The maximum delay for low-latency validation.

getDecimals

Gets the number of decimals for the price.

function getDecimals() external view returns (uint8 decimals_);

Returns

NameTypeDescription
decimals_uint8The number of decimals.

validationCost

Returns the cost of one price validation for the given action (in native token).

function validationCost(bytes calldata data, Types.ProtocolAction action) external view returns (uint256 cost_);

Parameters

NameTypeDescription
databytesPrice data for which to get the fee.
actionTypes.ProtocolActionType of the action for which the price is requested.

Returns

NameTypeDescription
cost_uint256The cost of one price validation (in native token).

IChainlinkDataStreamsOracle

Git Source

Functions

getProxyVerifier

Gets the Chainlink Proxy verifier contract.

function getProxyVerifier() external view returns (IVerifierProxy proxyVerifier_);

Returns

NameTypeDescription
proxyVerifier_IVerifierProxyThe address of the proxy verifier contract.

getStreamId

Gets the supported Chainlink data stream ID.

function getStreamId() external view returns (bytes32 streamId_);

Returns

NameTypeDescription
streamId_bytes32The unique identifier for the Chainlink data streams.

getDataStreamRecentPriceDelay

Gets the maximum age of a recent price to be considered valid.

function getDataStreamRecentPriceDelay() external view returns (uint256 delay_);

Returns

NameTypeDescription
delay_uint256The maximum acceptable age of a recent price in seconds.

getReportVersion

Gets the supported Chainlink data streams report version.

function getReportVersion() external pure returns (uint256 version_);

Returns

NameTypeDescription
version_uint256The version number of the supported Chainlink data streams report.

IChainlinkOracle

Git Source

Functions

PRICE_TOO_OLD

The sentinel value returned instead of the price if the data from the oracle is too old.

function PRICE_TOO_OLD() external pure returns (int256 sentinelValue_);

Returns

NameTypeDescription
sentinelValue_int256The sentinel value for "price too old".

getChainlinkDecimals

Gets the number of decimals of the asset from Chainlink.

function getChainlinkDecimals() external view returns (uint256 decimals_);

Returns

NameTypeDescription
decimals_uint256The number of decimals of the asset.

getPriceFeed

Gets the Chainlink price feed aggregator contract address.

function getPriceFeed() external view returns (AggregatorV3Interface priceFeed_);

Returns

NameTypeDescription
priceFeed_AggregatorV3InterfaceThe address of the Chainlink price feed contract.

getChainlinkTimeElapsedLimit

Gets the duration after which the Chainlink data is considered stale or invalid.

function getChainlinkTimeElapsedLimit() external view returns (uint256 limit_);

Returns

NameTypeDescription
limit_uint256The price validity duration.

ICommonOracleMiddleware

Git Source

Inherits: IBaseOracleMiddleware, IOracleMiddlewareErrors, IOracleMiddlewareEvents, IAccessControlDefaultAdminRules

This is the common middleware interface for all current middlewares.

Functions

ADMIN_ROLE

Gets the admin role's signature.

function ADMIN_ROLE() external pure returns (bytes32 role_);

Returns

NameTypeDescription
role_bytes32Get the role signature.

setChainlinkTimeElapsedLimit

Sets the elapsed time tolerated before we consider the price from Chainlink invalid.

function setChainlinkTimeElapsedLimit(uint256 newTimeElapsedLimit) external;

Parameters

NameTypeDescription
newTimeElapsedLimituint256The new time elapsed limit.

setPythRecentPriceDelay

Sets the amount of time after which we do not consider a price as recent.

function setPythRecentPriceDelay(uint64 newDelay) external;

Parameters

NameTypeDescription
newDelayuint64The maximum age of a price to be considered recent.

setValidationDelay

Sets the validation delay (in seconds) between an action timestamp and the price data timestamp used to validate that action.

function setValidationDelay(uint256 newValidationDelay) external;

Parameters

NameTypeDescription
newValidationDelayuint256The new validation delay.

setLowLatencyDelay

Sets the new low latency delay.

function setLowLatencyDelay(uint16 newLowLatencyDelay, IUsdnProtocol usdnProtocol) external;

Parameters

NameTypeDescription
newLowLatencyDelayuint16The new low latency delay.
usdnProtocolIUsdnProtocolThe address of the USDN protocol.

withdrawEther

Withdraws the ether balance of this contract.

This contract can receive funds but is not designed to hold them. So this function can be used if there's an error and funds remain after a call.

function withdrawEther(address to) external;

Parameters

NameTypeDescription
toaddressThe address to send the ether to.

IFeeManager

Git Source

Inherits: IERC165

Functions

s_subscriberDiscounts

Gets the subscriber discount for a specific feedId.

function s_subscriberDiscounts(address subscriber, bytes32 feedId, address token) external view returns (uint256);

Parameters

NameTypeDescription
subscriberaddressThe address of the subscriber to check for a discount.
feedIdbytes32The feedId related to the discount.
tokenaddressThe address of the quote payment token.

Returns

NameTypeDescription
<none>uint256The current subscriber discount.

s_linkDeficit

Gets any subsidized LINK that is owed to the reward manager for a specific feedId.

function s_linkDeficit(bytes32 feedId) external view returns (uint256);

Parameters

NameTypeDescription
feedIdbytes32The feedId related to the link deficit.

Returns

NameTypeDescription
<none>uint256The amount of link deficit.

i_linkAddress

Gets the LINK token address.

function i_linkAddress() external view returns (address);

Returns

NameTypeDescription
<none>addressThe address of the LINK token.

i_nativeAddress

Gets the native token address.

function i_nativeAddress() external view returns (address);

Returns

NameTypeDescription
<none>addressThe address of the native token.

i_proxyAddress

Gets the proxy contract address.

function i_proxyAddress() external view returns (address);

Returns

NameTypeDescription
<none>addressThe address of the proxy contract.

s_nativeSurcharge

Gets the surcharge fee to be paid if paying in native.

function s_nativeSurcharge() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The surcharge fee for native payments.

getFeeAndReward

Calculates the applied fee and reward from a report. If the sender is a subscriber, they will receive a discount.

function getFeeAndReward(address subscriber, bytes memory report, address quoteAddress)
    external
    view
    returns (Asset memory feeData, Asset memory rewardData, uint256 discount);

Parameters

NameTypeDescription
subscriberaddressThe address of the subscriber trying to verify.
reportbytesThe report to calculate the fee for.
quoteAddressaddressThe address of the quote payment token.

Returns

NameTypeDescription
feeDataAssetThe calculated fee data.
rewardDataAssetThe calculated reward data.
discountuint256The current subscriber discount applied.

Structs

Asset

The Asset struct to hold the address of an asset and its amount.

struct Asset {
    address assetAddress;
    uint256 amount;
}

Properties

NameTypeDescription
assetAddressaddressThe address of the asset.
amountuint256The amount of the asset.

IOracleMiddlewareErrors

Git Source

Defines all the custom errors thrown by the contracts related to the OracleMiddleware contracts.

Errors

OracleMiddlewareWrongPrice

The price returned by an oracle is negative.

error OracleMiddlewareWrongPrice(int256 price);

Parameters

NameTypeDescription
priceint256The price returned by the oracle.

OracleMiddlewareWrongAskPrice

The ask price returned by Chainlink data streams is negative.

error OracleMiddlewareWrongAskPrice(int256 askPrice);

Parameters

NameTypeDescription
askPriceint256The ask price returned by Chainlink data streams.

OracleMiddlewareWrongBidPrice

The bid price returned by Chainlink data streams is negative.

error OracleMiddlewareWrongBidPrice(int256 bidPrice);

Parameters

NameTypeDescription
bidPriceint256The bid price returned by Chainlink data streams.

OracleMiddlewarePriceTooOld

The price returned by an oracle is too old.

error OracleMiddlewarePriceTooOld(uint256 timestamp);

Parameters

NameTypeDescription
timestampuint256The timestamp of the price given by the oracle.

OracleMiddlewarePriceTooRecent

The price returned by an oracle is too recent.

error OracleMiddlewarePriceTooRecent(uint256 timestamp);

Parameters

NameTypeDescription
timestampuint256The timestamp of the price given by the oracle.

OracleMiddlewarePythPositiveExponent

The Pyth price reported a positive exponent (negative decimals).

error OracleMiddlewarePythPositiveExponent(int32 expo);

Parameters

NameTypeDescription
expoint32The price exponent.

OracleMiddlewareConfValueTooHigh

Indicates that the confidence value is higher than the price.

error OracleMiddlewareConfValueTooHigh();

OracleMiddlewareConfRatioTooHigh

Indicates that the confidence ratio is too high.

error OracleMiddlewareConfRatioTooHigh();

OracleMiddlewareIncorrectFee

Indicates that an incorrect amount of tokens was provided to cover the cost of price validation.

error OracleMiddlewareIncorrectFee();

OracleMiddlewarePythFeeSafeguard

The validation fee returned by the Pyth contract exceeded the safeguard value.

error OracleMiddlewarePythFeeSafeguard(uint256 fee);

Parameters

NameTypeDescription
feeuint256The required fee returned by Pyth.

OracleMiddlewareRedstoneSafeguard

The Redstone price is to divergent from the Chainlink price.

error OracleMiddlewareRedstoneSafeguard();

OracleMiddlewareTransferFailed

The withdrawal of the Ether in the contract failed.

error OracleMiddlewareTransferFailed(address to);

Parameters

NameTypeDescription
toaddressThe address of the intended recipient.

OracleMiddlewareTransferToZeroAddress

The recipient of a transfer is the zero address.

error OracleMiddlewareTransferToZeroAddress();

OracleMiddlewareInvalidRecentPriceDelay

The recent price delay is outside of the limits.

error OracleMiddlewareInvalidRecentPriceDelay(uint64 newDelay);

Parameters

NameTypeDescription
newDelayuint64The delay that was provided.

OracleMiddlewareInvalidPenaltyBps

The new penalty is invalid.

error OracleMiddlewareInvalidPenaltyBps();

OracleMiddlewareInvalidRoundId

The provided Chainlink round ID is invalid.

error OracleMiddlewareInvalidRoundId();

OracleMiddlewareInvalidLowLatencyDelay

The new low latency delay is invalid.

error OracleMiddlewareInvalidLowLatencyDelay();

OracleMiddlewareInvalidReportVersion

The Chainlink data streams report version is invalid.

error OracleMiddlewareInvalidReportVersion();

OracleMiddlewareInvalidStreamId

The Chainlink report stream ID is invalid.

error OracleMiddlewareInvalidStreamId();

OracleMiddlewareDataStreamInvalidTimestamp

The Chainlink data streams report timestamp is invalid.

error OracleMiddlewareDataStreamInvalidTimestamp();

OracleMiddlewareDataStreamFeeSafeguard

The validation fee returned by the Chainlink fee manager contract exceeded the safeguard value.

error OracleMiddlewareDataStreamFeeSafeguard(uint256 fee);

Parameters

NameTypeDescription
feeuint256The required fee returned by the Chainlink fee manager.

IOracleMiddlewareEvents

Git Source

Defines all the custom events emitted by the contracts related to the OracleMiddleware contracts.

Events

TimeElapsedLimitUpdated

The time elapsed limit was updated.

event TimeElapsedLimitUpdated(uint256 newTimeElapsedLimit);

Parameters

NameTypeDescription
newTimeElapsedLimituint256The new limit.

ValidationDelayUpdated

The validation delay was updated.

event ValidationDelayUpdated(uint256 newValidationDelay);

Parameters

NameTypeDescription
newValidationDelayuint256The new validation delay.

PythRecentPriceDelayUpdated

The recent price delay for Pyth was updated.

event PythRecentPriceDelayUpdated(uint64 newDelay);

Parameters

NameTypeDescription
newDelayuint64The new recent price delay.

DataStreamsRecentPriceDelayUpdated

The recent price delay for Chainlink data streams was updated.

event DataStreamsRecentPriceDelayUpdated(uint64 newDelay);

Parameters

NameTypeDescription
newDelayuint64The new recent price delay.

RedstoneRecentPriceDelayUpdated

The recent price delay for Redstone was updated.

event RedstoneRecentPriceDelayUpdated(uint48 newDelay);

Parameters

NameTypeDescription
newDelayuint48The new recent price delay.

ConfRatioUpdated

The confidence ratio was updated.

event ConfRatioUpdated(uint256 newConfRatio);

Parameters

NameTypeDescription
newConfRatiouint256The new confidence ratio.

PenaltyBpsUpdated

The penalty for Redstone prices was updated.

event PenaltyBpsUpdated(uint16 newPenaltyBps);

Parameters

NameTypeDescription
newPenaltyBpsuint16The new penalty.

LowLatencyDelayUpdated

The low latency delay was updated.

event LowLatencyDelayUpdated(uint16 newLowLatencyDelay);

Parameters

NameTypeDescription
newLowLatencyDelayuint16The new low latency delay.

PriceInfo

Git Source

The price and timestamp returned by the oracle middleware.

struct PriceInfo {
    uint256 price;
    uint256 neutralPrice;
    uint256 timestamp;
}

Properties

NameTypeDescription
priceuint256The validated asset price, potentially adjusted by the middleware.
neutralPriceuint256The neutral/average price of the asset.
timestampuint256The timestamp of the price data.

ChainlinkPriceInfo

Git Source

The price and timestamp returned by the Chainlink oracle.

struct ChainlinkPriceInfo {
    int256 price;
    uint256 timestamp;
}

Properties

NameTypeDescription
priceint256The asset price formatted by the middleware.
timestampuint256When the price was published on chain.

FormattedPythPrice

Git Source

Representation of a Pyth price with a uint256 price.

struct FormattedPythPrice {
    uint256 price;
    uint256 conf;
    uint256 publishTime;
}

Properties

NameTypeDescription
priceuint256The price of the asset.
confuint256The confidence interval around the price (in dollars, absolute value).
publishTimeuint256Unix timestamp describing when the price was published.

RedstonePriceInfo

Git Source

The price and timestamp returned by the Redstone oracle.

struct RedstonePriceInfo {
    uint256 price;
    uint256 timestamp;
}

Properties

NameTypeDescription
priceuint256The asset price formatted by the middleware.
timestampuint256The timestamp of the price data.

PriceAdjustment

Git Source

Represents the options for the low latency price adjustment.

Used to determine how the price is adjusted based on protocol action.

enum PriceAdjustment {
    Up,
    Down,
    None
}

FormattedDataStreamsPrice

Git Source

Representation of data streams asset price with a uint256 price.

struct FormattedDataStreamsPrice {
    uint256 timestamp;
    uint256 price;
    uint256 ask;
    uint256 bid;
}

Properties

NameTypeDescription
timestampuint256The timestamp of the asset price.
priceuint256The price of the asset with 18 decimals.
askuint256The simulated price impact of a sell order.
biduint256The simulated price impact of a buy order.

IOracleMiddlewareWithDataStreams

Git Source

Inherits: ICommonOracleMiddleware, IChainlinkDataStreamsOracle

The oracle middleware is a contract that is used by the USDN protocol to validate price data. Using a middleware allows the protocol to later upgrade to a new oracle logic without having to modify the protocol's contracts.

This middleware uses Chainlink Data Streams and Pyth as the low-latency oracle, and Chainlink Data Feeds as fallback. For liquidations, either Pyth or Data Streams can be used. For validations, only Data Streams is accepted.

Functions

setDataStreamsRecentPriceDelay

Sets the amount of time after which we do not consider a price as recent for Chainlink.

function setDataStreamsRecentPriceDelay(uint64 newDelay) external;

Parameters

NameTypeDescription
newDelayuint64The maximum age of a price to be considered recent.

IOracleMiddlewareWithPyth

Git Source

Inherits: ICommonOracleMiddleware

The oracle middleware is a contract that is used by the USDN protocol to validate price data. Using a middleware allows the protocol to later upgrade to a new oracle logic without having to modify the protocol's contracts.

This middleware uses Pyth as low-latency oracle and Chainlink Data Feeds as fallback.

Functions

BPS_DIVISOR

Gets the denominator for the variables using basis points as a unit.

function BPS_DIVISOR() external pure returns (uint16 denominator_);

Returns

NameTypeDescription
denominator_uint16The BPS divisor.

MAX_CONF_RATIO

Gets the maximum value for _confRatioBps.

function MAX_CONF_RATIO() external pure returns (uint16 ratio_);

Returns

NameTypeDescription
ratio_uint16The max allowed confidence ratio.

getConfRatioBps

Gets the confidence ratio.

This ratio is used to apply a specific portion of the confidence interval provided by an oracle, which is used to adjust the precision of predictions or estimations.

function getConfRatioBps() external view returns (uint16 ratio_);

Returns

NameTypeDescription
ratio_uint16The confidence ratio (in basis points).

setConfRatio

Sets the confidence ratio.

The new value should be lower than MAX_CONF_RATIO.

function setConfRatio(uint16 newConfRatio) external;

Parameters

NameTypeDescription
newConfRatiouint16the new confidence ratio.

IOracleMiddlewareWithRedstone

Git Source

Inherits: IOracleMiddlewareWithPyth

Same as the default oracle middleware, with added support for Redstone

Functions

getPenaltyBps

Gets the penalty for using a non-Pyth price with low latency oracle (in basis points)

function getPenaltyBps() external view returns (uint16 penaltyBps_);

Returns

NameTypeDescription
penaltyBps_uint16The penalty (in basis points).

setRedstoneRecentPriceDelay

Sets the Redstone recent price delay.

function setRedstoneRecentPriceDelay(uint48 newDelay) external;

Parameters

NameTypeDescription
newDelayuint48The maximum age of a price to be considered recent.

setPenaltyBps

Sets the penalty (in basis points).

function setPenaltyBps(uint16 newPenaltyBps) external;

Parameters

NameTypeDescription
newPenaltyBpsuint16The new penalty.

IPythOracle

Git Source

Inherits: IOracleMiddlewareErrors

Functions

getPyth

Gets the Pyth contract address.

function getPyth() external view returns (IPyth pyth_);

Returns

NameTypeDescription
pyth_IPythThe Pyth contract address.

getPythFeedId

Gets the ID of the price feed queried by this contract.

function getPythFeedId() external view returns (bytes32 feedId_);

Returns

NameTypeDescription
feedId_bytes32The Pyth price feed ID.

getPythRecentPriceDelay

Gets the recent price delay.

function getPythRecentPriceDelay() external view returns (uint64 recentPriceDelay_);

Returns

NameTypeDescription
recentPriceDelay_uint64The maximum age of a recent price to be considered valid.

IRedstoneOracle

Git Source

Functions

REDSTONE_HEARTBEAT

Gets the interval between two Redstone price updates.

function REDSTONE_HEARTBEAT() external pure returns (uint48 heartbeat_);

Returns

NameTypeDescription
heartbeat_uint48The interval in seconds.

REDSTONE_DECIMALS

Gets the number of decimals for prices contained in Redstone price updates.

function REDSTONE_DECIMALS() external pure returns (uint8 decimals_);

Returns

NameTypeDescription
decimals_uint8The number of decimals.

getRedstoneFeedId

Gets the ID of the Redstone price feed.

function getRedstoneFeedId() external view returns (bytes32 feedId_);

Returns

NameTypeDescription
feedId_bytes32The feed ID.

getRedstoneRecentPriceDelay

Gets the maximum age of a price to be considered recent.

function getRedstoneRecentPriceDelay() external view returns (uint48 delay_);

Returns

NameTypeDescription
delay_uint48The age in seconds.

validateTimestamp

Used by the Redstone contract internally, we override it to allow all timestamps.

function validateTimestamp(uint256 timestampMs) external pure;

Parameters

NameTypeDescription
timestampMsuint256The timestamp of the price update in milliseconds.

IVerifierProxy

Git Source

Functions

s_feeManager

Gets the fee manager contract.

function s_feeManager() external view returns (IFeeManager feeManager_);

Returns

NameTypeDescription
feeManager_IFeeManagerThe fee manager contract.

verify

Verifies that the data encoded has been signed correctly by routing to the correct verifier, and bills the user if applicable.

function verify(bytes calldata payload, bytes calldata parameterPayload)
    external
    payable
    returns (bytes memory verifierResponse);

Parameters

NameTypeDescription
payloadbytesThe encoded data to be verified, including the signed report.
parameterPayloadbytesThe fee metadata for billing.

Returns

NameTypeDescription
verifierResponsebytesThe encoded report from the verifier.

verifyBulk

Bulk verifies that the data encoded has been signed correctly by routing to the correct verifier, and bills the user if applicable.

function verifyBulk(bytes[] calldata payloads, bytes calldata parameterPayload)
    external
    payable
    returns (bytes[] memory verifiedReports);

Parameters

NameTypeDescription
payloadsbytes[]The encoded payloads to be verified, including the signed report.
parameterPayloadbytesThe fee metadata for billing.

Returns

NameTypeDescription
verifiedReportsbytes[]The encoded reports from the verifier.

getVerifier

Retrieves the verifier address that verifies reports for a config digest.

function getVerifier(bytes32 configDigest) external view returns (address verifierAddress);

Parameters

NameTypeDescription
configDigestbytes32The config digest to query for.

Returns

NameTypeDescription
verifierAddressaddressThe address of the verifier contract that verifies reports for a given config digest.

Structs

ReportV3

Represents a data report from a Data Streams for v3 schema (crypto streams).

The price, bid, and ask values are carried to either 8 or 18 decimal places, depending on the streams. For more information, see https://docs.chain.link/data-streams/crypto-streams and https://docs.chain.link/data-streams/reference/report-schema.

struct ReportV3 {
    bytes32 feedId;
    uint32 validFromTimestamp;
    uint32 observationsTimestamp;
    uint192 nativeFee;
    uint192 linkFee;
    uint32 expiresAt;
    int192 price;
    int192 bid;
    int192 ask;
}

Properties

NameTypeDescription
feedIdbytes32The stream ID the report has data for.
validFromTimestampuint32The earliest timestamp for which price is applicable.
observationsTimestampuint32The latest timestamp for which price is applicable.
nativeFeeuint192The base cost to validate a transaction using the report, denominated in the chain’s native token (e.g., WETH/ETH).
linkFeeuint192The base cost to validate a transaction using the report, denominated in LINK.
expiresAtuint32The latest timestamp where the report can be verified onchain.
priceint192The DON consensus median price (8 or 18 decimals).
bidint192The simulated price impact of a buy order up to the X% depth of liquidity usage (8 or 18 decimals).
askint192The simulated price impact of a sell order up to the X% depth of liquidity usage (8 or 18 decimals).

Contents

IBaseRebalancer

Git Source

Functions

getCurrentStateData

Returns the necessary data for the USDN protocol to update the position.

function getCurrentStateData()
    external
    view
    returns (uint128 pendingAssets_, uint256 maxLeverage_, Types.PositionId memory currentPosId_);

Returns

NameTypeDescription
pendingAssets_uint128The amount of assets that are pending inclusion in the protocol.
maxLeverage_uint256The maximum leverage of the rebalancer.
currentPosId_Types.PositionIdThe ID of the current position (tick == NO_POSITION_TICK if no position).

getMinAssetDeposit

Returns the minimum amount of assets a user can deposit in the rebalancer.

function getMinAssetDeposit() external view returns (uint256 minAssetDeposit_);

Returns

NameTypeDescription
minAssetDeposit_uint256The minimum amount of assets that can be deposited by a user.

getUserDepositData

Returns the data regarding the assets deposited by the provided user.

function getUserDepositData(address user) external view returns (IRebalancerTypes.UserDeposit memory data_);

Parameters

NameTypeDescription
useraddressThe address of the user.

Returns

NameTypeDescription
data_IRebalancerTypes.UserDepositThe data regarding the assets deposited by the provided user.

updatePosition

Indicates that the previous version of the position was closed and a new one was opened.

If previousPosValue equals 0, it means the previous version got liquidated.

function updatePosition(Types.PositionId calldata newPosId, uint128 previousPosValue) external;

Parameters

NameTypeDescription
newPosIdTypes.PositionIdThe position ID of the new position.
previousPosValueuint128The amount of assets left in the previous position.

setMinAssetDeposit

Sets the minimum amount of assets to be deposited by a user.

The new minimum amount must be greater than or equal to the minimum long position of the USDN protocol. This function can only be called by the owner or the USDN protocol.

function setMinAssetDeposit(uint256 minAssetDeposit) external;

Parameters

NameTypeDescription
minAssetDeposituint256The new minimum amount of assets to be deposited.

IRebalancer

Git Source

Inherits: IBaseRebalancer, IRebalancerErrors, IRebalancerEvents, IRebalancerTypes

Functions

MULTIPLIER_FACTOR

Gets the value of the multiplier at 1x.

Also helps to normalize the result of multiplier calculations.

function MULTIPLIER_FACTOR() external view returns (uint256 factor_);

Returns

NameTypeDescription
factor_uint256The multiplier factor.

MAX_ACTION_COOLDOWN

The maximum cooldown time between actions.

function MAX_ACTION_COOLDOWN() external view returns (uint256 cooldown_);

Returns

NameTypeDescription
cooldown_uint256The maximum cooldown time between actions.

INITIATE_CLOSE_TYPEHASH

The EIP712 initiateClosePosition typehash.

By including this hash into the EIP712 message for this domain, this can be used together with ECDSA-recover to obtain the signer of a message.

function INITIATE_CLOSE_TYPEHASH() external view returns (bytes32 typehash_);

Returns

NameTypeDescription
typehash_bytes32The EIP712 initiateClosePosition typehash.

MAX_CLOSE_DELAY

Gets the maximum amount of seconds to wait to execute a initiateClosePosition since a new rebalancer long position has been created.

function MAX_CLOSE_DELAY() external view returns (uint256 closeDelay_);

Returns

NameTypeDescription
closeDelay_uint256The max close delay value.

getAsset

Returns the address of the asset used by the USDN protocol.

function getAsset() external view returns (IERC20Metadata asset_);

Returns

NameTypeDescription
asset_IERC20MetadataThe address of the asset used by the USDN protocol.

getUsdnProtocol

Returns the address of the USDN protocol.

function getUsdnProtocol() external view returns (IUsdnProtocol protocol_);

Returns

NameTypeDescription
protocol_IUsdnProtocolThe address of the USDN protocol.

getPositionVersion

Returns the version of the current position (0 means no position open).

function getPositionVersion() external view returns (uint128 version_);

Returns

NameTypeDescription
version_uint128The version of the current position.

getPositionMaxLeverage

Returns the maximum leverage the rebalancer position can have.

In some edge cases during the calculation of the rebalancer position's tick, this value might be exceeded by a slight margin.

Returns the max leverage of the USDN Protocol if it's lower than the rebalancer's.

function getPositionMaxLeverage() external view returns (uint256 maxLeverage_);

Returns

NameTypeDescription
maxLeverage_uint256The maximum leverage.

getPendingAssetsAmount

Returns the amount of assets deposited and waiting for the next version to be opened.

function getPendingAssetsAmount() external view returns (uint128 pendingAssetsAmount_);

Returns

NameTypeDescription
pendingAssetsAmount_uint128The amount of pending assets.

getPositionData

Returns the data of the provided version of the position.

function getPositionData(uint128 version) external view returns (PositionData memory positionData_);

Parameters

NameTypeDescription
versionuint128The version of the position.

Returns

NameTypeDescription
positionData_PositionDataThe data for the provided version of the position.

getTimeLimits

Gets the time limits for the action validation process.

function getTimeLimits() external view returns (TimeLimits memory timeLimits_);

Returns

NameTypeDescription
timeLimits_TimeLimitsThe time limits.

increaseAssetAllowance

Increases the allowance of assets for the USDN protocol spender by addAllowance.

function increaseAssetAllowance(uint256 addAllowance) external;

Parameters

NameTypeDescription
addAllowanceuint256Amount to add to the allowance of the USDN Protocol.

getLastLiquidatedVersion

Returns the version of the last position that got liquidated.

0 means no liquidated version yet.

function getLastLiquidatedVersion() external view returns (uint128 version_);

Returns

NameTypeDescription
version_uint128The version of the last position that got liquidated.

getNonce

Gets the nonce a user can use to generate a delegation signature.

This is to prevent replay attacks when using an EIP712 delegation signature.

function getNonce(address user) external view returns (uint256 nonce_);

Parameters

NameTypeDescription
useraddressThe user address of the deposited amount in the rebalancer.

Returns

NameTypeDescription
nonce_uint256The user's nonce.

domainSeparatorV4

Gets the domain separator v4 used for EIP-712 signatures.

function domainSeparatorV4() external view returns (bytes32 domainSeparator_);

Returns

NameTypeDescription
domainSeparator_bytes32The domain separator v4.

getCloseLockedUntil

Gets the timestamp by which a user must wait to perform a initiateClosePosition.

function getCloseLockedUntil() external view returns (uint256 timestamp_);

Returns

NameTypeDescription
timestamp_uint256The timestamp until which the position cannot be closed.

initiateDepositAssets

Deposits assets into this contract to be included in the next position after validation

The user must call validateDepositAssets between _timeLimits.validationDelay and. _timeLimits.validationDeadline seconds after this action.

function initiateDepositAssets(uint88 amount, address to) external;

Parameters

NameTypeDescription
amountuint88The amount in assets that will be deposited into the rebalancer.
toaddressThe address which will need to validate and which will own the position.

validateDepositAssets

Validates a deposit to be included in the next position version.

The to from the initiateDepositAssets must call this function between _timeLimits.validationDelay and _timeLimits.validationDeadline seconds after the initiate action. After that, the user must wait until _timeLimits.actionCooldown seconds has elapsed, and then can call resetDepositAssets to retrieve their assets.

function validateDepositAssets() external;

resetDepositAssets

Retrieves the assets for a failed deposit due to waiting too long before calling validateDepositAssets.

The user must wait _timeLimits.actionCooldown since the initiateDepositAssets before calling this function.

function resetDepositAssets() external;

initiateWithdrawAssets

Withdraws assets that were not yet included in a position.

The user must call validateWithdrawAssets between _timeLimits.validationDelay and _timeLimits.validationDeadline seconds after this action.

function initiateWithdrawAssets() external;

validateWithdrawAssets

Validates a withdrawal of assets that were not yet included in a position.

The user must call this function between _timeLimits.validationDelay and _timeLimits.validationDeadline seconds after initiateWithdrawAssets. After that, the user must wait until the cooldown has elapsed, and then can call initiateWithdrawAssets again or wait to be included in the next position.

function validateWithdrawAssets(uint88 amount, address to) external;

Parameters

NameTypeDescription
amountuint88The amount of assets to withdraw.
toaddressThe recipient of the assets.

initiateClosePosition

Closes the provided amount from the current rebalancer's position.

The rebalancer allows partially closing its position to withdraw the user's assets + PnL. The remaining amount needs to be above _minAssetDeposit. The validator is always the msg.sender, which means the user must call validateClosePosition on the protocol side after calling this function.

function initiateClosePosition(
    uint88 amount,
    address to,
    address payable validator,
    uint256 userMinPrice,
    uint256 deadline,
    bytes calldata currentPriceData,
    Types.PreviousActionsData calldata previousActionsData,
    bytes calldata delegationData
) external payable returns (Types.LongActionOutcome outcome_);

Parameters

NameTypeDescription
amountuint88The amount to close relative to the amount deposited.
toaddressThe recipient of the assets.
validatoraddress payableThe address that should validate the open position.
userMinPriceuint256The minimum price at which the position can be closed.
deadlineuint256The deadline of the close position to be initiated.
currentPriceDatabytesThe current price data.
previousActionsDataTypes.PreviousActionsDataThe data needed to validate actionable pending actions.
delegationDatabytesAn optional delegation data that include the depositOwner and an EIP712 signature to provide when closing a position on the owner's behalf. If used, it needs to be encoded with abi.encode(depositOwner, abi.encodePacked(r, s, v)).

Returns

NameTypeDescription
outcome_Types.LongActionOutcomeThe outcome of the UsdnProtocol's initiateClosePosition call, check initiateClosePosition for more details.

setPositionMaxLeverage

Updates the max leverage a position can have.

newMaxLeverage must be between the min and max leverage of the USDN protocol. This function can only be called by the owner of the contract.

function setPositionMaxLeverage(uint256 newMaxLeverage) external;

Parameters

NameTypeDescription
newMaxLeverageuint256The new max leverage.

setTimeLimits

Sets the various time limits in seconds.

This function can only be called by the owner of the contract.

function setTimeLimits(uint64 validationDelay, uint64 validationDeadline, uint64 actionCooldown, uint64 closeDelay)
    external;

Parameters

NameTypeDescription
validationDelayuint64The amount of time to wait before an initiate can be validated.
validationDeadlineuint64The amount of time a user has to validate an initiate.
actionCooldownuint64The amount of time to wait after the deadline has passed before trying again.
closeDelayuint64The close delay that will be applied to the next long position opening.

IRebalancerErrors

Git Source

Defines all custom errors thrown by the Rebalancer contract.

Errors

RebalancerUserPending

The user's assets are not used in a position.

error RebalancerUserPending();

RebalancerUserLiquidated

The user's assets were in a position that has been liquidated.

error RebalancerUserLiquidated();

RebalancerInvalidAddressTo

The to address is invalid.

error RebalancerInvalidAddressTo();

RebalancerInvalidAmount

The amount of assets is invalid.

error RebalancerInvalidAmount();

RebalancerInsufficientAmount

The amount to deposit is insufficient.

error RebalancerInsufficientAmount();

RebalancerInvalidMaxLeverage

The given maximum leverage is invalid.

error RebalancerInvalidMaxLeverage();

RebalancerInvalidMinAssetDeposit

The given minimum asset deposit is invalid.

error RebalancerInvalidMinAssetDeposit();

RebalancerInvalidTimeLimits

The given time limits are invalid.

error RebalancerInvalidTimeLimits();

RebalancerUnauthorized

The caller is not authorized to perform the action.

error RebalancerUnauthorized();

RebalancerDepositUnauthorized

The user can't initiate or validate a deposit at this time.

error RebalancerDepositUnauthorized();

RebalancerActionNotValidated

The user must validate their deposit or withdrawal.

error RebalancerActionNotValidated();

RebalancerNoPendingAction

The user has no pending deposit or withdrawal requiring validation.

error RebalancerNoPendingAction();

RebalancerValidateTooEarly

Ton was attempted too early, the user must wait for _timeLimits.validationDelay.

error RebalancerValidateTooEarly();

RebalancerActionCooldown

Ton was attempted too late, the user must wait for _timeLimits.actionCooldown.

error RebalancerActionCooldown();

RebalancerWithdrawalUnauthorized

The user can't initiate or validate a withdrawal at this time.

error RebalancerWithdrawalUnauthorized();

RebalancerEtherRefundFailed

The address was unable to accept the Ether refund.

error RebalancerEtherRefundFailed();

RebalancerInvalidDelegationSignature

The signature provided for delegation is invalid.

error RebalancerInvalidDelegationSignature();

RebalancerCloseLockedUntil

The user can't initiate a close position until the given timestamp has passed.

error RebalancerCloseLockedUntil(uint256 closeLockedUntil);

Parameters

NameTypeDescription
closeLockedUntiluint256The timestamp until which the user must wait to perform a close position action.

IRebalancerEvents

Git Source

Defines all custom events emitted by the Rebalancer contract.

Events

InitiatedAssetsDeposit

A user initiates a deposit into the Rebalancer.

event InitiatedAssetsDeposit(address indexed payer, address indexed to, uint256 amount, uint256 timestamp);

Parameters

NameTypeDescription
payeraddressThe address of the user initiating the deposit.
toaddressThe address the assets will be assigned to.
amountuint256The amount of assets deposited.
timestampuint256The timestamp of the action.

AssetsDeposited

Assets are successfully deposited into the contract.

event AssetsDeposited(address indexed user, uint256 amount, uint256 positionVersion);

Parameters

NameTypeDescription
useraddressThe address of the user.
amountuint256The amount of assets deposited.
positionVersionuint256The version of the position in which the assets will be used.

DepositRefunded

A deposit is refunded after failing to meet the validation deadline.

event DepositRefunded(address indexed user, uint256 amount);

Parameters

NameTypeDescription
useraddressThe address of the user.
amountuint256The amount of assets refunded.

InitiatedAssetsWithdrawal

A user initiates the withdrawal of their pending assets.

event InitiatedAssetsWithdrawal(address indexed user);

Parameters

NameTypeDescription
useraddressThe address of the user.

AssetsWithdrawn

Pending assets are withdrawn from the contract.

event AssetsWithdrawn(address indexed user, address indexed to, uint256 amount);

Parameters

NameTypeDescription
useraddressThe original owner of the position.
toaddressThe address the assets are sent to.
amountuint256The amount of assets withdrawn.

ClosePositionInitiated

A user initiates a close position action through the rebalancer.

event ClosePositionInitiated(
    address indexed user, uint256 rebalancerAmountToClose, uint256 amountToClose, uint256 rebalancerAmountRemaining
);

Parameters

NameTypeDescription
useraddressThe address of the rebalancer user.
rebalancerAmountToCloseuint256The amount of rebalancer assets to close.
amountToCloseuint256The amount to close, taking into account the previous versions PnL.
rebalancerAmountRemaininguint256The remaining rebalancer assets of the user.

PositionMaxLeverageUpdated

The maximum leverage is updated.

event PositionMaxLeverageUpdated(uint256 newMaxLeverage);

Parameters

NameTypeDescription
newMaxLeverageuint256The updated value for the maximum leverage.

MinAssetDepositUpdated

The minimum asset deposit requirement is updated.

event MinAssetDepositUpdated(uint256 minAssetDeposit);

Parameters

NameTypeDescription
minAssetDeposituint256The updated minimum amount of assets to be deposited by a user.

PositionVersionUpdated

The position version is updated.

event PositionVersionUpdated(
    uint128 newPositionVersion, uint256 entryAccMultiplier, uint128 amount, Types.PositionId positionId
);

Parameters

NameTypeDescription
newPositionVersionuint128The updated version of the position.
entryAccMultiplieruint256The accumulated multiplier at the opening of the new version.
amountuint128The amount of assets injected into the position as collateral by the rebalancer.
positionIdTypes.PositionIdThe ID of the new position in the USDN protocol.

TimeLimitsUpdated

Time limits are updated.

event TimeLimitsUpdated(
    uint256 validationDelay, uint256 validationDeadline, uint256 actionCooldown, uint256 closeDelay
);

Parameters

NameTypeDescription
validationDelayuint256The updated validation delay.
validationDeadlineuint256The updated validation deadline.
actionCooldownuint256The updated action cooldown.
closeDelayuint256The updated close delay.

IRebalancerTypes

Git Source

Defines all custom types used by the Rebalancer contract.

Structs

UserDeposit

Represents the deposit data of a user.

A value of zero for initiateTimestamp indicates that the deposit or withdrawal has been validated.

struct UserDeposit {
    uint40 initiateTimestamp;
    uint88 amount;
    uint128 entryPositionVersion;
}

Properties

NameTypeDescription
initiateTimestampuint40The timestamp when the deposit or withdrawal was initiated.
amountuint88The amount of assets deposited by the user.
entryPositionVersionuint128The version of the position the user entered.

PositionData

Represents data for a specific version of a position.

The difference between amount here and the amount saved in the USDN protocol is the liquidation bonus.

struct PositionData {
    uint128 amount;
    int24 tick;
    uint256 tickVersion;
    uint256 index;
    uint256 entryAccMultiplier;
}

Properties

NameTypeDescription
amountuint128The amount of assets used as collateral to open the position.
tickint24The tick of the position.
tickVersionuint256The version of the tick.
indexuint256The index of the position in the tick list.
entryAccMultiplieruint256The accumulated PnL multiplier of all positions up to this one.

TimeLimits

Defines parameters related to the validation process for rebalancer deposits and withdrawals.

If validationDeadline has passed, the user must wait until the cooldown duration has elapsed. Then, for deposit actions, the user must retrieve its funds using resetDepositAssets. For withdrawal actions, the user can simply initiate a new withdrawal.

struct TimeLimits {
    uint64 validationDelay;
    uint64 validationDeadline;
    uint64 actionCooldown;
    uint64 closeDelay;
}

Properties

NameTypeDescription
validationDelayuint64The minimum duration in seconds between an initiate action and the corresponding validate action.
validationDeadlineuint64The maximum duration in seconds between an initiate action and the corresponding validate action.
actionCooldownuint64The duration in seconds from the initiate action during which the user can't interact with the rebalancer if the validationDeadline is exceeded.
closeDelayuint64The Duration in seconds from the last rebalancer long position opening during which the user can't perform an initiateClosePosition.

Contents

IRebaseCallback

Git Source

Functions

rebaseCallback

Called by the USDN token after a rebase has happened.

function rebaseCallback(uint256 oldDivisor, uint256 newDivisor) external returns (bytes memory result_);

Parameters

NameTypeDescription
oldDivisoruint256The value of the divisor before the rebase.
newDivisoruint256The value of the divisor after the rebase (necessarily smaller than oldDivisor).

Returns

NameTypeDescription
result_bytesArbitrary data that will be forwarded to the caller of rebase.

IUsdn

Git Source

Inherits: IERC20, IERC20Metadata, IERC20Permit, IUsdnEvents, IUsdnErrors

Implements the ERC-20 token standard as well as the EIP-2612 permit extension. Additional functions related to the specifics of this token are included below.

Functions

totalShares

Returns the total number of shares in existence.

function totalShares() external view returns (uint256 shares_);

Returns

NameTypeDescription
shares_uint256The number of shares.

sharesOf

Returns the number of shares owned by account.

function sharesOf(address account) external view returns (uint256 shares_);

Parameters

NameTypeDescription
accountaddressThe account to query.

Returns

NameTypeDescription
shares_uint256The number of shares.

transferShares

Transfers a given amount of shares from the msg.sender to to.

function transferShares(address to, uint256 value) external returns (bool success_);

Parameters

NameTypeDescription
toaddressRecipient of the shares.
valueuint256Number of shares to transfer.

Returns

NameTypeDescription
success_boolIndicates whether the transfer was successfully executed.

transferSharesFrom

Transfers a given amount of shares from the from to to.

There should be sufficient allowance for the spender. Be mindful of the rebase logic. The allowance is in tokens. So, after a rebase, the same amount of shares will be worth a higher amount of tokens. In that case, the allowance of the initial approval will not be enough to transfer the new amount of tokens. This can also happen when your transaction is in the mempool and the rebase happens before your transaction. Also note that the amount of tokens deduced from the allowance is rounded up, so the convertToTokensRoundUp function should be used when converting shares into an allowance value.

function transferSharesFrom(address from, address to, uint256 value) external returns (bool success_);

Parameters

NameTypeDescription
fromaddressThe owner of the shares.
toaddressRecipient of the shares.
valueuint256Number of shares to transfer.

Returns

NameTypeDescription
success_boolIndicates whether the transfer was successfully executed.

mint

Mints new shares, providing a token value.

Caller must have the MINTER_ROLE.

function mint(address to, uint256 amount) external;

Parameters

NameTypeDescription
toaddressAccount to receive the new shares.
amountuint256Amount of tokens to mint, is internally converted to the proper shares amounts.

mintShares

Mints new shares, providing a share value.

Caller must have the MINTER_ROLE.

function mintShares(address to, uint256 amount) external returns (uint256 mintedTokens_);

Parameters

NameTypeDescription
toaddressAccount to receive the new shares.
amountuint256Amount of shares to mint.

Returns

NameTypeDescription
mintedTokens_uint256Amount of tokens that were minted (informational).

burn

Destroys a value amount of tokens from the caller, reducing the total supply.

function burn(uint256 value) external;

Parameters

NameTypeDescription
valueuint256Amount of tokens to burn, is internally converted to the proper shares amounts.

burnFrom

Destroys a value amount of tokens from account, deducting from the caller's allowance.

function burnFrom(address account, uint256 value) external;

Parameters

NameTypeDescription
accountaddressAccount to burn tokens from.
valueuint256Amount of tokens to burn, is internally converted to the proper shares amounts.

burnShares

Destroys a value amount of shares from the caller, reducing the total supply.

function burnShares(uint256 value) external;

Parameters

NameTypeDescription
valueuint256Amount of shares to burn.

burnSharesFrom

Destroys a value amount of shares from account, deducting from the caller's allowance.

There should be sufficient allowance for the spender. Be mindful of the rebase logic. The allowance is in tokens. So, after a rebase, the same amount of shares will be worth a higher amount of tokens. In that case, the allowance of the initial approval will not be enough to transfer the new amount of tokens. This can also happen when your transaction is in the mempool and the rebase happens before your transaction. Also note that the amount of tokens deduced from the allowance is rounded up, so the convertToTokensRoundUp function should be used when converting shares into an allowance value.

function burnSharesFrom(address account, uint256 value) external;

Parameters

NameTypeDescription
accountaddressAccount to burn shares from.
valueuint256Amount of shares to burn.

convertToShares

Converts a number of tokens to the corresponding amount of shares.

The conversion reverts with UsdnMaxTokensExceeded if the corresponding amount of shares overflows.

function convertToShares(uint256 amountTokens) external view returns (uint256 shares_);

Parameters

NameTypeDescription
amountTokensuint256The amount of tokens to convert to shares.

Returns

NameTypeDescription
shares_uint256The corresponding amount of shares.

convertToTokens

Converts a number of shares to the corresponding amount of tokens.

The conversion never overflows as we are performing a division. The conversion rounds to the nearest amount of tokens that minimizes the error when converting back to shares.

function convertToTokens(uint256 amountShares) external view returns (uint256 tokens_);

Parameters

NameTypeDescription
amountSharesuint256The amount of shares to convert to tokens.

Returns

NameTypeDescription
tokens_uint256The corresponding amount of tokens.

convertToTokensRoundUp

Converts a number of shares to the corresponding amount of tokens, rounding up.

Use this function to determine the amount of a token approval, as we always round up when deducting from a token transfer allowance.

function convertToTokensRoundUp(uint256 amountShares) external view returns (uint256 tokens_);

Parameters

NameTypeDescription
amountSharesuint256The amount of shares to convert to tokens.

Returns

NameTypeDescription
tokens_uint256The corresponding amount of tokens, rounded up.

maxTokens

Returns the current maximum tokens supply, given the current divisor.

This function is used to check if a conversion operation would overflow.

function maxTokens() external view returns (uint256 maxTokens_);

Returns

NameTypeDescription
maxTokens_uint256The maximum number of tokens that can exist.

rebase

Decreases the global divisor, which effectively grows all balances and the total supply.

If the provided divisor is larger than or equal to the current divisor value, no rebase will happen If the new divisor is smaller than MIN_DIVISOR, the value will be clamped to MIN_DIVISOR. Caller must have the REBASER_ROLE.

function rebase(uint256 newDivisor)
    external
    returns (bool rebased_, uint256 oldDivisor_, bytes memory callbackResult_);

Parameters

NameTypeDescription
newDivisoruint256The new divisor, should be strictly smaller than the current one and greater or equal to MIN_DIVISOR.

Returns

NameTypeDescription
rebased_boolWhether a rebase happened.
oldDivisor_uint256The previous value of the divisor.
callbackResult_bytesThe result of the callback, if a rebase happened and a callback handler is defined.

setRebaseHandler

Sets the rebase handler address.

Emits a RebaseHandlerUpdated event. If set to the zero address, no handler will be called after a rebase. Caller must have the DEFAULT_ADMIN_ROLE.

function setRebaseHandler(IRebaseCallback newHandler) external;

Parameters

NameTypeDescription
newHandlerIRebaseCallbackThe new handler address.

divisor

Gets the current value of the divisor that converts between tokens and shares.

function divisor() external view returns (uint256 divisor_);

Returns

NameTypeDescription
divisor_uint256The current divisor.

rebaseHandler

Gets the rebase handler address, which is called whenever a rebase happens.

function rebaseHandler() external view returns (IRebaseCallback rebaseHandler_);

Returns

NameTypeDescription
rebaseHandler_IRebaseCallbackThe rebase handler address.

MINTER_ROLE

Gets the minter role signature.

function MINTER_ROLE() external pure returns (bytes32 minter_role_);

Returns

NameTypeDescription
minter_role_bytes32The role signature.

REBASER_ROLE

Gets the rebaser role signature.

function REBASER_ROLE() external pure returns (bytes32 rebaser_role_);

Returns

NameTypeDescription
rebaser_role_bytes32The role signature.

MAX_DIVISOR

Gets the maximum value of the divisor, which is also the initial value.

function MAX_DIVISOR() external pure returns (uint256 maxDivisor_);

Returns

NameTypeDescription
maxDivisor_uint256The maximum divisor.

MIN_DIVISOR

Gets the minimum acceptable value of the divisor.

The minimum divisor that can be set. This corresponds to a growth of 1B times. Technically, 1e5 would still work without precision errors.

function MIN_DIVISOR() external pure returns (uint256 minDivisor_);

Returns

NameTypeDescription
minDivisor_uint256The minimum divisor.

IUsdnErrors

Git Source

Defines all custom errors emitted by the USDN token contract.

Errors

UsdnMaxTokensExceeded

The amount of tokens exceeds the maximum allowed limit.

error UsdnMaxTokensExceeded(uint256 value);

Parameters

NameTypeDescription
valueuint256The invalid token value.

UsdnInsufficientSharesBalance

The sender's share balance is insufficient.

error UsdnInsufficientSharesBalance(address sender, uint256 balance, uint256 needed);

Parameters

NameTypeDescription
senderaddressThe sender's address.
balanceuint256The current share balance of the sender.
neededuint256The required amount of shares for the transfer.

UsdnInvalidDivisor

The divisor value in storage is invalid (< 1).

error UsdnInvalidDivisor();

UsdnRebaseNotSupported

The current implementation does not allow rebasing.

error UsdnRebaseNotSupported();

IUsdnEvents

Git Source

Defines all custom events emitted by the USDN token contract.

Events

Rebase

The divisor was updated, emitted during a rebase.

event Rebase(uint256 oldDivisor, uint256 newDivisor);

Parameters

NameTypeDescription
oldDivisoruint256The divisor value before the rebase.
newDivisoruint256The new divisor value.

RebaseHandlerUpdated

The rebase handler address was updated.

The rebase handler is a contract that is called when a rebase occurs.

event RebaseHandlerUpdated(IRebaseCallback newHandler);

Parameters

NameTypeDescription
newHandlerIRebaseCallbackThe address of the new rebase handler contract.

IWusdn

Git Source

Inherits: IERC20Metadata, IERC20Permit, IWusdnEvents, IWusdnErrors

Interface for the Wrapped Ultimate Synthetic Delta Neutral (WUSDN) token.

Functions

USDN

Returns the address of the USDN token.

function USDN() external view returns (IUsdn);

Returns

NameTypeDescription
<none>IUsdnThe address of the USDN token.

SHARES_RATIO

Returns the ratio used to convert USDN shares to WUSDN amounts.

This ratio is initialized in the constructor based on the maximum divisor of the USDN token.

function SHARES_RATIO() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The conversion ratio between USDN shares and WUSDN amounts.

wrap

Wraps a given amount of USDN into WUSDN.

This function may use slightly less than usdnAmount due to rounding errors. For a more precise operation, use wrapShares.

function wrap(uint256 usdnAmount) external returns (uint256 wrappedAmount_);

Parameters

NameTypeDescription
usdnAmountuint256The amount of USDN to wrap.

Returns

NameTypeDescription
wrappedAmount_uint256The amount of WUSDN received.

wrap

Wraps a given amount of USDN into WUSDN and sends it to a specified address.

This function may use slightly less than usdnAmount due to rounding errors. For a more precise operation, use wrapShares.

function wrap(uint256 usdnAmount, address to) external returns (uint256 wrappedAmount_);

Parameters

NameTypeDescription
usdnAmountuint256The amount of USDN to wrap.
toaddressThe address to receive the WUSDN.

Returns

NameTypeDescription
wrappedAmount_uint256The amount of WUSDN received.

wrapShares

Wraps a given amount of USDN shares into WUSDN and sends it to a specified address.

function wrapShares(uint256 usdnShares, address to) external returns (uint256 wrappedAmount_);

Parameters

NameTypeDescription
usdnSharesuint256The amount of USDN shares to wrap.
toaddressThe address to receive the WUSDN.

Returns

NameTypeDescription
wrappedAmount_uint256The amount of WUSDN received.

unwrap

Unwraps a given amount of WUSDN into USDN.

function unwrap(uint256 wusdnAmount) external returns (uint256 usdnAmount_);

Parameters

NameTypeDescription
wusdnAmountuint256The amount of WUSDN to unwrap.

Returns

NameTypeDescription
usdnAmount_uint256The amount of USDN received.

unwrap

Unwraps a given amount of WUSDN into USDN and sends it to a specified address.

function unwrap(uint256 wusdnAmount, address to) external returns (uint256 usdnAmount_);

Parameters

NameTypeDescription
wusdnAmountuint256The amount of WUSDN to unwrap.
toaddressThe address to receive the USDN.

Returns

NameTypeDescription
usdnAmount_uint256The amount of USDN received.

previewWrap

Computes the amount of WUSDN that would be received for a given amount of USDN.

The actual amount received may differ slightly due to rounding errors. For a precise value, use previewWrapShares.

function previewWrap(uint256 usdnAmount) external view returns (uint256 wrappedAmount_);

Parameters

NameTypeDescription
usdnAmountuint256The amount of USDN to wrap.

Returns

NameTypeDescription
wrappedAmount_uint256The estimated amount of WUSDN that would be received.

previewWrapShares

Computes the amount of WUSDN that would be received for a given amount of USDN shares.

function previewWrapShares(uint256 usdnShares) external view returns (uint256 wrappedAmount_);

Parameters

NameTypeDescription
usdnSharesuint256The amount of USDN shares to wrap.

Returns

NameTypeDescription
wrappedAmount_uint256The amount of WUSDN that would be received.

redemptionRate

Returns the exchange rate between WUSDN and USDN.

function redemptionRate() external view returns (uint256 usdnAmount_);

Returns

NameTypeDescription
usdnAmount_uint256The amount of USDN that corresponds to 1 WUSDN.

previewUnwrap

Computes the amount of USDN that would be received for a given amount of WUSDN.

The actual amount received may differ slightly due to rounding errors. For a precise value, use previewUnwrapShares.

function previewUnwrap(uint256 wusdnAmount) external view returns (uint256 usdnAmount_);

Parameters

NameTypeDescription
wusdnAmountuint256The amount of WUSDN to unwrap.

Returns

NameTypeDescription
usdnAmount_uint256The estimated amount of USDN that would be received.

previewUnwrapShares

Computes the amount of USDN shares that would be received for a given amount of WUSDN.

function previewUnwrapShares(uint256 wusdnAmount) external view returns (uint256 usdnSharesAmount_);

Parameters

NameTypeDescription
wusdnAmountuint256The amount of WUSDN to unwrap.

Returns

NameTypeDescription
usdnSharesAmount_uint256The amount of USDN shares that would be received.

totalUsdnBalance

Returns the total amount of USDN held by the contract.

function totalUsdnBalance() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The total amount of USDN held by the contract.

totalUsdnShares

Returns the total amount of USDN shares held by the contract.

function totalUsdnShares() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The total amount of USDN shares held by the contract.

IWusdnErrors

Git Source

Defines all custom errors emitted by the WUSDN token contract.

Errors

WusdnInsufficientBalance

The user has insufficient USDN balance to wrap the given usdnAmount.

error WusdnInsufficientBalance(uint256 usdnAmount);

Parameters

NameTypeDescription
usdnAmountuint256The amount of USDN the user attempted to wrap.

WusdnWrapZeroAmount

The user is attempting to wrap an amount of USDN shares that is lower than the minimum: SHARES_RATIO, required by the WUSDN token. This results in a wrapped amount of zero WUSDN.

error WusdnWrapZeroAmount();

IWusdnEvents

Git Source

Defines all custom events emitted by the WUSDN token contract.

Events

Wrap

The user wrapped USDN to mint WUSDN tokens.

event Wrap(address indexed from, address indexed to, uint256 usdnAmount, uint256 wusdnAmount);

Parameters

NameTypeDescription
fromaddressThe address of the user who wrapped the USDN.
toaddressThe address of the recipient who received the WUSDN tokens.
usdnAmountuint256The amount of USDN tokens wrapped.
wusdnAmountuint256The amount of WUSDN tokens minted.

Unwrap

The user unwrapped WUSDN tokens to redeem USDN.

event Unwrap(address indexed from, address indexed to, uint256 wusdnAmount, uint256 usdnAmount);

Parameters

NameTypeDescription
fromaddressThe address of the user who unwrapped the WUSDN tokens.
toaddressThe address of the recipient who received the USDN tokens.
wusdnAmountuint256The amount of WUSDN tokens unwrapped.
usdnAmountuint256The amount of USDN tokens redeemed.

Contents

IFeeCollectorCallback

Git Source

Inherits: IERC165

Interface for a fee collector contract to receive callbacks from the USDN protocol upon fee collection.

Implementing contracts must support the ERC-165 interface detection mechanism.

Functions

feeCollectorCallback

Called by the USDN protocol on the fee collector contract when the fee threshold is reached.

function feeCollectorCallback(uint256 feeAmount) external;

Parameters

NameTypeDescription
feeAmountuint256The amount of the fee that was transferred to the fee collector.

IOwnershipCallback

Git Source

Inherits: IERC165

This interface can be implemented by contracts that wish to be notified when they become owner of a USDN protocol position.

The contract must implement the ERC-165 interface detection mechanism.

Functions

ownershipCallback

Called by the USDN protocol on the new position owner after an ownership transfer occurs.

Implementers can use this callback to perform actions triggered by the ownership change.

function ownershipCallback(address oldOwner, Types.PositionId calldata posId) external;

Parameters

NameTypeDescription
oldOwneraddressThe address of the previous position owner.
posIdTypes.PositionIdThe unique position identifier.

IPaymentCallback

Git Source

Inherits: IERC165

This interface can be implemented by contracts that wish to transfer tokens during initiate actions.

The contract must implement the ERC-165 interface detection mechanism.

Functions

transferCallback

Triggered by the USDN protocol to transfer asset tokens during initiate actions.

Implementations must ensure that the msg.sender is the USDN protocol for security purposes.

function transferCallback(IERC20Metadata token, uint256 amount, address to) external;

Parameters

NameTypeDescription
tokenIERC20MetadataThe address of the ERC20 token to be transferred.
amountuint256The amount of tokens to transfer.
toaddressThe recipient's address.

usdnTransferCallback

Triggered by the USDN protocol during the initiateWithdrawal process to transfer USDN shares.

Implementations must verify that the msg.sender is the USDN protocol.

function usdnTransferCallback(IUsdn usdn, uint256 shares) external;

Parameters

NameTypeDescription
usdnIUsdnThe address of the USDN protocol.
sharesuint256The number of USDN shares to transfer to the protocol (msg.sender).

IUsdnProtocol

Git Source

Inherits: IUsdnProtocolImpl, IUsdnProtocolFallback, IUsdnProtocolErrors, IUsdnProtocolEvents

Interface for the USDN protocol and fallback.

Functions

upgradeToAndCall

Upgrades the protocol to a new implementation (check UUPSUpgradeable).

This function should be called by the role with the PROXY_UPGRADE_ROLE.

function upgradeToAndCall(address newImplementation, bytes calldata data) external payable;

Parameters

NameTypeDescription
newImplementationaddressThe address of the new implementation.
databytesThe data to call when upgrading to the new implementation. Passing in empty data skips the delegatecall to newImplementation.

IUsdnProtocolActions

Git Source

Inherits: IUsdnProtocolTypes

Interface for the USDN Protocol Actions.

Functions

initiateOpenPosition

Initiates an open position action.

Consult the current oracle middleware for price data format and possible oracle fee. Requires _securityDepositValue to be included in the transaction value. In case of pending liquidations, this function will not initiate the position (isInitiated_ would be false). The user's input for price and leverage is not guaranteed due to the price difference between the initiate and validate actions.

function initiateOpenPosition(
    uint128 amount,
    uint128 desiredLiqPrice,
    uint128 userMaxPrice,
    uint256 userMaxLeverage,
    address to,
    address payable validator,
    uint256 deadline,
    bytes calldata currentPriceData,
    PreviousActionsData calldata previousActionsData
) external payable returns (bool isInitiated_, PositionId memory posId_);

Parameters

NameTypeDescription
amountuint128The amount of assets to deposit.
desiredLiqPriceuint128The desired liquidation price, including the penalty.
userMaxPriceuint128The user's wanted maximum price at which the position can be opened.
userMaxLeverageuint256The user's wanted maximum leverage for the new position.
toaddressThe address that will owns of the position.
validatoraddress payableThe address that is supposed to validate the opening and receive the security deposit. If not an EOA, it must be a contract that implements a receive function.
deadlineuint256The deadline for initiating the open position.
currentPriceDatabytesThe price data used for temporary leverage and entry price computations.
previousActionsDataPreviousActionsDataThe data needed to validate actionable pending actions.

Returns

NameTypeDescription
isInitiated_boolWhether the position was successfully initiated. If false, the security deposit was refunded
posId_PositionIdThe unique position identifier. If the position was not initiated, the tick number will be NO_POSITION_TICK.

validateOpenPosition

Validates a pending open position action.

Consult the current oracle middleware for price data format and possible oracle fee. It is possible for this operation to change the tick, tick version and index of the position, in which case we emit the LiquidationPriceUpdated event. This function always sends the security deposit to the validator. So users wanting to earn the corresponding security deposit must use validateActionablePendingActions. In case liquidations are pending (outcome_ == LongActionOutcome.PendingLiquidations), the pending action will not be removed from the queue, and the user will have to try again. In case the position was liquidated by this call (outcome_ == LongActionOutcome.Liquidated), this function will refund the security deposit and remove the pending action from the queue.

function validateOpenPosition(
    address payable validator,
    bytes calldata openPriceData,
    PreviousActionsData calldata previousActionsData
) external payable returns (LongActionOutcome outcome_, PositionId memory posId_);

Parameters

NameTypeDescription
validatoraddress payableThe address associated with the pending open position. If not an EOA, it must be a contract that implements a receive function.
openPriceDatabytesThe price data for the pending open position.
previousActionsDataPreviousActionsDataThe data needed to validate actionable pending actions.

Returns

NameTypeDescription
outcome_LongActionOutcomeThe effect on the pending action (processed, liquidated, or pending liquidations).
posId_PositionIdThe position ID after validation (or NO_POSITION_TICK if liquidated).

initiateClosePosition

Initiates a close position action.

Consult the current oracle middleware for price data format and possible oracle fee. Requires _securityDepositValue to be included in the transaction value. If the current tick version is greater than the tick version of the position (when it was opened), then the position has been liquidated and the transaction will revert. In case liquidations are pending (outcome_ == LongActionOutcome.PendingLiquidations), the pending action will not be removed from the queue, and the user will have to try again. In case the position was liquidated by this call (outcome_ == LongActionOutcome.Liquidated), this function will refund the security deposit and remove the pending action from the queue. The user's input for the price is not guaranteed due to the price difference between the initiate and validate actions.

function initiateClosePosition(
    PositionId calldata posId,
    uint128 amountToClose,
    uint256 userMinPrice,
    address to,
    address payable validator,
    uint256 deadline,
    bytes calldata currentPriceData,
    PreviousActionsData calldata previousActionsData,
    bytes calldata delegationSignature
) external payable returns (LongActionOutcome outcome_);

Parameters

NameTypeDescription
posIdPositionIdThe unique identifier of the position to close.
amountToCloseuint128The amount of collateral to remove.
userMinPriceuint256The user's wanted minimum price for closing the position.
toaddressThe address that will receive the assets.
validatoraddress payableThe address that is supposed to validate the closing and receive the security deposit. If not an EOA, it must be a contract that implements a receive function.
deadlineuint256The deadline for initiating the close position.
currentPriceDatabytesThe price data for temporary calculations.
previousActionsDataPreviousActionsDataThe data needed to validate actionable pending actions.
delegationSignaturebytesOptional EIP712 signature for delegated action.

Returns

NameTypeDescription
outcome_LongActionOutcomeThe effect on the pending action (processed, liquidated, or pending liquidations).

validateClosePosition

Validates a pending close position action.

Consult the current oracle middleware for price data format and possible oracle fee. This function calculates the final exit price, determines the profit of the long position, and performs the payout. This function always sends the security deposit to the validator. So users wanting to earn the corresponding security deposit must use validateActionablePendingActions. In case liquidations are pending (outcome_ == LongActionOutcome.PendingLiquidations), the pending action will not be removed from the queue, and the user will have to try again. In case the position was liquidated by this call (outcome_ == LongActionOutcome.Liquidated), this function will refund the security deposit and remove the pending action from the queue.

function validateClosePosition(
    address payable validator,
    bytes calldata closePriceData,
    PreviousActionsData calldata previousActionsData
) external payable returns (LongActionOutcome outcome_);

Parameters

NameTypeDescription
validatoraddress payableThe address associated with the pending close position. If not an EOA, it must be a contract that implements a receive function.
closePriceDatabytesThe price data for the pending close position action.
previousActionsDataPreviousActionsDataThe data required to validate actionable pending actions.

Returns

NameTypeDescription
outcome_LongActionOutcomeThe outcome of the action (processed, liquidated, or pending liquidations).

initiateDeposit

Initiates a deposit of assets into the vault to mint USDN.

Consult the current oracle middleware for price data format and possible oracle fee. Requires _securityDepositValue to be included in the transaction value. In case liquidations are pending, this function might not initiate the deposit, and success_ would be false. The user's input for the shares is not guaranteed due to the price difference between the initiate and validate actions.

function initiateDeposit(
    uint128 amount,
    uint256 sharesOutMin,
    address to,
    address payable validator,
    uint256 deadline,
    bytes calldata currentPriceData,
    PreviousActionsData calldata previousActionsData
) external payable returns (bool success_);

Parameters

NameTypeDescription
amountuint128The amount of assets to deposit.
sharesOutMinuint256The minimum amount of USDN shares to receive.
toaddressThe address that will receive the USDN tokens.
validatoraddress payableThe address that is supposed to validate the deposit and receive the security deposit. If not an EOA, it must be a contract that implements a receive function.
deadlineuint256The deadline for initiating the deposit.
currentPriceDatabytesThe current price data.
previousActionsDataPreviousActionsDataThe data required to validate actionable pending actions.

Returns

NameTypeDescription
success_boolIndicates whether the deposit was successfully initiated.

validateDeposit

Validates a pending deposit action.

Consult the current oracle middleware for price data format and possible oracle fee. This function always sends the security deposit to the validator. So users wanting to earn the corresponding security deposit must use validateActionablePendingActions. If liquidations are pending, the validation may fail, and success_ would be false.

function validateDeposit(
    address payable validator,
    bytes calldata depositPriceData,
    PreviousActionsData calldata previousActionsData
) external payable returns (bool success_);

Parameters

NameTypeDescription
validatoraddress payableThe address associated with the pending deposit action. If not an EOA, it must be a contract that implements a receive function.
depositPriceDatabytesThe price data for the pending deposit action.
previousActionsDataPreviousActionsDataThe data required to validate actionable pending actions.

Returns

NameTypeDescription
success_boolIndicates whether the deposit was successfully validated.

initiateWithdrawal

Initiates a withdrawal of assets from the vault using USDN tokens.

Consult the current oracle middleware for price data format and possible oracle fee. Requires _securityDepositValue to be included in the transaction value. Note that in case liquidations are pending, this function might not initiate the withdrawal, and success_ would be false. The user's input for the minimum amount is not guaranteed due to the price difference between the initiate and validate actions.

function initiateWithdrawal(
    uint152 usdnShares,
    uint256 amountOutMin,
    address to,
    address payable validator,
    uint256 deadline,
    bytes calldata currentPriceData,
    PreviousActionsData calldata previousActionsData
) external payable returns (bool success_);

Parameters

NameTypeDescription
usdnSharesuint152The amount of USDN shares to burn.
amountOutMinuint256The minimum amount of assets to receive.
toaddressThe address that will receive the assets.
validatoraddress payableThe address that is supposed to validate the withdrawal and receive the security deposit. If not an EOA, it must be a contract that implements a receive function.
deadlineuint256The deadline for initiating the withdrawal.
currentPriceDatabytesThe current price data.
previousActionsDataPreviousActionsDataThe data required to validate actionable pending actions.

Returns

NameTypeDescription
success_boolIndicates whether the withdrawal was successfully initiated.

validateWithdrawal

Validates a pending withdrawal action.

Consult the current oracle middleware for price data format and possible oracle fee. This function always sends the security deposit to the validator. So users wanting to earn the corresponding security deposit must use validateActionablePendingActions. In case liquidations are pending, this function might not validate the withdrawal, and success_ would be false.

function validateWithdrawal(
    address payable validator,
    bytes calldata withdrawalPriceData,
    PreviousActionsData calldata previousActionsData
) external payable returns (bool success_);

Parameters

NameTypeDescription
validatoraddress payableThe address associated with the pending withdrawal action. If not an EOA, it must be a contract that implements a receive function.
withdrawalPriceDatabytesThe price data for the pending withdrawal action.
previousActionsDataPreviousActionsDataThe data required to validate actionable pending actions.

Returns

NameTypeDescription
success_boolIndicates whether the withdrawal was successfully validated.

liquidate

Liquidates positions based on the provided asset price.

Consult the current oracle middleware for price data format and possible oracle fee. Each tick is liquidated in constant time. The tick version is incremented for each liquidated tick.

function liquidate(bytes calldata currentPriceData) external payable returns (LiqTickInfo[] memory liquidatedTicks_);

Parameters

NameTypeDescription
currentPriceDatabytesThe price data.

Returns

NameTypeDescription
liquidatedTicks_LiqTickInfo[]Information about the liquidated ticks.

validateActionablePendingActions

Manually validates actionable pending actions.

Consult the current oracle middleware for price data format and possible oracle fee. The timestamp for each pending action is calculated by adding the OracleMiddleware.validationDelay to its initiation timestamp.

function validateActionablePendingActions(PreviousActionsData calldata previousActionsData, uint256 maxValidations)
    external
    payable
    returns (uint256 validatedActions_);

Parameters

NameTypeDescription
previousActionsDataPreviousActionsDataThe data required to validate actionable pending actions.
maxValidationsuint256The maximum number of actionable pending actions to validate. At least one validation will be performed.

Returns

NameTypeDescription
validatedActions_uint256The number of successfully validated actions.

transferPositionOwnership

Transfers the ownership of a position to another address.

This function reverts if the caller is not the position owner, if the position does not exist, or if the new owner's address is the zero address. If the new owner is a contract that implements the IOwnershipCallback interface, its ownershipCallback function will be invoked after the transfer.

function transferPositionOwnership(PositionId calldata posId, address newOwner, bytes calldata delegationSignature)
    external;

Parameters

NameTypeDescription
posIdPositionIdThe unique identifier of the position.
newOwneraddressThe address of the new position owner.
delegationSignaturebytesAn optional EIP712 signature to authorize the transfer on the owner's behalf.

domainSeparatorV4

Retrieves the domain separator used in EIP-712 signatures.

function domainSeparatorV4() external view returns (bytes32 domainSeparatorV4_);

Returns

NameTypeDescription
domainSeparatorV4_bytes32The domain separator compliant with EIP-712.

IUsdnProtocolCore

Git Source

Interface for the core layer of the USDN protocol.

Functions

funding

Computes the predicted funding value since the last state update for the specified timestamp.

The funding value, when multiplied by the long trading exposure, represents the asset balance to be transferred to the vault side, or to the long side if the value is negative. Reverts with UsdnProtocolTimestampTooOld if the given timestamp is older than the last state update.

function funding(uint128 timestamp)
    external
    view
    returns (int256 funding_, int256 fundingPerDay_, int256 oldLongExpo_);

Parameters

NameTypeDescription
timestampuint128The timestamp to use for the computation.

Returns

NameTypeDescription
funding_int256The funding magnitude (with FUNDING_RATE_DECIMALS decimals) since the last update timestamp.
fundingPerDay_int256The funding rate per day (with FUNDING_RATE_DECIMALS decimals).
oldLongExpo_int256The long trading exposure recorded at the last state update.

initialize

Initializes the protocol by making an initial deposit and creating the first long position.

This function can only be called once. No other user actions can be performed until the protocol is initialized.

function initialize(uint128 depositAmount, uint128 longAmount, uint128 desiredLiqPrice, bytes calldata currentPriceData)
    external
    payable;

Parameters

NameTypeDescription
depositAmountuint128The amount of assets to deposit.
longAmountuint128The amount of assets for the long position.
desiredLiqPriceuint128The desired liquidation price for the long position, excluding the liquidation penalty.
currentPriceDatabytesThe encoded current price data.

IUsdnProtocolErrors

Git Source

All errors used in the USDN Protocol.

Errors

UsdnProtocolInsufficientOracleFee

Insufficient Ether provided to cover the cost of price validation.

error UsdnProtocolInsufficientOracleFee();

UsdnProtocolEtherRefundFailed

Ether refund to the sender failed.

error UsdnProtocolEtherRefundFailed();

UsdnProtocolNotEligibleForRefund

Validator is not eligible for a security deposit refund.

error UsdnProtocolNotEligibleForRefund(address validator);

Parameters

NameTypeDescription
validatoraddressThe address of the validator.

UsdnProtocolZeroAmount

The provided amount is zero.

error UsdnProtocolZeroAmount();

UsdnProtocolInvalidAddressTo

The provided to address is invalid.

error UsdnProtocolInvalidAddressTo();

UsdnProtocolInvalidAddressValidator

The provided validator address is invalid.

error UsdnProtocolInvalidAddressValidator();

UsdnProtocolMinInitAmount

The initial amount provided during initialization is too small to support opening a long position.

error UsdnProtocolMinInitAmount();

UsdnProtocolInvalidUsdn

The provided USDN token has a non-zero total supply at deployment.

error UsdnProtocolInvalidUsdn(address usdnAddress);

Parameters

NameTypeDescription
usdnAddressaddressThe address of the USDN contract.

UsdnProtocolInvalidAssetDecimals

The asset's decimal precision is invalid.

error UsdnProtocolInvalidAssetDecimals(uint8 assetDecimals);

Parameters

NameTypeDescription
assetDecimalsuint8The specified asset decimals.

UsdnProtocolInvalidTokenDecimals

The token's decimals do not match TOKENS_DECIMALS.

error UsdnProtocolInvalidTokenDecimals();

UsdnProtocolUnauthorized

The caller is not authorized to perform the action.

error UsdnProtocolUnauthorized();

UsdnProtocolPendingAction

A pending action already exists for the user.

error UsdnProtocolPendingAction();

UsdnProtocolNoPendingAction

The user does not have any pending action.

error UsdnProtocolNoPendingAction();

UsdnProtocolInvalidPendingAction

A pending action exists, but its type is not the expected one.

error UsdnProtocolInvalidPendingAction();

UsdnProtocolTimestampTooOld

The provided timestamp predates the last balance update.

error UsdnProtocolTimestampTooOld();

UsdnProtocolLeverageTooLow

The calculated leverage is below the minimum allowed.

error UsdnProtocolLeverageTooLow();

UsdnProtocolLeverageTooHigh

The calculated leverage exceeds the maximum allowed.

error UsdnProtocolLeverageTooHigh();

UsdnProtocolLongPositionTooSmall

The amount of collateral in the long position is too small.

error UsdnProtocolLongPositionTooSmall();

UsdnProtocolInvalidLiquidationPrice

The liquidation price exceeds or equals the starting price.

error UsdnProtocolInvalidLiquidationPrice(uint128 liquidationPrice, uint128 startPrice);

Parameters

NameTypeDescription
liquidationPriceuint128The specified liquidation price.
startPriceuint128The starting price.

UsdnProtocolLiquidationPriceSafetyMargin

The liquidation price exceeds the safety margin.

error UsdnProtocolLiquidationPriceSafetyMargin(uint128 liquidationPrice, uint128 maxLiquidationPrice);

Parameters

NameTypeDescription
liquidationPriceuint128The specified liquidation price.
maxLiquidationPriceuint128The maximum liquidation price.

UsdnProtocolOutdatedTick

The provided tick version is outdated due to liquidation.

error UsdnProtocolOutdatedTick(uint256 currentVersion, uint256 providedVersion);

Parameters

NameTypeDescription
currentVersionuint256The current tick version.
providedVersionuint256The provided tick version.

UsdnProtocolPositionNotValidated

The position cannot be closed because it has not been validated yet.

error UsdnProtocolPositionNotValidated();

UsdnProtocolInvalidPositionFee

The specified position fee exceeds the allowed maximum.

error UsdnProtocolInvalidPositionFee();

UsdnProtocolInvalidVaultFee

The specified vault fee exceeds the allowed maximum.

error UsdnProtocolInvalidVaultFee();

UsdnProtocolInvalidSdexRewardsRatio

The specified SDEX rewards ratio exceeds the allowed maximum.

error UsdnProtocolInvalidSdexRewardsRatio();

UsdnProtocolInvalidRebalancerBonus

The specified rebalancer bonus exceeds the allowed maximum.

error UsdnProtocolInvalidRebalancerBonus();

UsdnProtocolInvalidBurnSdexOnDepositRatio

The specified ratio exceeds the allowed maximum.

error UsdnProtocolInvalidBurnSdexOnDepositRatio();

UsdnProtocolInvalidMiddlewareAddress

The specified middleware address is invalid.

error UsdnProtocolInvalidMiddlewareAddress();

UsdnProtocolInvalidRebalancerMinLeverage

The specified minimum leverage is invalid.

error UsdnProtocolInvalidRebalancerMinLeverage();

UsdnProtocolInvalidMinLeverage

The specified minLeverage value is invalid.

error UsdnProtocolInvalidMinLeverage();

UsdnProtocolInvalidMaxLeverage

The specified maxLeverage value is invalid.

error UsdnProtocolInvalidMaxLeverage();

UsdnProtocolInvalidValidatorDeadline

The specified validation deadline is invalid.

error UsdnProtocolInvalidValidatorDeadline();

UsdnProtocolInvalidLiquidationPenalty

The specified liquidation penalty is invalid.

error UsdnProtocolInvalidLiquidationPenalty();

UsdnProtocolInvalidSafetyMarginBps

The specified safety margin basis points are invalid.

error UsdnProtocolInvalidSafetyMarginBps();

UsdnProtocolInvalidLiquidationIteration

The specified liquidation iteration value is invalid.

error UsdnProtocolInvalidLiquidationIteration();

UsdnProtocolInvalidEMAPeriod

The specified EMA period is invalid.

error UsdnProtocolInvalidEMAPeriod();

UsdnProtocolInvalidFundingSF

The specified funding scale factor (SF) is invalid.

error UsdnProtocolInvalidFundingSF();

UsdnProtocolInvalidLiquidationRewardsManagerAddress

The specified LiquidationRewardsManager contract address is invalid.

error UsdnProtocolInvalidLiquidationRewardsManagerAddress();

UsdnProtocolInvalidProtocolFeeBps

The specified protocol fee basis points are invalid.

error UsdnProtocolInvalidProtocolFeeBps();

UsdnProtocolInvalidFeeCollector

The specified fee collector address is invalid.

error UsdnProtocolInvalidFeeCollector();

UsdnProtocolSecurityDepositTooLow

The specified security deposit is below the required value.

error UsdnProtocolSecurityDepositTooLow();

UsdnProtocolUnexpectedBalance

The contract's ether balance after the action is not as expected.

error UsdnProtocolUnexpectedBalance();

UsdnProtocolInvalidExpoImbalanceLimit

The specified trading exposure imbalance limit is invalid.

error UsdnProtocolInvalidExpoImbalanceLimit();

UsdnProtocolInvalidLongImbalanceTarget

The specified imbalance target is invalid.

error UsdnProtocolInvalidLongImbalanceTarget();

UsdnProtocolImbalanceLimitReached

The protocol imbalance limit has been reached.

error UsdnProtocolImbalanceLimitReached(int256 imbalanceBps);

Parameters

NameTypeDescription
imbalanceBpsint256The imbalance value in basis points.

UsdnProtocolInvalidRebalancerTick

The tick of the rebalancer position is invalid.

error UsdnProtocolInvalidRebalancerTick();

UsdnProtocolInvalidLongExpo

The long total exposure value is invalid.

error UsdnProtocolInvalidLongExpo();

UsdnProtocolZeroTotalExpo

The total exposure value is zero.

error UsdnProtocolZeroTotalExpo();

UsdnProtocolInvalidPendingActionData

Indicates that the data provided to validate an actionable pending action is invalid.

error UsdnProtocolInvalidPendingActionData();

UsdnProtocolInvalidTargetUsdnPrice

The specified target USDN price is invalid.

error UsdnProtocolInvalidTargetUsdnPrice();

UsdnProtocolInvalidUsdnRebaseThreshold

The specified USDN rebase threshold is invalid.

error UsdnProtocolInvalidUsdnRebaseThreshold();

UsdnProtocolAmountToCloseHigherThanPositionAmount

The amount to close exceeds the position amount.

error UsdnProtocolAmountToCloseHigherThanPositionAmount(uint128 amountToClose, uint128 positionAmount);

Parameters

NameTypeDescription
amountToCloseuint128The specified amount to close.
positionAmountuint128The total amount in the position.

UsdnProtocolDepositTooSmall

The deposit amount is too small to mint USDN.

error UsdnProtocolDepositTooSmall();

UsdnProtocolZeroLongTradingExpo

The long trading exposure is zero, making liquidation tick calculation impossible.

error UsdnProtocolZeroLongTradingExpo();

UsdnProtocolEmptyVault

The vault balance is zero, so the calculation cannot proceed.

error UsdnProtocolEmptyVault();

UsdnProtocolSlippageMaxPriceExceeded

The entry price exceeds the maximum specified by the user.

error UsdnProtocolSlippageMaxPriceExceeded();

UsdnProtocolSlippageMinPriceExceeded

The current price is below the minimum specified by the user.

error UsdnProtocolSlippageMinPriceExceeded();

UsdnProtocolAmountReceivedTooSmall

The estimated amount of tokens to be received is less than expected.

error UsdnProtocolAmountReceivedTooSmall();

UsdnProtocolPaymentCallbackFailed

The payment callback execution failed.

error UsdnProtocolPaymentCallbackFailed();

UsdnProtocolDeadlineExceeded

The user initiate action's deadline has passed.

error UsdnProtocolDeadlineExceeded();

UsdnProtocolInvalidDelegationSignature

The delegation signature is invalid.

error UsdnProtocolInvalidDelegationSignature();

UsdnProtocolInvalidSecurityDeposit

The specified security deposit value exceeds the allowed maximum

error UsdnProtocolInvalidSecurityDeposit();

UsdnProtocolInvalidMinLongPosition

The specified minimum long position value exceeds the allowed maximum.

error UsdnProtocolInvalidMinLongPosition();

UsdnProtocolInvalidMiddlewareLowLatencyDelay

The low latency delay of the specified oracle middleware contract is below the validator's deadline.

error UsdnProtocolInvalidMiddlewareLowLatencyDelay();

UsdnProtocolInvalidRebalancerMinAssetDeposit

The minimum asset deposit of the specified rebalancer contract is below the protocol's minimum asset deposit.

error UsdnProtocolInvalidRebalancerMinAssetDeposit();

IUsdnProtocolEvents

Git Source

Inherits: IUsdnProtocolTypes

Events for the USDN Protocol

Events

InitiatedDeposit

User initiates a deposit.

event InitiatedDeposit(
    address indexed to, address indexed validator, uint256 amount, uint256 feeBps, uint256 timestamp, uint256 sdexBurned
);

Parameters

NameTypeDescription
toaddressThe address that will receive the USDN tokens.
validatoraddressThe address that will receive the security deposit.
amountuint256The amount of assets that were deposited.
feeBpsuint256The fee in basis points.
timestampuint256The timestamp of the action.
sdexBurneduint256The amount of SDEX tokens burned.

ValidatedDeposit

User validates a deposit.

event ValidatedDeposit(
    address indexed to, address indexed validator, uint256 amountAfterFees, uint256 usdnMinted, uint256 timestamp
);

Parameters

NameTypeDescription
toaddressThe address that received the USDN tokens.
validatoraddressThe address that received the security deposit.
amountAfterFeesuint256The amount of assets that were deposited after fees.
usdnMinteduint256The amount of USDN that was minted.
timestampuint256The timestamp of the InitiatedDeposit action.

InitiatedWithdrawal

User initiates a withdrawal.

event InitiatedWithdrawal(
    address indexed to, address indexed validator, uint256 usdnAmount, uint256 feeBps, uint256 timestamp
);

Parameters

NameTypeDescription
toaddressThe address that will receive the assets.
validatoraddressThe address that will receive the security deposit.
usdnAmountuint256The amount of USDN that will be burned.
feeBpsuint256The fee in basis points.
timestampuint256The timestamp of the action.

ValidatedWithdrawal

User validates a withdrawal.

event ValidatedWithdrawal(
    address indexed to,
    address indexed validator,
    uint256 amountWithdrawnAfterFees,
    uint256 usdnBurned,
    uint256 timestamp
);

Parameters

NameTypeDescription
toaddressThe address that received the assets.
validatoraddressThe address that received the security deposit.
amountWithdrawnAfterFeesuint256The amount of assets that were withdrawn after fees.
usdnBurneduint256The amount of USDN that was burned.
timestampuint256The timestamp of the InitiatedWithdrawal action.

InitiatedOpenPosition

User initiates the opening of a long position.

event InitiatedOpenPosition(
    address indexed owner,
    address indexed validator,
    uint40 timestamp,
    uint128 totalExpo,
    uint128 amount,
    uint128 startPrice,
    PositionId posId
);

Parameters

NameTypeDescription
owneraddressThe address that owns the position.
validatoraddressThe address that will receive the security deposit.
timestampuint40The timestamp of the action.
totalExpouint128The initial total expo of the position (pending validation).
amountuint128The amount of assets that were deposited as collateral.
startPriceuint128The asset price at the moment of the position creation (pending validation).
posIdPositionIdThe unique position identifier.

ValidatedOpenPosition

User validates the opening of a long position.

event ValidatedOpenPosition(
    address indexed owner, address indexed validator, uint128 totalExpo, uint128 newStartPrice, PositionId posId
);

Parameters

NameTypeDescription
owneraddressThe address that owns the position.
validatoraddressThe address that received the security deposit.
totalExpouint128The total expo of the position.
newStartPriceuint128The asset price at the moment of the position creation (final).
posIdPositionIdThe unique position identifier. If changed compared to InitiatedOpenLong, then LiquidationPriceUpdated will be emitted too.

LiquidationPriceUpdated

The position was moved from one tick to another.

event LiquidationPriceUpdated(PositionId oldPosId, PositionId newPosId);

Parameters

NameTypeDescription
oldPosIdPositionIdThe old position identifier.
newPosIdPositionIdThe new position identifier.

InitiatedClosePosition

User initiates the closing of all or part of a long position.

event InitiatedClosePosition(
    address indexed owner,
    address indexed validator,
    address indexed to,
    PositionId posId,
    uint128 originalAmount,
    uint128 amountToClose,
    uint128 totalExpoRemaining
);

Parameters

NameTypeDescription
owneraddressThe owner of this position.
validatoraddressThe address that received the security deposit.
toaddressThe address that will receive the assets.
posIdPositionIdThe unique position identifier.
originalAmountuint128The amount of collateral originally on the position.
amountToCloseuint128The amount of collateral to close from the position. If the entirety of the position is being closed, this value equals originalAmount.
totalExpoRemaininguint128The total expo remaining in the position. If the entirety of the position is being closed, this value is zero.

ValidatedClosePosition

User validates the closing of a long position.

event ValidatedClosePosition(
    address indexed validator, address indexed to, PositionId posId, uint256 amountReceived, int256 profit
);

Parameters

NameTypeDescription
validatoraddressThe address that received the security deposit.
toaddressThe address that received the assets.
posIdPositionIdThe unique position identifier.
amountReceiveduint256The amount of assets that were sent to the user.
profitint256The profit that the user made.

LiquidatedTick

The tick is liquidated.

event LiquidatedTick(
    int24 indexed tick,
    uint256 indexed oldTickVersion,
    uint256 liquidationPrice,
    uint256 effectiveTickPrice,
    int256 remainingCollateral
);

Parameters

NameTypeDescription
tickint24The liquidated tick.
oldTickVersionuint256The liquidated tick version.
liquidationPriceuint256The asset price at the moment of liquidation.
effectiveTickPriceuint256The effective liquidated tick price.
remainingCollateralint256The amount of asset that was left in the tick, which was transferred to the vault if positive, or was taken from the vault if negative.

LiquidatedPosition

The position is individually liquidated.

event LiquidatedPosition(address indexed user, PositionId posId, uint256 liquidationPrice, uint256 effectiveTickPrice);

Parameters

NameTypeDescription
useraddressThe validator of the action, not necessarily the owner of the position.
posIdPositionIdThe unique identifier for the position that was liquidated.
liquidationPriceuint256The asset price at the moment of liquidation.
effectiveTickPriceuint256The effective liquidated tick price.

StalePendingActionRemoved

User's position was liquidated while pending validation and we removed the pending action.

event StalePendingActionRemoved(address indexed validator, PositionId posId);

Parameters

NameTypeDescription
validatoraddressThe validator address.
posIdPositionIdThe unique position identifier.

PositionFeeUpdated

The position fee is updated.

event PositionFeeUpdated(uint256 positionFee);

Parameters

NameTypeDescription
positionFeeuint256The new position fee (in basis points).

VaultFeeUpdated

The vault fee is updated.

event VaultFeeUpdated(uint256 vaultFee);

Parameters

NameTypeDescription
vaultFeeuint256The new vault fee (in basis points).

SdexRewardsRatioUpdated

The SDEX rewards ratio is updated.

event SdexRewardsRatioUpdated(uint16 ratio);

Parameters

NameTypeDescription
ratiouint16The new ratio (in basis points).

RebalancerBonusUpdated

The rebalancer bonus is updated.

event RebalancerBonusUpdated(uint256 bonus);

Parameters

NameTypeDescription
bonusuint256The new bonus (in basis points).

BurnSdexOnDepositRatioUpdated

The ratio of USDN to SDEX tokens to burn on deposit is updated.

event BurnSdexOnDepositRatioUpdated(uint256 newRatio);

Parameters

NameTypeDescription
newRatiouint256The new ratio.

SecurityDepositValueUpdated

The deposit value is updated.

event SecurityDepositValueUpdated(uint256 securityDepositValue);

Parameters

NameTypeDescription
securityDepositValueuint256The new deposit value.

OracleMiddlewareUpdated

The oracle middleware is updated.

event OracleMiddlewareUpdated(address newMiddleware);

Parameters

NameTypeDescription
newMiddlewareaddressThe new oracle middleware address.

RebalancerMinLeverageUpdated

The minimum leverage of the rebalancer is updated.

event RebalancerMinLeverageUpdated(uint256 newMinLeverage);

Parameters

NameTypeDescription
newMinLeverageuint256The new value for the minimum leverage.

MinLeverageUpdated

The minLeverage is updated.

event MinLeverageUpdated(uint256 newMinLeverage);

Parameters

NameTypeDescription
newMinLeverageuint256The new minLeverage.

MaxLeverageUpdated

The maxLeverage is updated.

event MaxLeverageUpdated(uint256 newMaxLeverage);

Parameters

NameTypeDescription
newMaxLeverageuint256The new maxLeverage.

ValidatorDeadlinesUpdated

The lowLatencyValidatorDeadline and onChainValidatorDeadline are updated.

event ValidatorDeadlinesUpdated(uint128 newLowLatencyValidatorDeadline, uint128 newOnChainValidatorDeadline);

Parameters

NameTypeDescription
newLowLatencyValidatorDeadlineuint128The new deadline for low-latency validation (offset from the initiate action timestamp).
newOnChainValidatorDeadlineuint128The new deadline for on-chain validation (offset from the initiate action timestamp + the oracle middleware's low-latency delay).

LiquidationPenaltyUpdated

The liquidationPenalty is updated.

event LiquidationPenaltyUpdated(uint24 newLiquidationPenalty);

Parameters

NameTypeDescription
newLiquidationPenaltyuint24The new liquidationPenalty.

SafetyMarginBpsUpdated

The safetyMargin is updated.

event SafetyMarginBpsUpdated(uint256 newSafetyMargin);

Parameters

NameTypeDescription
newSafetyMarginuint256The new safetyMargin.

LiquidationIterationUpdated

The liquidationIteration is updated.

event LiquidationIterationUpdated(uint16 newLiquidationIteration);

Parameters

NameTypeDescription
newLiquidationIterationuint16The new liquidationIteration.

EMAPeriodUpdated

The EMAPeriod is updated.

event EMAPeriodUpdated(uint128 newEMAPeriod);

Parameters

NameTypeDescription
newEMAPerioduint128The new EMAPeriod.

FundingSFUpdated

The fundingSF is updated.

event FundingSFUpdated(uint256 newFundingSF);

Parameters

NameTypeDescription
newFundingSFuint256The new fundingSF.

LiquidatorRewarded

Emitted when a user (liquidator) successfully liquidated positions.

event LiquidatorRewarded(address indexed liquidator, uint256 rewards);

Parameters

NameTypeDescription
liquidatoraddressThe address that initiated the liquidation.
rewardsuint256The amount of tokens the liquidator received in rewards.

LiquidationRewardsManagerUpdated

The LiquidationRewardsManager contract is updated.

event LiquidationRewardsManagerUpdated(address newAddress);

Parameters

NameTypeDescription
newAddressaddressThe address of the new (current) contract.

RebalancerUpdated

The rebalancer contract is updated.

event RebalancerUpdated(address newAddress);

Parameters

NameTypeDescription
newAddressaddressThe address of the new (current) contract.

ProtocolFeeDistributed

The pending protocol fee is distributed.

event ProtocolFeeDistributed(address feeCollector, uint256 amount);

Parameters

NameTypeDescription
feeCollectoraddressThe collector's address.
amountuint256The amount of fee transferred.

FeeBpsUpdated

The protocol fee is updated.

event FeeBpsUpdated(uint256 feeBps);

Parameters

NameTypeDescription
feeBpsuint256The new fee in basis points.

FeeCollectorUpdated

The fee collector is updated.

event FeeCollectorUpdated(address feeCollector);

Parameters

NameTypeDescription
feeCollectoraddressThe new fee collector address.

FeeThresholdUpdated

The fee threshold is updated.

event FeeThresholdUpdated(uint256 feeThreshold);

Parameters

NameTypeDescription
feeThresholduint256The new fee threshold.

TargetUsdnPriceUpdated

The target USDN price is updated.

event TargetUsdnPriceUpdated(uint128 price);

Parameters

NameTypeDescription
priceuint128The new target USDN price.

UsdnRebaseThresholdUpdated

The USDN rebase threshold is updated.

event UsdnRebaseThresholdUpdated(uint128 threshold);

Parameters

NameTypeDescription
thresholduint128The new target USDN price.

ImbalanceLimitsUpdated

Imbalance limits are updated.

event ImbalanceLimitsUpdated(
    uint256 newOpenLimitBps,
    uint256 newDepositLimitBps,
    uint256 newWithdrawalLimitBps,
    uint256 newCloseLimitBps,
    uint256 newRebalancerCloseLimitBps,
    int256 newLongImbalanceTargetBps
);

Parameters

NameTypeDescription
newOpenLimitBpsuint256The new open limit.
newDepositLimitBpsuint256The new deposit limit.
newWithdrawalLimitBpsuint256The new withdrawal limit.
newCloseLimitBpsuint256The new close limit.
newRebalancerCloseLimitBpsuint256The new close limit for the rebalancer's position.
newLongImbalanceTargetBpsint256The new long imbalance target.

MinLongPositionUpdated

The minimum long position is updated.

event MinLongPositionUpdated(uint256 minLongPosition);

Parameters

NameTypeDescription
minLongPositionuint256The new minimum long position.

HighestPopulatedTickUpdated

The highest populated tick is updated.

event HighestPopulatedTickUpdated(int24 tick);

Parameters

NameTypeDescription
tickint24The new highest populated tick.

SecurityDepositRefunded

Security deposit is refunded.

event SecurityDepositRefunded(address indexed pendingActionValidator, address indexed receivedBy, uint256 amount);

Parameters

NameTypeDescription
pendingActionValidatoraddressAddress of the default validator.
receivedByaddressAddress of the user that received the security deposit.
amountuint256Amount of security deposit refunded.

PositionOwnershipTransferred

Position changes ownership.

event PositionOwnershipTransferred(PositionId posId, address indexed oldOwner, address indexed newOwner);

Parameters

NameTypeDescription
posIdPositionIdThe unique position ID.
oldOwneraddressThe old owner.
newOwneraddressThe new owner.

LastFundingPerDayUpdated

The last funding per day is updated.

event LastFundingPerDayUpdated(int256 lastFundingPerDay, uint256 lastUpdateTimestamp);

Parameters

NameTypeDescription
lastFundingPerDayint256The new funding per day.
lastUpdateTimestampuint256The timestamp for which the funding per day was calculated.

SdexBurned

The protocol balance of SDEX has been burned.

event SdexBurned(uint256 amount, uint256 rewards);

Parameters

NameTypeDescription
amountuint256The amount of SDEX that was burned.
rewardsuint256The amount of rewards that were distributed to the caller.

IUsdnProtocolFallback

Git Source

Inherits: IUsdnProtocolTypes

Interface for the USDN protocol fallback functions

Functions

getActionablePendingActions

Retrieves the list of pending actions that must be validated by the next user action in the protocol.

If this function returns a non-empty list of pending actions, then the next user action MUST include the corresponding list of price update data and raw indices as the last parameter. The user that processes those pending actions will receive the corresponding security deposit.

function getActionablePendingActions(address currentUser, uint256 lookAhead, uint256 maxIter)
    external
    view
    returns (PendingAction[] memory actions_, uint128[] memory rawIndices_);

Parameters

NameTypeDescription
currentUseraddressThe address of the user that will submit the price signatures for third-party actions validations. This is used to filter out their actions from the returned list.
lookAheaduint256Additionally to pending actions which are actionable at this moment block.timestamp, the function will also return pending actions which will be actionable lookAhead seconds later. It is recommended to use a non-zero value in order to account for the interval where the validation transaction will be pending. A value of 30 seconds should already account for most situations and avoid reverts in case an action becomes actionable after a user submits their transaction.
maxIteruint256The maximum number of iterations when looking through the queue to find actionable pending actions. This value will be clamped to [MIN_ACTIONABLE_PENDING_ACTIONS_ITER,_pendingActionsQueue.length()].

Returns

NameTypeDescription
actions_PendingAction[]The pending actions if any, otherwise an empty array.
rawIndices_uint128[]The raw indices of the actionable pending actions in the queue if any, otherwise an empty array. Each entry corresponds to the action in the actions_ array, at the same index.

getUserPendingAction

Retrieves the pending action with user as the given validator.

function getUserPendingAction(address user) external view returns (PendingAction memory action_);

Parameters

NameTypeDescription
useraddressThe user's address.

Returns

NameTypeDescription
action_PendingActionThe pending action if any, otherwise a struct with all fields set to zero and ProtocolAction.None.

tickHash

Computes the hash generated from the given tick number and version.

function tickHash(int24 tick, uint256 version) external pure returns (bytes32 hash_);

Parameters

NameTypeDescription
tickint24The tick number.
versionuint256The tick version.

Returns

NameTypeDescription
hash_bytes32The hash of the given tick number and version.

getEffectivePriceForTick

Computes the liquidation price of the given tick number, taking into account the effects of funding.

Uses the values from storage for the various variables. Note that ticks that are not a multiple of the tick spacing cannot contain a long position.

function getEffectivePriceForTick(int24 tick) external view returns (uint128 price_);

Parameters

NameTypeDescription
tickint24The tick number.

Returns

NameTypeDescription
price_uint128The liquidation price.

getEffectivePriceForTick

Computes the liquidation price of the given tick number, taking into account the effects of funding.

Uses the given values instead of the ones from the storage. Note that ticks that are not a multiple of the tick spacing cannot contain a long position.

function getEffectivePriceForTick(
    int24 tick,
    uint256 assetPrice,
    uint256 longTradingExpo,
    HugeUint.Uint512 memory accumulator
) external view returns (uint128 price_);

Parameters

NameTypeDescription
tickint24The tick number.
assetPriceuint256The current/projected price of the asset.
longTradingExpouint256The trading exposure of the long side (total expo - balance long).
accumulatorHugeUint.Uint512The liquidation multiplier accumulator.

Returns

NameTypeDescription
price_uint128The liquidation price.

previewWithdraw

Computes an estimate of the amount of assets received when withdrawing.

The result is a rough estimate and does not take into account rebases and liquidations.

function previewWithdraw(uint256 usdnShares, uint128 price, uint128 timestamp)
    external
    view
    returns (uint256 assetExpected_);

Parameters

NameTypeDescription
usdnSharesuint256The amount of USDN shares to use in the withdrawal.
priceuint128The current/projected price of the asset.
timestampuint128The The timestamp corresponding to price.

Returns

NameTypeDescription
assetExpected_uint256The expected amount of assets to be received.

previewDeposit

Computes an estimate of USDN tokens to be minted and SDEX tokens to be burned when depositing.

The result is a rough estimate and does not take into account rebases and liquidations.

function previewDeposit(uint256 amount, uint128 price, uint128 timestamp)
    external
    view
    returns (uint256 usdnSharesExpected_, uint256 sdexToBurn_);

Parameters

NameTypeDescription
amountuint256The amount of assets to deposit.
priceuint128The current/projected price of the asset.
timestampuint128The timestamp corresponding to price.

Returns

NameTypeDescription
usdnSharesExpected_uint256The amount of USDN shares to be minted.
sdexToBurn_uint256The amount of SDEX tokens to be burned.

refundSecurityDeposit

Refunds the security deposit to the given validator if it has a liquidated initiated long position.

The security deposit is always sent to the validator even if the pending action is actionable.

function refundSecurityDeposit(address payable validator) external;

Parameters

NameTypeDescription
validatoraddress payableThe address of the validator (must be payable as it will receive some native currency).

burnSdex

Sends the accumulated SDEX token fees to the dead address. This function can be called by anyone.

function burnSdex() external;

removeBlockedPendingAction

Removes a stuck pending action and performs the minimal amount of cleanup necessary.

This function can only be called by the owner of the protocol, it serves as an escape hatch if a pending action ever gets stuck due to something internal reverting unexpectedly. It will not refund any fees or burned SDEX.

function removeBlockedPendingAction(address validator, address payable to) external;

Parameters

NameTypeDescription
validatoraddressThe address of the validator of the stuck pending action.
toaddress payableWhere the retrieved funds should be sent (security deposit, assets, usdn). Must be payable.

removeBlockedPendingActionNoCleanup

Removes a stuck pending action with no cleanup.

This function can only be called by the owner of the protocol, it serves as an escape hatch if a pending action ever gets stuck due to something internal reverting unexpectedly. Always try to use removeBlockedPendingAction first, and only call this function if the other one fails. It will not refund any fees or burned SDEX.

function removeBlockedPendingActionNoCleanup(address validator, address payable to) external;

Parameters

NameTypeDescription
validatoraddressThe address of the validator of the stuck pending action.
toaddress payableWhere the retrieved funds should be sent (security deposit, assets, usdn). Must be payable.

removeBlockedPendingAction

Removes a stuck pending action and performs the minimal amount of cleanup necessary.

This function can only be called by the owner of the protocol, it serves as an escape hatch if a pending action ever gets stuck due to something internal reverting unexpectedly. It will not refund any fees or burned SDEX.

function removeBlockedPendingAction(uint128 rawIndex, address payable to) external;

Parameters

NameTypeDescription
rawIndexuint128The raw index of the stuck pending action.
toaddress payableWhere the retrieved funds should be sent (security deposit, assets, usdn). Must be payable.

removeBlockedPendingActionNoCleanup

Removes a stuck pending action with no cleanup.

This function can only be called by the owner of the protocol, it serves as an escape hatch if a pending action ever gets stuck due to something internal reverting unexpectedly. Always try to use removeBlockedPendingAction first, and only call this function if the other one fails. It will not refund any fees or burned SDEX.

function removeBlockedPendingActionNoCleanup(uint128 rawIndex, address payable to) external;

Parameters

NameTypeDescription
rawIndexuint128The raw index of the stuck pending action.
toaddress payableWhere the retrieved funds should be sent (security deposit, assets, usdn). Must be payable.

getTickSpacing

The number of ticks between usable ticks. Only tick numbers that are a multiple of the tick spacing can be used for storing long positions.

A tick spacing of 1 is equivalent to a 0.01% increase in price between ticks. A tick spacing of 100 is. equivalent to a ~1.005% increase in price between ticks.

function getTickSpacing() external view returns (int24 tickSpacing_);

Returns

NameTypeDescription
tickSpacing_int24The tick spacing.

getAsset

Gets the address of the protocol's underlying asset (ERC20 token).

function getAsset() external view returns (IERC20Metadata asset_);

Returns

NameTypeDescription
asset_IERC20MetadataThe address of the asset token.

getSdex

Gets the address of the SDEX ERC20 token.

function getSdex() external view returns (IERC20Metadata sdex_);

Returns

NameTypeDescription
sdex_IERC20MetadataThe address of the SDEX token.

getPriceFeedDecimals

Gets the number of decimals of the asset's price feed.

function getPriceFeedDecimals() external view returns (uint8 decimals_);

Returns

NameTypeDescription
decimals_uint8The number of decimals of the asset's price feed.

getAssetDecimals

Gets the number of decimals of the underlying asset token.

function getAssetDecimals() external view returns (uint8 decimals_);

Returns

NameTypeDescription
decimals_uint8The number of decimals of the asset token.

getUsdn

Gets the address of the USDN ERC20 token.

function getUsdn() external view returns (IUsdn usdn_);

Returns

NameTypeDescription
usdn_IUsdnThe address of USDN ERC20 token.

getUsdnMinDivisor

Gets the MIN_DIVISOR constant of the USDN token.

Check the USDN contract for more information.

function getUsdnMinDivisor() external view returns (uint256 minDivisor_);

Returns

NameTypeDescription
minDivisor_uint256The MIN_DIVISOR constant of the USDN token.

getOracleMiddleware

Gets the oracle middleware contract.

function getOracleMiddleware() external view returns (IBaseOracleMiddleware oracleMiddleware_);

Returns

NameTypeDescription
oracleMiddleware_IBaseOracleMiddlewareThe address of the oracle middleware contract.

getLiquidationRewardsManager

Gets the liquidation rewards manager contract.

function getLiquidationRewardsManager()
    external
    view
    returns (IBaseLiquidationRewardsManager liquidationRewardsManager_);

Returns

NameTypeDescription
liquidationRewardsManager_IBaseLiquidationRewardsManagerThe address of the liquidation rewards manager contract.

getRebalancer

Gets the rebalancer contract.

function getRebalancer() external view returns (IBaseRebalancer rebalancer_);

Returns

NameTypeDescription
rebalancer_IBaseRebalancerThe address of the rebalancer contract.

getMinLeverage

Gets the lowest leverage that can be used to open a long position.

function getMinLeverage() external view returns (uint256 minLeverage_);

Returns

NameTypeDescription
minLeverage_uint256The minimum leverage (with LEVERAGE_DECIMALS decimals).

getMaxLeverage

Gets the highest leverage that can be used to open a long position.

A position can have a leverage a bit higher than this value under specific conditions involving a change to the liquidation penalty setting.

function getMaxLeverage() external view returns (uint256 maxLeverage_);

Returns

NameTypeDescription
maxLeverage_uint256The maximum leverage value (with LEVERAGE_DECIMALS decimals).

getLowLatencyValidatorDeadline

Gets the deadline of the exclusivity period for the validator of a pending action with a low-latency oracle.

After this deadline, any user can validate the action with the low-latency oracle until the OracleMiddleware's _lowLatencyDelay, and retrieve the security deposit for the pending action.

function getLowLatencyValidatorDeadline() external view returns (uint128 deadline_);

Returns

NameTypeDescription
deadline_uint128The low-latency validation deadline of a validator (in seconds).

getOnChainValidatorDeadline

Gets the deadline of the exclusivity period for the validator to confirm their action with the on-chain oracle.

After this deadline, any user can validate the pending action with the on-chain oracle and retrieve its security deposit.

function getOnChainValidatorDeadline() external view returns (uint128 deadline_);

Returns

NameTypeDescription
deadline_uint128The on-chain validation deadline of a validator (in seconds)

getLiquidationPenalty

Gets the liquidation penalty applied to the liquidation price when opening a position.

function getLiquidationPenalty() external view returns (uint24 liquidationPenalty_);

Returns

NameTypeDescription
liquidationPenalty_uint24The liquidation penalty (in ticks).

getSafetyMarginBps

Gets the safety margin for the liquidation price of newly open positions.

function getSafetyMarginBps() external view returns (uint256 safetyMarginBps_);

Returns

NameTypeDescription
safetyMarginBps_uint256The safety margin (in basis points).

getLiquidationIteration

Gets the number of tick liquidations to perform when attempting to liquidate positions during user actions.

function getLiquidationIteration() external view returns (uint16 iterations_);

Returns

NameTypeDescription
iterations_uint16The number of iterations for liquidations during user actions.

getEMAPeriod

Gets the time frame for the EMA calculations.

The EMA is set to the last funding rate when the time elapsed between 2 actions is greater than this value.

function getEMAPeriod() external view returns (uint128 period_);

Returns

NameTypeDescription
period_uint128The time frame of the EMA (in seconds).

getFundingSF

Gets the scaling factor (SF) of the funding rate.

function getFundingSF() external view returns (uint256 scalingFactor_);

Returns

NameTypeDescription
scalingFactor_uint256The scaling factor (with FUNDING_SF_DECIMALS decimals).

getProtocolFeeBps

Gets the fee taken by the protocol during the application of funding.

function getProtocolFeeBps() external view returns (uint16 feeBps_);

Returns

NameTypeDescription
feeBps_uint16The fee applied to the funding (in basis points).

getPositionFeeBps

Gets the fee applied when a long position is opened or closed.

function getPositionFeeBps() external view returns (uint16 feeBps_);

Returns

NameTypeDescription
feeBps_uint16The fee applied to a long position (in basis points).

getVaultFeeBps

Gets the fee applied during a vault deposit or withdrawal.

function getVaultFeeBps() external view returns (uint16 feeBps_);

Returns

NameTypeDescription
feeBps_uint16The fee applied to a vault action (in basis points).

getSdexRewardsRatioBps

Gets the rewards ratio given to the caller when burning SDEX tokens.

function getSdexRewardsRatioBps() external view returns (uint16 rewardsBps_);

Returns

NameTypeDescription
rewardsBps_uint16The rewards ratio (in basis points).

getRebalancerBonusBps

Gets the part of the remaining collateral given as a bonus to the Rebalancer upon liquidation of a tick.

function getRebalancerBonusBps() external view returns (uint16 bonusBps_);

Returns

NameTypeDescription
bonusBps_uint16The fraction of the remaining collateral for the Rebalancer bonus (in basis points).

getSdexBurnOnDepositRatio

Gets the ratio of SDEX tokens to burn per minted USDN.

function getSdexBurnOnDepositRatio() external view returns (uint64 ratio_);

Returns

NameTypeDescription
ratio_uint64The ratio (to be divided by SDEX_BURN_ON_DEPOSIT_DIVISOR).

getSecurityDepositValue

Gets the amount of native tokens used as security deposit when opening a new position.

function getSecurityDepositValue() external view returns (uint64 securityDeposit_);

Returns

NameTypeDescription
securityDeposit_uint64The amount of assets to use as a security deposit (in ether).

getFeeThreshold

Gets the threshold to reach to send accumulated fees to the fee collector.

function getFeeThreshold() external view returns (uint256 threshold_);

Returns

NameTypeDescription
threshold_uint256The amount of accumulated fees to reach (in _assetDecimals).

getFeeCollector

Gets the address of the fee collector.

function getFeeCollector() external view returns (address feeCollector_);

Returns

NameTypeDescription
feeCollector_addressThe address of the fee collector.

getMiddlewareValidationDelay

Returns the amount of time to wait before an action can be validated.

This is also the amount of time to add to the initiate action timestamp to fetch the correct price data to validate said action with a low-latency oracle.

function getMiddlewareValidationDelay() external view returns (uint256 delay_);

Returns

NameTypeDescription
delay_uint256The validation delay (in seconds).

getDepositExpoImbalanceLimitBps

Gets the expo imbalance limit when depositing assets (in basis points).

function getDepositExpoImbalanceLimitBps() external view returns (int256 depositExpoImbalanceLimitBps_);

Returns

NameTypeDescription
depositExpoImbalanceLimitBps_int256The deposit expo imbalance limit.

getWithdrawalExpoImbalanceLimitBps

Gets the expo imbalance limit when withdrawing assets (in basis points).

function getWithdrawalExpoImbalanceLimitBps() external view returns (int256 withdrawalExpoImbalanceLimitBps_);

Returns

NameTypeDescription
withdrawalExpoImbalanceLimitBps_int256The withdrawal expo imbalance limit.

getOpenExpoImbalanceLimitBps

Gets the expo imbalance limit when opening a position (in basis points).

function getOpenExpoImbalanceLimitBps() external view returns (int256 openExpoImbalanceLimitBps_);

Returns

NameTypeDescription
openExpoImbalanceLimitBps_int256The open expo imbalance limit.

getCloseExpoImbalanceLimitBps

Gets the expo imbalance limit when closing a position (in basis points).

function getCloseExpoImbalanceLimitBps() external view returns (int256 closeExpoImbalanceLimitBps_);

Returns

NameTypeDescription
closeExpoImbalanceLimitBps_int256The close expo imbalance limit.

getRebalancerCloseExpoImbalanceLimitBps

Returns the limit of the imbalance in bps to close the rebalancer position.

function getRebalancerCloseExpoImbalanceLimitBps()
    external
    view
    returns (int256 rebalancerCloseExpoImbalanceLimitBps_);

Returns

NameTypeDescription
rebalancerCloseExpoImbalanceLimitBps_int256The limit of the imbalance in bps to close the rebalancer position.

getLongImbalanceTargetBps

Returns the imbalance desired on the long side after the creation of a rebalancer position.

The creation of the rebalancer position aims for this target but does not guarantee reaching it.

function getLongImbalanceTargetBps() external view returns (int256 targetLongImbalance_);

Returns

NameTypeDescription
targetLongImbalance_int256The target long imbalance.

getTargetUsdnPrice

Gets the nominal (target) price of USDN.

function getTargetUsdnPrice() external view returns (uint128 price_);

Returns

NameTypeDescription
price_uint128The price of the USDN token after a rebase (in _priceFeedDecimals).

getUsdnRebaseThreshold

Gets the USDN token price above which a rebase should occur.

function getUsdnRebaseThreshold() external view returns (uint128 threshold_);

Returns

NameTypeDescription
threshold_uint128The rebase threshold (in _priceFeedDecimals).

getMinLongPosition

Gets the minimum collateral amount when opening a long position.

function getMinLongPosition() external view returns (uint256 minLongPosition_);

Returns

NameTypeDescription
minLongPosition_uint256The minimum amount (with _assetDecimals).

getLastFundingPerDay

Gets the value of the funding rate at the last timestamp (getLastUpdateTimestamp).

function getLastFundingPerDay() external view returns (int256 lastFunding_);

Returns

NameTypeDescription
lastFunding_int256The last value of the funding rate (per day) with FUNDING_RATE_DECIMALS decimals.

getLastPrice

Gets the neutral price of the asset used during the last update of the vault and long balances.

function getLastPrice() external view returns (uint128 lastPrice_);

Returns

NameTypeDescription
lastPrice_uint128The most recent known price of the asset (in _priceFeedDecimals).

getLastUpdateTimestamp

Gets the timestamp of the last time a fresh price was provided.

function getLastUpdateTimestamp() external view returns (uint128 lastTimestamp_);

Returns

NameTypeDescription
lastTimestamp_uint128The timestamp of the last update.

getPendingProtocolFee

Gets the fees that were accumulated by the contract and are yet to be sent to the fee collector (in _assetDecimals).

function getPendingProtocolFee() external view returns (uint256 protocolFees_);

Returns

NameTypeDescription
protocolFees_uint256The amount of accumulated fees still in the contract.

getBalanceVault

Gets the amount of assets backing the USDN token.

function getBalanceVault() external view returns (uint256 balanceVault_);

Returns

NameTypeDescription
balanceVault_uint256The amount of assets on the vault side (in _assetDecimals).

getPendingBalanceVault

Gets the pending balance updates due to pending vault actions.

function getPendingBalanceVault() external view returns (int256 pendingBalanceVault_);

Returns

NameTypeDescription
pendingBalanceVault_int256The unreflected balance change due to pending vault actions (in _assetDecimals).

getEMA

Gets the exponential moving average of the funding rate per day.

function getEMA() external view returns (int256 ema_);

Returns

NameTypeDescription
ema_int256The exponential moving average of the funding rate per day.

getBalanceLong

Gets the summed value of all the currently open long positions at _lastUpdateTimestamp.

function getBalanceLong() external view returns (uint256 balanceLong_);

Returns

NameTypeDescription
balanceLong_uint256The balance of the long side (in _assetDecimals).

getTotalExpo

Gets the total exposure of all currently open long positions.

function getTotalExpo() external view returns (uint256 totalExpo_);

Returns

NameTypeDescription
totalExpo_uint256The total exposure of the longs (in _assetDecimals).

getLiqMultiplierAccumulator

Gets the accumulator used to calculate the liquidation multiplier.

function getLiqMultiplierAccumulator() external view returns (HugeUint.Uint512 memory accumulator_);

Returns

NameTypeDescription
accumulator_HugeUint.Uint512The liquidation multiplier accumulator.

getTickVersion

Gets the current version of the given tick.

function getTickVersion(int24 tick) external view returns (uint256 tickVersion_);

Parameters

NameTypeDescription
tickint24The tick number.

Returns

NameTypeDescription
tickVersion_uint256The version of the tick.

getTickData

Gets the tick data for the current tick version.

function getTickData(int24 tick) external view returns (TickData memory tickData_);

Parameters

NameTypeDescription
tickint24The tick number.

Returns

NameTypeDescription
tickData_TickDataThe tick data.

getCurrentLongPosition

Gets the long position at the provided tick and index.

function getCurrentLongPosition(int24 tick, uint256 index) external view returns (Position memory position_);

Parameters

NameTypeDescription
tickint24The tick number.
indexuint256The position index.

Returns

NameTypeDescription
position_PositionThe long position.

getHighestPopulatedTick

Gets the highest tick that has an open position.

function getHighestPopulatedTick() external view returns (int24 tick_);

Returns

NameTypeDescription
tick_int24The highest populated tick.

getTotalLongPositions

Gets the total number of long positions currently open.

function getTotalLongPositions() external view returns (uint256 totalLongPositions_);

Returns

NameTypeDescription
totalLongPositions_uint256The number of long positions.

getFallbackAddress

Gets the address of the fallback contract.

function getFallbackAddress() external view returns (address fallback_);

Returns

NameTypeDescription
fallback_addressThe address of the fallback contract.

isPaused

Gets the pause status of the USDN protocol.

function isPaused() external view returns (bool isPaused_);

Returns

NameTypeDescription
isPaused_boolTrue if it's paused, false otherwise.

getNonce

Gets the nonce a user can use to generate a delegation signature.

This is to prevent replay attacks when using an eip712 delegation signature.

function getNonce(address user) external view returns (uint256 nonce_);

Parameters

NameTypeDescription
useraddressThe address of the user.

Returns

NameTypeDescription
nonce_uint256The user's nonce.

setOracleMiddleware

Replaces the OracleMiddleware contract with a new implementation.

Cannot be the 0 address.

function setOracleMiddleware(IBaseOracleMiddleware newOracleMiddleware) external;

Parameters

NameTypeDescription
newOracleMiddlewareIBaseOracleMiddlewareThe address of the new contract.

setFeeCollector

Sets the fee collector address.

Cannot be the zero address.

function setFeeCollector(address newFeeCollector) external;

Parameters

NameTypeDescription
newFeeCollectoraddressThe address of the fee collector.

setLiquidationRewardsManager

Replaces the LiquidationRewardsManager contract with a new implementation.

Cannot be the 0 address.

function setLiquidationRewardsManager(IBaseLiquidationRewardsManager newLiquidationRewardsManager) external;

Parameters

NameTypeDescription
newLiquidationRewardsManagerIBaseLiquidationRewardsManagerThe address of the new contract.

setRebalancer

Replaces the Rebalancer contract with a new implementation.

function setRebalancer(IBaseRebalancer newRebalancer) external;

Parameters

NameTypeDescription
newRebalancerIBaseRebalancerThe address of the new contract.

setValidatorDeadlines

Sets the new deadlines of the exclusivity period for the validator to confirm its action and get its security deposit back.

function setValidatorDeadlines(uint128 newLowLatencyValidatorDeadline, uint128 newOnChainValidatorDeadline) external;

Parameters

NameTypeDescription
newLowLatencyValidatorDeadlineuint128The new exclusivity deadline for low-latency validation (offset from initiate timestamp).
newOnChainValidatorDeadlineuint128The new exclusivity deadline for on-chain validation (offset from initiate timestamp + oracle middleware's low latency delay).

setMinLongPosition

Sets the minimum long position size.

This value is used to prevent users from opening positions that are too small and not worth liquidating. As this parameter highly depends on the value of the underlying asset, the max value for newMinLongPosition is given as a constructor argument when the UsdnProtocolFallback contract is deployed, and is stored in an immutable variable.

function setMinLongPosition(uint256 newMinLongPosition) external;

Parameters

NameTypeDescription
newMinLongPositionuint256The new minimum long position size (with _assetDecimals).

setMinLeverage

Sets the new minimum leverage for a position.

function setMinLeverage(uint256 newMinLeverage) external;

Parameters

NameTypeDescription
newMinLeverageuint256The new minimum leverage.

setMaxLeverage

Sets the new maximum leverage for a position.

function setMaxLeverage(uint256 newMaxLeverage) external;

Parameters

NameTypeDescription
newMaxLeverageuint256The new maximum leverage.

setLiquidationPenalty

Sets the new liquidation penalty (in ticks).

function setLiquidationPenalty(uint24 newLiquidationPenalty) external;

Parameters

NameTypeDescription
newLiquidationPenaltyuint24The new liquidation penalty.

setEMAPeriod

Sets the new exponential moving average period of the funding rate.

function setEMAPeriod(uint128 newEMAPeriod) external;

Parameters

NameTypeDescription
newEMAPerioduint128The new EMA period.

setFundingSF

Sets the new scaling factor (SF) of the funding rate.

function setFundingSF(uint256 newFundingSF) external;

Parameters

NameTypeDescription
newFundingSFuint256The new scaling factor (SF) of the funding rate.

setProtocolFeeBps

Sets the protocol fee.

Fees are charged when the funding is applied (Example: 50 bps -> 0.5%).

function setProtocolFeeBps(uint16 newFeeBps) external;

Parameters

NameTypeDescription
newFeeBpsuint16The fee to be charged (in basis points).

setPositionFeeBps

Sets the position fee.

function setPositionFeeBps(uint16 newPositionFee) external;

Parameters

NameTypeDescription
newPositionFeeuint16The new position fee (in basis points).

setVaultFeeBps

Sets the vault fee.

function setVaultFeeBps(uint16 newVaultFee) external;

Parameters

NameTypeDescription
newVaultFeeuint16The new vault fee (in basis points).

setSdexRewardsRatioBps

Sets the rewards ratio given to the caller when burning SDEX tokens.

function setSdexRewardsRatioBps(uint16 newRewardsBps) external;

Parameters

NameTypeDescription
newRewardsBpsuint16The new rewards ratio (in basis points).

setRebalancerBonusBps

Sets the rebalancer bonus.

function setRebalancerBonusBps(uint16 newBonus) external;

Parameters

NameTypeDescription
newBonusuint16The bonus (in basis points).

setSdexBurnOnDepositRatio

Sets the ratio of SDEX tokens to burn per minted USDN.

As this parameter highly depends on the value of the USDN token, the max value for newRatio is given as a constructor argument when the UsdnProtocolFallback contract is deployed and is stored in an immutable variable.

function setSdexBurnOnDepositRatio(uint64 newRatio) external;

Parameters

NameTypeDescription
newRatiouint64The new ratio.

setSecurityDepositValue

Sets the security deposit value.

The maximum value of the security deposit is 2^64 - 1 = 18446744073709551615 = 18.4 ethers.

function setSecurityDepositValue(uint64 securityDepositValue) external;

Parameters

NameTypeDescription
securityDepositValueuint64The security deposit value. This value cannot be greater than MAX_SECURITY_DEPOSIT.

setExpoImbalanceLimits

Sets the imbalance limits (in basis point).

newLongImbalanceTargetBps needs to be lower than newCloseLimitBps and higher than the additive inverse of newWithdrawalLimitBps.

function setExpoImbalanceLimits(
    uint256 newOpenLimitBps,
    uint256 newDepositLimitBps,
    uint256 newWithdrawalLimitBps,
    uint256 newCloseLimitBps,
    uint256 newRebalancerCloseLimitBps,
    int256 newLongImbalanceTargetBps
) external;

Parameters

NameTypeDescription
newOpenLimitBpsuint256The new open limit.
newDepositLimitBpsuint256The new deposit limit.
newWithdrawalLimitBpsuint256The new withdrawal limit.
newCloseLimitBpsuint256The new close limit.
newRebalancerCloseLimitBpsuint256The new rebalancer close limit.
newLongImbalanceTargetBpsint256The new target imbalance limit for the long side. A positive value will target below equilibrium, a negative one will target above equilibrium. If negative, the rebalancerCloseLimit will be useless since the minimum value is 1.

setSafetyMarginBps

Sets the new safety margin for the liquidation price of newly open positions.

function setSafetyMarginBps(uint256 newSafetyMarginBps) external;

Parameters

NameTypeDescription
newSafetyMarginBpsuint256The new safety margin (in basis points).

setLiquidationIteration

Sets the new number of liquidations iteration for user actions.

function setLiquidationIteration(uint16 newLiquidationIteration) external;

Parameters

NameTypeDescription
newLiquidationIterationuint16The new number of liquidation iteration.

setFeeThreshold

Sets the minimum amount of fees to be collected before they can be withdrawn.

function setFeeThreshold(uint256 newFeeThreshold) external;

Parameters

NameTypeDescription
newFeeThresholduint256The minimum amount of fees to be collected before they can be withdrawn.

setTargetUsdnPrice

Sets the target USDN price.

When a rebase of USDN occurs, it will bring the price back down to this value.

function setTargetUsdnPrice(uint128 newPrice) external;

Parameters

NameTypeDescription
newPriceuint128The new target price (with _priceFeedDecimals). This value cannot be greater than _usdnRebaseThreshold.

setUsdnRebaseThreshold

Sets the USDN rebase threshold.

When the price of USDN exceeds this value, a rebase will be triggered.

function setUsdnRebaseThreshold(uint128 newThreshold) external;

Parameters

NameTypeDescription
newThresholduint128The new threshold value (with _priceFeedDecimals). This value cannot be smaller than _targetUsdnPrice or greater than uint128(2 * 10 ** s._priceFeedDecimals)

pause

Pauses related USDN protocol functions.

Pauses simultaneously all initiate/validate, refundSecurityDeposit and transferPositionOwnership functions. Before pausing, this function will call _applyPnlAndFunding with _lastPrice and the current timestamp. This is done to stop the funding rate from accumulating while the protocol is paused. Be sure to call unpause to update _lastUpdateTimestamp when unpausing.

function pause() external;

pauseSafe

Pauses related USDN protocol functions without applying PnLs and the funding.

Pauses simultaneously all initiate/validate, refundSecurityDeposit and transferPositionOwnership functions. This safe version will not call _applyPnlAndFunding before pausing.

function pauseSafe() external;

unpause

Unpauses related USDN protocol functions.

Unpauses simultaneously all initiate/validate, refundSecurityDeposit and transferPositionOwnership functions. This function will set _lastUpdateTimestamp to the current timestamp to prevent any funding during the pause. Only meant to be called after a pause call.

function unpause() external;

unpauseSafe

Unpauses related USDN protocol functions without updating _lastUpdateTimestamp.

Unpauses simultaneously all initiate/validate, refundSecurityDeposit and transferPositionOwnership functions. This safe version will not set _lastUpdateTimestamp to the current timestamp.

function unpauseSafe() external;

IUsdnProtocolImpl

Git Source

Inherits: IUsdnProtocolActions, IUsdnProtocolVault, IUsdnProtocolLong, IUsdnProtocolCore, IAccessControlDefaultAdminRules, IERC5267

Interface for the implementation of the USDN protocol (completed with IUsdnProtocolFallback)

Functions

initializeStorage

Initializes the protocol's storage with the given values.

This function should be called on deployment when creating the proxy. It can only be called once.

function initializeStorage(InitStorage calldata initStorage) external;

Parameters

NameTypeDescription
initStorageInitStorageThe initial storage values. Any call with a function signature not present in this contract will be delegated to the fallback contract.

IUsdnProtocolLong

Git Source

Inherits: IUsdnProtocolTypes

Interface for the long side layer of the USDN protocol.

Functions

minTick

Gets the value of the lowest usable tick, taking into account the tick spacing.

Note that the effective minimum tick of a newly open long position also depends on the minimum allowed leverage value and the current value of the liquidation price multiplier.

function minTick() external view returns (int24 tick_);

Returns

NameTypeDescription
tick_int24The lowest usable tick.

getLiqPriceFromDesiredLiqPrice

Gets the liquidation price from a desired one by taking into account the tick rounding.

function getLiqPriceFromDesiredLiqPrice(
    uint128 desiredLiqPriceWithoutPenalty,
    uint256 assetPrice,
    uint256 longTradingExpo,
    HugeUint.Uint512 memory accumulator,
    int24 tickSpacing,
    uint24 liquidationPenalty
) external view returns (uint128 liqPrice_);

Parameters

NameTypeDescription
desiredLiqPriceWithoutPenaltyuint128The desired liquidation price without the penalty.
assetPriceuint256The current price of the asset.
longTradingExpouint256The trading exposition of the long side.
accumulatorHugeUint.Uint512The liquidation multiplier accumulator.
tickSpacingint24The tick spacing.
liquidationPenaltyuint24The liquidation penalty set on the tick.

Returns

NameTypeDescription
liqPrice_uint128The new liquidation price without the penalty.

getPositionValue

Gets the value of a long position when the asset price is equal to the given price, at the given timestamp.

If the current price is smaller than the liquidation price of the position without the liquidation penalty, then the value of the position is negative.

function getPositionValue(PositionId calldata posId, uint128 price, uint128 timestamp)
    external
    view
    returns (int256 value_);

Parameters

NameTypeDescription
posIdPositionIdThe unique position identifier.
priceuint128The asset price.
timestampuint128The timestamp of the price.

Returns

NameTypeDescription
value_int256The position value in assets.

getEffectiveTickForPrice

Gets the tick number corresponding to a given price, accounting for funding effects.

Uses the stored parameters for calculation.

function getEffectiveTickForPrice(uint128 price) external view returns (int24 tick_);

Parameters

NameTypeDescription
priceuint128The asset price.

Returns

NameTypeDescription
tick_int24The tick number, a multiple of the tick spacing.

getEffectiveTickForPrice

Gets the tick number corresponding to a given price, accounting for funding effects.

function getEffectiveTickForPrice(
    uint128 price,
    uint256 assetPrice,
    uint256 longTradingExpo,
    HugeUint.Uint512 memory accumulator,
    int24 tickSpacing
) external view returns (int24 tick_);

Parameters

NameTypeDescription
priceuint128The asset price.
assetPriceuint256The current price of the asset.
longTradingExpouint256The trading exposition of the long side.
accumulatorHugeUint.Uint512The liquidation multiplier accumulator.
tickSpacingint24The tick spacing.

Returns

NameTypeDescription
tick_int24The tick number, a multiple of the tick spacing.

getTickLiquidationPenalty

Retrieves the liquidation penalty assigned to the given tick if there are positions in it, otherwise retrieve the current setting value from storage.

function getTickLiquidationPenalty(int24 tick) external view returns (uint24 liquidationPenalty_);

Parameters

NameTypeDescription
tickint24The tick number.

Returns

NameTypeDescription
liquidationPenalty_uint24The liquidation penalty, in tick spacing units.

getLongPosition

Gets a long position identified by its tick, tick version and index.

function getLongPosition(PositionId calldata posId)
    external
    view
    returns (Position memory pos_, uint24 liquidationPenalty_);

Parameters

NameTypeDescription
posIdPositionIdThe unique position identifier.

Returns

NameTypeDescription
pos_PositionThe position data.
liquidationPenalty_uint24The liquidation penalty for that position.

longAssetAvailableWithFunding

Gets the predicted value of the long balance for the given asset price and timestamp.

The effects of the funding and any PnL of the long positions since the last contract state update is taken into account, as well as the fees. If the provided timestamp is older than the last state update, the function reverts with UsdnProtocolTimestampTooOld. The value cannot be below 0.

function longAssetAvailableWithFunding(uint128 currentPrice, uint128 timestamp)
    external
    view
    returns (uint256 available_);

Parameters

NameTypeDescription
currentPriceuint128The given asset price.
timestampuint128The timestamp corresponding to the given price.

Returns

NameTypeDescription
available_uint256The long balance value in assets.

longTradingExpoWithFunding

Gets the predicted value of the long trading exposure for the given asset price and timestamp.

The effects of the funding and any profit or loss of the long positions since the last contract state update is taken into account. If the provided timestamp is older than the last state update, the function reverts with UsdnProtocolTimestampTooOld. The value cannot be below 0.

function longTradingExpoWithFunding(uint128 currentPrice, uint128 timestamp) external view returns (uint256 expo_);

Parameters

NameTypeDescription
currentPriceuint128The given asset price.
timestampuint128The timestamp corresponding to the given price.

Returns

NameTypeDescription
expo_uint256The long trading exposure value in assets.

IUsdnProtocolTypes

Git Source

Structs

Position

Information about a long user position.

struct Position {
    bool validated;
    uint40 timestamp;
    address user;
    uint128 totalExpo;
    uint128 amount;
}

Properties

NameTypeDescription
validatedboolWhether the position was validated.
timestampuint40The timestamp of the position start.
useraddressThe user's address.
totalExpouint128The total exposure of the position (0 for vault deposits). The product of the initial collateral and the initial leverage.
amountuint128The amount of initial collateral in the position.

PendingAction

A pending action in the queue.

struct PendingAction {
    ProtocolAction action;
    uint40 timestamp;
    uint24 var0;
    address to;
    address validator;
    uint64 securityDepositValue;
    int24 var1;
    uint128 var2;
    uint128 var3;
    uint256 var4;
    uint256 var5;
    uint256 var6;
    uint256 var7;
}

Properties

NameTypeDescription
actionProtocolActionThe action type.
timestampuint40The timestamp of the initiate action.
var0uint24See DepositPendingAction, WithdrawalPendingAction and LongPendingAction.
toaddressThe target of the action.
validatoraddressThe address that is supposed to validate the action.
securityDepositValueuint64The security deposit of the pending action.
var1int24See DepositPendingAction, WithdrawalPendingAction and LongPendingAction.
var2uint128See DepositPendingAction, WithdrawalPendingAction and LongPendingAction.
var3uint128See DepositPendingAction, WithdrawalPendingAction and LongPendingAction.
var4uint256See DepositPendingAction, WithdrawalPendingAction and LongPendingAction.
var5uint256See DepositPendingAction, WithdrawalPendingAction and LongPendingAction.
var6uint256See DepositPendingAction, WithdrawalPendingAction and LongPendingAction.
var7uint256See DepositPendingAction, WithdrawalPendingAction and LongPendingAction.

DepositPendingAction

A pending action in the queue for a vault deposit.

struct DepositPendingAction {
    ProtocolAction action;
    uint40 timestamp;
    uint24 feeBps;
    address to;
    address validator;
    uint64 securityDepositValue;
    uint24 _unused;
    uint128 amount;
    uint128 assetPrice;
    uint256 totalExpo;
    uint256 balanceVault;
    uint256 balanceLong;
    uint256 usdnTotalShares;
}

Properties

NameTypeDescription
actionProtocolActionThe action type.
timestampuint40The timestamp of the initiate action.
feeBpsuint24Fee for the deposit, in BPS.
toaddressThe recipient of the funds.
validatoraddressThe address that is supposed to validate the action.
securityDepositValueuint64The security deposit of the pending action.
_unuseduint24Unused field to align the struct to PendingAction.
amountuint128The amount of assets of the pending deposit.
assetPriceuint128The price of the asset at the time of the last update.
totalExpouint256The total exposure at the time of the last update.
balanceVaultuint256The balance of the vault at the time of the last update.
balanceLonguint256The balance of the long position at the time of the last update.
usdnTotalSharesuint256The total supply of USDN shares at the time of the action.

WithdrawalPendingAction

A pending action in the queue for a vault withdrawal.

struct WithdrawalPendingAction {
    ProtocolAction action;
    uint40 timestamp;
    uint24 feeBps;
    address to;
    address validator;
    uint64 securityDepositValue;
    uint24 sharesLSB;
    uint128 sharesMSB;
    uint128 assetPrice;
    uint256 totalExpo;
    uint256 balanceVault;
    uint256 balanceLong;
    uint256 usdnTotalShares;
}

Properties

NameTypeDescription
actionProtocolActionThe action type.
timestampuint40The timestamp of the initiate action.
feeBpsuint24Fee for the withdrawal, in BPS.
toaddressThe recipient of the funds.
validatoraddressThe address that is supposed to validate the action.
securityDepositValueuint64The security deposit of the pending action.
sharesLSBuint243 least significant bytes of the withdrawal shares amount (uint152).
sharesMSBuint12816 most significant bytes of the withdrawal shares amount (uint152).
assetPriceuint128The price of the asset at the time of the last update.
totalExpouint256The total exposure at the time of the last update.
balanceVaultuint256The balance of the vault at the time of the last update.
balanceLonguint256The balance of the long position at the time of the last update.
usdnTotalSharesuint256The total shares supply of USDN at the time of the action.

LongPendingAction

A pending action in the queue for a long position.

struct LongPendingAction {
    ProtocolAction action;
    uint40 timestamp;
    uint24 closeLiqPenalty;
    address to;
    address validator;
    uint64 securityDepositValue;
    int24 tick;
    uint128 closeAmount;
    uint128 closePosTotalExpo;
    uint256 tickVersion;
    uint256 index;
    uint256 liqMultiplier;
    uint256 closeBoundedPositionValue;
}

Properties

NameTypeDescription
actionProtocolActionThe action type.
timestampuint40The timestamp of the initiate action.
closeLiqPenaltyuint24The liquidation penalty of the tick (only used when closing a position).
toaddressThe recipient of the position.
validatoraddressThe address that is supposed to validate the action.
securityDepositValueuint64The security deposit of the pending action.
tickint24The tick of the position.
closeAmountuint128The portion of the initial position amount to close (only used when closing a position).
closePosTotalExpouint128The total expo of the position (only used when closing a position).
tickVersionuint256The version of the tick.
indexuint256The index of the position in the tick list.
liqMultiplieruint256A fixed precision representation of the liquidation multiplier (with LIQUIDATION_MULTIPLIER_DECIMALS decimals) used to calculate the effective price for a given tick number.
closeBoundedPositionValueuint256The amount that was removed from the long balance on initiateClosePosition (only used when closing a position).

PreviousActionsData

The data allowing to validate an actionable pending action.

struct PreviousActionsData {
    bytes[] priceData;
    uint128[] rawIndices;
}

Properties

NameTypeDescription
priceDatabytes[]An array of bytes, each representing the data to be forwarded to the oracle middleware to validate a pending action in the queue.
rawIndicesuint128[]An array of raw indices in the pending actions queue, in the same order as the corresponding priceData.

LiqTickInfo

Information of a liquidated tick.

struct LiqTickInfo {
    uint256 totalPositions;
    uint256 totalExpo;
    int256 remainingCollateral;
    uint128 tickPrice;
    uint128 priceWithoutPenalty;
}

Properties

NameTypeDescription
totalPositionsuint256The total number of positions in the tick.
totalExpouint256The total expo of the tick.
remainingCollateralint256The remaining collateral after liquidation.
tickPriceuint128The corresponding price.
priceWithoutPenaltyuint128The price without the liquidation penalty.

LiquidationsEffects

The effects of executed liquidations on the protocol.

struct LiquidationsEffects {
    uint256 liquidatedPositions;
    int256 remainingCollateral;
    uint256 newLongBalance;
    uint256 newVaultBalance;
    bool isLiquidationPending;
    LiqTickInfo[] liquidatedTicks;
}

Properties

NameTypeDescription
liquidatedPositionsuint256The total number of liquidated positions.
remainingCollateralint256The remaining collateral after liquidation.
newLongBalanceuint256The new balance of the long side.
newVaultBalanceuint256The new balance of the vault side.
isLiquidationPendingboolWhether some ticks are still populated above the current price (left to liquidate).
liquidatedTicksLiqTickInfo[]Information about the liquidated ticks.

TickData

Accumulator for tick data.

Since the liquidation penalty is a parameter that can be updated, we need to ensure that positions that get created with a given penalty, use this penalty throughout their lifecycle. As such, once a tick gets populated by a first position, it gets assigned the current liquidation penalty parameter value and can't use another value until it gets liquidated or all positions exit the tick.

struct TickData {
    uint256 totalExpo;
    uint248 totalPos;
    uint24 liquidationPenalty;
}

Properties

NameTypeDescription
totalExpouint256The sum of the total expo of each position in the tick.
totalPosuint248The number of positions in the tick.
liquidationPenaltyuint24The liquidation penalty for the positions in the tick.

PositionId

The unique identifier for a long position.

struct PositionId {
    int24 tick;
    uint256 tickVersion;
    uint256 index;
}

Properties

NameTypeDescription
tickint24The tick of the position.
tickVersionuint256The version of the tick.
indexuint256The index of the position in the tick list.

InitiateOpenPositionParams

Parameters for the internal _initiateOpenPosition function.

struct InitiateOpenPositionParams {
    address user;
    address to;
    address validator;
    uint128 amount;
    uint128 desiredLiqPrice;
    uint128 userMaxPrice;
    uint256 userMaxLeverage;
    uint256 deadline;
    uint64 securityDepositValue;
}

Properties

NameTypeDescription
useraddressThe address of the user initiating the open position.
toaddressThe address that will be the owner of the position.
validatoraddressThe address that is supposed to validate the action.
amountuint128The amount of assets to deposit.
desiredLiqPriceuint128The desired liquidation price, including the liquidation penalty.
userMaxPriceuint128The maximum price at which the position can be opened. The userMaxPrice is compared with the price after confidence interval, penalty, etc...
userMaxLeverageuint256The maximum leverage for the newly created position.
deadlineuint256The deadline of the open position to be initiated.
securityDepositValueuint64The value of the security deposit for the newly created pending action.

PrepareInitiateOpenPositionParams

Parameters for the internal {UsdnProtocolLongLibrary._prepareInitiateOpenPosition} function.

struct PrepareInitiateOpenPositionParams {
    address validator;
    uint128 amount;
    uint128 desiredLiqPrice;
    uint256 userMaxPrice;
    uint256 userMaxLeverage;
    bytes currentPriceData;
}

Properties

NameTypeDescription
validatoraddressThe address that is supposed to validate the action.
amountuint128The amount of assets to deposit.
desiredLiqPriceuint128The desired liquidation price, including the liquidation penalty.
userMaxPriceuint256The maximum price at which the position can be opened. The userMaxPrice is compared with the price after confidence interval, penalty, etc...
userMaxLeverageuint256The maximum leverage for the newly created position.
currentPriceDatabytesThe current price data.

PrepareInitiateClosePositionParams

Parameters for the internal _prepareClosePositionData function.

struct PrepareInitiateClosePositionParams {
    address to;
    address validator;
    PositionId posId;
    uint128 amountToClose;
    uint256 userMinPrice;
    uint256 deadline;
    bytes currentPriceData;
    bytes delegationSignature;
    bytes32 domainSeparatorV4;
}

Properties

NameTypeDescription
toaddressThe recipient of the funds.
validatoraddressThe address that is supposed to validate the action.
posIdPositionIdThe unique identifier of the position.
amountToCloseuint128The amount of collateral to remove from the position's amount.
userMinPriceuint256The minimum price at which the position can be closed.
deadlineuint256The deadline until the position can be closed.
currentPriceDatabytesThe current price data.
delegationSignaturebytesAn EIP712 signature that proves the caller is authorized by the owner of the position to close it on their behalf.
domainSeparatorV4bytes32The domain separator v4.

InitiateClosePositionParams

Parameters for the internal _initiateClosePosition function.

struct InitiateClosePositionParams {
    address to;
    address payable validator;
    uint256 deadline;
    PositionId posId;
    uint128 amountToClose;
    uint256 userMinPrice;
    uint64 securityDepositValue;
    bytes32 domainSeparatorV4;
}

Properties

NameTypeDescription
toaddressThe recipient of the funds.
validatoraddress payableThe address that is supposed to validate the action.
deadlineuint256The deadline of the close position to be initiated.
posIdPositionIdThe unique identifier of the position.
amountToCloseuint128The amount to close.
userMinPriceuint256The minimum price at which the position can be closed.
securityDepositValueuint64The value of the security deposit for the newly created pending action.
domainSeparatorV4bytes32The domain separator v4 for EIP712 signature.

ClosePositionData

Structure to hold the transient data during _initiateClosePosition

struct ClosePositionData {
    Position pos;
    uint24 liquidationPenalty;
    uint128 totalExpoToClose;
    uint128 lastPrice;
    uint256 tempPositionValue;
    uint256 longTradingExpo;
    HugeUint.Uint512 liqMulAcc;
    bool isLiquidationPending;
}

Properties

NameTypeDescription
posPositionThe position to close.
liquidationPenaltyuint24The liquidation penalty.
totalExpoToCloseuint128The total expo to close.
lastPriceuint128The price after the last balances update.
tempPositionValueuint256The bounded value of the position that was removed from the long balance.
longTradingExpouint256The long trading expo.
liqMulAccHugeUint.Uint512The liquidation multiplier accumulator.
isLiquidationPendingboolWhether some ticks are still populated above the current price (left to liquidate).

ValidateOpenPositionData

Structure to hold the transient data during _validateOpenPosition.

struct ValidateOpenPositionData {
    LongPendingAction action;
    uint128 startPrice;
    uint128 lastPrice;
    bytes32 tickHash;
    Position pos;
    uint128 liqPriceWithoutPenaltyNorFunding;
    uint128 liqPriceWithoutPenalty;
    uint256 leverage;
    uint256 oldPosValue;
    uint24 liquidationPenalty;
    bool isLiquidationPending;
}

Properties

NameTypeDescription
actionLongPendingActionThe long pending action.
startPriceuint128The new entry price of the position.
lastPriceuint128The price of the last balances update.
tickHashbytes32The tick hash.
posPositionThe position object.
liqPriceWithoutPenaltyNorFundinguint128The liquidation price without penalty nor funding used to calculate the user leverage and the new total expo.
liqPriceWithoutPenaltyuint128The new liquidation price without penalty.
leverageuint256The new leverage.
oldPosValueuint256The value of the position according to the old entry price and the _lastPrice.
liquidationPenaltyuint24The liquidation penalty for the position's tick.
isLiquidationPendingboolWhether some ticks are still populated above the current price (left to liquidate).

InitiateOpenPositionData

Structure to hold the transient data during _initiateOpenPosition.

struct InitiateOpenPositionData {
    uint128 adjustedPrice;
    PositionId posId;
    uint24 liquidationPenalty;
    uint128 positionTotalExpo;
    uint256 positionValue;
    uint256 liqMultiplier;
    bool isLiquidationPending;
}

Properties

NameTypeDescription
adjustedPriceuint128The adjusted price with position fees applied.
posIdPositionIdThe unique identifier of the position.
liquidationPenaltyuint24The liquidation penalty.
positionTotalExpouint128The total expo of the position. The product of the initial collateral and the initial leverage.
positionValueuint256The value of the position, taking into account the position fee.
liqMultiplieruint256The liquidation multiplier represented with fixed precision.
isLiquidationPendingboolWhether some ticks are still populated above the current price (left to liquidate).

CachedProtocolState

Structure to hold the state of the protocol.

struct CachedProtocolState {
    uint256 totalExpo;
    uint256 tradingExpo;
    uint256 longBalance;
    uint256 vaultBalance;
    HugeUint.Uint512 liqMultiplierAccumulator;
}

Properties

NameTypeDescription
totalExpouint256The long total expo.
tradingExpouint256The long trading expo.
longBalanceuint256The long balance.
vaultBalanceuint256The vault balance.
liqMultiplierAccumulatorHugeUint.Uint512The liquidation multiplier accumulator.

CalcRebalancerPositionTickData

Structure to hold transient data during the {UsdnProtocolActionsLongLibrary._calcRebalancerPositionTick} function.

struct CalcRebalancerPositionTickData {
    uint256 protocolMaxLeverage;
    int256 longImbalanceTargetBps;
    uint256 tradingExpoToFill;
    uint256 highestUsableTradingExpo;
    uint24 currentLiqPenalty;
    uint128 liqPriceWithoutPenalty;
}

Properties

NameTypeDescription
protocolMaxLeverageuint256The protocol maximum leverage.
longImbalanceTargetBpsint256The long imbalance target in basis points.
tradingExpoToFilluint256The trading expo to fill.
highestUsableTradingExpouint256The highest usable trading expo.
currentLiqPenaltyuint24The current liquidation penalty.
liqPriceWithoutPenaltyuint128The liquidation price without penalty.

RebalancerPositionData

Structure to hold the return values of the {UsdnProtocolActionsLongLibrary._calcRebalancerPositionTick} function.

struct RebalancerPositionData {
    int24 tick;
    uint128 totalExpo;
    uint24 liquidationPenalty;
}

Properties

NameTypeDescription
tickint24The tick of the rebalancer position, includes liquidation penalty.
totalExpouint128The total expo of the rebalancer position.
liquidationPenaltyuint24The liquidation penalty of the tick.

ApplyPnlAndFundingData

Data structure for the _applyPnlAndFunding function.

struct ApplyPnlAndFundingData {
    int256 tempLongBalance;
    int256 tempVaultBalance;
    uint128 lastPrice;
}

Properties

NameTypeDescription
tempLongBalanceint256The new balance of the long side, could be negative (temporarily).
tempVaultBalanceint256The new balance of the vault side, could be negative (temporarily).
lastPriceuint128The last price.

TickPriceConversionData

Data structure for tick to price conversion functions.

struct TickPriceConversionData {
    uint256 tradingExpo;
    HugeUint.Uint512 accumulator;
    int24 tickSpacing;
}

Properties

NameTypeDescription
tradingExpouint256The long side trading expo.
accumulatorHugeUint.Uint512The liquidation multiplier accumulator.
tickSpacingint24The tick spacing.

Storage

Structure to hold the state of the protocol.

Note: storage-location: erc7201:UsdnProtocol.storage.main.

struct Storage {
    int24 _tickSpacing;
    IERC20Metadata _asset;
    uint8 _assetDecimals;
    uint8 _priceFeedDecimals;
    IUsdn _usdn;
    IERC20Metadata _sdex;
    uint256 _usdnMinDivisor;
    IBaseOracleMiddleware _oracleMiddleware;
    IBaseLiquidationRewardsManager _liquidationRewardsManager;
    IBaseRebalancer _rebalancer;
    mapping(address => bool) _isRebalancer;
    uint256 _minLeverage;
    uint256 _maxLeverage;
    uint128 _lowLatencyValidatorDeadline;
    uint128 _onChainValidatorDeadline;
    uint256 _safetyMarginBps;
    uint16 _liquidationIteration;
    uint16 _protocolFeeBps;
    uint16 _rebalancerBonusBps;
    uint24 _liquidationPenalty;
    uint128 _EMAPeriod;
    uint256 _fundingSF;
    uint256 _feeThreshold;
    int256 _openExpoImbalanceLimitBps;
    int256 _withdrawalExpoImbalanceLimitBps;
    int256 _depositExpoImbalanceLimitBps;
    int256 _closeExpoImbalanceLimitBps;
    int256 _rebalancerCloseExpoImbalanceLimitBps;
    int256 _longImbalanceTargetBps;
    uint16 _positionFeeBps;
    uint16 _vaultFeeBps;
    uint16 _sdexRewardsRatioBps;
    uint32 __unused;
    address _feeCollector;
    uint64 _securityDepositValue;
    uint128 _targetUsdnPrice;
    uint128 _usdnRebaseThreshold;
    uint256 _minLongPosition;
    int256 _lastFundingPerDay;
    uint128 _lastPrice;
    uint128 _lastUpdateTimestamp;
    uint256 _pendingProtocolFee;
    mapping(address => uint256) _pendingActions;
    DoubleEndedQueue.Deque _pendingActionsQueue;
    uint256 _balanceVault;
    int256 _pendingBalanceVault;
    int256 _EMA;
    uint256 _balanceLong;
    uint256 _totalExpo;
    HugeUint.Uint512 _liqMultiplierAccumulator;
    mapping(int24 => uint256) _tickVersion;
    mapping(bytes32 => Position[]) _longPositions;
    mapping(bytes32 => TickData) _tickData;
    int24 _highestPopulatedTick;
    uint256 _totalLongPositions;
    LibBitmap.Bitmap _tickBitmap;
    address _protocolFallbackAddr;
    mapping(address => uint256) _nonce;
    uint64 _sdexBurnOnDepositRatio;
}

Properties

NameTypeDescription
_tickSpacingint24The liquidation tick spacing for storing long positions. A tick spacing of 1 is equivalent to a 0.01% increase in liquidation price between ticks. A tick spacing of 100 is equivalent to a ~1.005% increase in liquidation price between ticks.
_assetIERC20MetadataThe asset ERC20 contract. Assets with a blacklist are not supported because the protocol would be DoS if transfers revert.
_assetDecimalsuint8The number of decimals used by the _asset.
_priceFeedDecimalsuint8The price feed decimals (18).
_usdnIUsdnThe USDN ERC20 contract.
_sdexIERC20MetadataThe SDEX ERC20 contract.
_usdnMinDivisoruint256The minimum divisor for USDN.
_oracleMiddlewareIBaseOracleMiddlewareThe oracle middleware contract.
_liquidationRewardsManagerIBaseLiquidationRewardsManagerThe liquidation rewards manager contract.
_rebalancerIBaseRebalancerThe rebalancer contract.
_isRebalancermapping(address => bool)Whether an address is or has been a rebalancer.
_minLeverageuint256The minimum leverage for a position.
_maxLeverageuint256The maximum leverage for a position.
_lowLatencyValidatorDeadlineuint128The deadline for a user to confirm their action with a low-latency oracle. After this deadline, any user can validate the action with the low-latency oracle until the OracleMiddleware's _lowLatencyDelay. This is an offset compared to the timestamp of the initiate action.
_onChainValidatorDeadlineuint128The deadline for a user to confirm their action with an on-chain oracle. After this deadline, any user can validate the action with the on-chain oracle. This is an offset compared to the timestamp of the initiate action + the oracle middleware's _lowLatencyDelay.
_safetyMarginBpsuint256Safety margin for the liquidation price of newly open positions, in basis points.
_liquidationIterationuint16The number of iterations to perform during the user's action (in tick).
_protocolFeeBpsuint16The protocol fee in basis points.
_rebalancerBonusBpsuint16Part of the remaining collateral that is given as a bonus to the Rebalancer upon liquidation of a tick, in basis points. The rest is sent to the Vault balance.
_liquidationPenaltyuint24The liquidation penalty (in ticks).
_EMAPerioduint128The moving average period of the funding rate.
_fundingSFuint256The scaling factor (SF) of the funding rate.
_feeThresholduint256The threshold above which the fee will be sent.
_openExpoImbalanceLimitBpsint256The imbalance limit of the long expo for open actions (in basis points). As soon as the difference between the vault expo and the long expo exceeds this basis point limit in favor of long the open rebalancing mechanism is triggered, preventing the opening of a new long position.
_withdrawalExpoImbalanceLimitBpsint256The imbalance limit of the long expo for withdrawal actions (in basis points). As soon as the difference between vault expo and long expo exceeds this basis point limit in favor of long, the withdrawal rebalancing mechanism is triggered, preventing the withdrawal of the existing vault position.
_depositExpoImbalanceLimitBpsint256The imbalance limit of the vault expo for deposit actions (in basis points). As soon as the difference between the vault expo and the long expo exceeds this basis point limit in favor of the vault, the deposit vault rebalancing mechanism is triggered, preventing the opening of a new vault position.
_closeExpoImbalanceLimitBpsint256The imbalance limit of the vault expo for close actions (in basis points). As soon as the difference between the vault expo and the long expo exceeds this basis point limit in favor of the vault, the close rebalancing mechanism is triggered, preventing the close of an existing long position.
_rebalancerCloseExpoImbalanceLimitBpsint256The imbalance limit of the vault expo for close actions from the rebalancer (in basis points). As soon as the difference between the vault expo and the long expo exceeds this basis point limit in favor of the vault, the close rebalancing mechanism is triggered, preventing the close of an existing long position from the rebalancer contract.
_longImbalanceTargetBpsint256The target imbalance on the long side (in basis points) This value will be used to calculate how much of the missing trading expo the rebalancer position will try to compensate. A negative value means the rebalancer will compensate enough to go above the equilibrium. A positive value means the rebalancer will compensate but stay below the equilibrium.
_positionFeeBpsuint16The position fee in basis points.
_vaultFeeBpsuint16The fee for vault deposits and withdrawals, in basis points.
_sdexRewardsRatioBpsuint16The ratio of SDEX rewards to send to the user (in basis points).
__unuseduint32Old slot for _sdexBurnOnDepositRatio.
_feeCollectoraddressThe fee collector's address.
_securityDepositValueuint64The deposit required for a new position.
_targetUsdnPriceuint128The nominal (target) price of USDN (with _priceFeedDecimals).
_usdnRebaseThresholduint128The USDN price threshold to trigger a rebase (with _priceFeedDecimals).
_minLongPositionuint256The minimum long position size (with _assetDecimals).
_lastFundingPerDayint256The funding rate calculated at the last update timestamp.
_lastPriceuint128The price of the asset during the last balances update (with price feed decimals).
_lastUpdateTimestampuint128The timestamp of the last balances update.
_pendingProtocolFeeuint256The pending protocol fee accumulator.
_pendingActionsmapping(address => uint256)The pending actions by the user (1 per user max). The value stored is an index into the pendingActionsQueue deque, shifted by one. A value of 0 means no pending action. Since the deque uses uint128 indices, the highest index will not overflow when adding one.
_pendingActionsQueueDoubleEndedQueue.DequeThe queue of pending actions.
_balanceVaultuint256The balance of deposits (with _assetDecimals).
_pendingBalanceVaultint256The unreflected balance change due to pending vault actions (with _assetDecimals).
_EMAint256The exponential moving average of the funding (0.0003 at initialization).
_balanceLonguint256The balance of long positions (with _assetDecimals).
_totalExpouint256The total exposure of the long positions (with _assetDecimals).
_liqMultiplierAccumulatorHugeUint.Uint512The accumulator used to calculate the liquidation multiplier. This is the sum, for all ticks, of the total expo of positions inside the tick, multiplied by the unadjusted price of the tick which is _tickData[tickHash].liquidationPenalty below The unadjusted price is obtained with `TickMath.getPriceAtTick.
_tickVersionmapping(int24 => uint256)The liquidation tick version.
_longPositionsmapping(bytes32 => Position[])The long positions per versioned tick (liquidation price).
_tickDatamapping(bytes32 => TickData)Accumulated data for a given tick and tick version.
_highestPopulatedTickint24The highest tick with a position.
_totalLongPositionsuint256Cache of the total long positions count.
_tickBitmapLibBitmap.BitmapThe bitmap used to quickly find populated ticks.
_protocolFallbackAddraddressThe address of the fallback contract.
_noncemapping(address => uint256)The user EIP712 nonce.
_sdexBurnOnDepositRatiouint64The ratio of USDN to SDEX tokens to burn on deposit.

InitStorage

Structure to hold initial parameters for the protocol.

struct InitStorage {
    int24 tickSpacing;
    IERC20Metadata asset;
    IUsdn usdn;
    IERC20Metadata sdex;
    IBaseOracleMiddleware oracleMiddleware;
    IBaseLiquidationRewardsManager liquidationRewardsManager;
    uint256 minLeverage;
    uint256 maxLeverage;
    uint128 lowLatencyValidatorDeadline;
    uint128 onChainValidatorDeadline;
    uint256 safetyMarginBps;
    uint16 liquidationIteration;
    uint16 protocolFeeBps;
    uint16 rebalancerBonusBps;
    uint24 liquidationPenalty;
    uint128 emaPeriod;
    uint256 fundingSF;
    uint256 feeThreshold;
    int256 openExpoImbalanceLimitBps;
    int256 withdrawalExpoImbalanceLimitBps;
    int256 depositExpoImbalanceLimitBps;
    int256 closeExpoImbalanceLimitBps;
    int256 rebalancerCloseExpoImbalanceLimitBps;
    int256 longImbalanceTargetBps;
    uint16 positionFeeBps;
    uint16 vaultFeeBps;
    uint16 sdexRewardsRatioBps;
    uint64 sdexBurnOnDepositRatio;
    address feeCollector;
    uint64 securityDepositValue;
    uint128 targetUsdnPrice;
    uint128 usdnRebaseThreshold;
    uint256 minLongPosition;
    int256 EMA;
    address protocolFallbackAddr;
}

Properties

NameTypeDescription
tickSpacingint24The liquidation tick spacing for storing long positions.
assetIERC20MetadataThe asset ERC20 contract.
usdnIUsdnThe USDN ERC20 contract.
sdexIERC20MetadataThe SDEX ERC20 contract.
oracleMiddlewareIBaseOracleMiddlewareThe oracle middleware contract.
liquidationRewardsManagerIBaseLiquidationRewardsManagerThe liquidation rewards manager contract.
minLeverageuint256The minimum leverage for a position.
maxLeverageuint256The maximum leverage for a position.
lowLatencyValidatorDeadlineuint128The deadline for a user to confirm their action with a low-latency oracle.
onChainValidatorDeadlineuint128The deadline for a user to confirm their action with an on-chain oracle.
safetyMarginBpsuint256Safety margin for the liquidation price of newly open positions, in basis points.
liquidationIterationuint16The number of iterations to perform during the user's action (in tick).
protocolFeeBpsuint16The protocol fee in basis points.
rebalancerBonusBpsuint16Part of the remaining collateral that is given as a bonus to the Rebalancer upon liquidation of a tick, in basis points. The rest is sent to the Vault balance.
liquidationPenaltyuint24The liquidation penalty (in ticks).
emaPerioduint128The moving average period of the funding rate.
fundingSFuint256The scaling factor (SF) of the funding rate.
feeThresholduint256The threshold above which the fee will be sent.
openExpoImbalanceLimitBpsint256The imbalance limit of the long expo for open actions (in basis points).
withdrawalExpoImbalanceLimitBpsint256The imbalance limit of the long expo for withdrawal actions (in basis points).
depositExpoImbalanceLimitBpsint256The imbalance limit of the vault expo for deposit actions (in basis points).
closeExpoImbalanceLimitBpsint256The imbalance limit of the vault expo for close actions (in basis points).
rebalancerCloseExpoImbalanceLimitBpsint256The imbalance limit of the vault expo for close actions from the rebalancer (in basis points).
longImbalanceTargetBpsint256The target imbalance on the long side (in basis points)
positionFeeBpsuint16The position fee in basis points.
vaultFeeBpsuint16The fee for vault deposits and withdrawals, in basis points.
sdexRewardsRatioBpsuint16The ratio of SDEX rewards to send to the user (in basis points).
sdexBurnOnDepositRatiouint64The ratio of USDN to SDEX tokens to burn on deposit.
feeCollectoraddressThe fee collector's address.
securityDepositValueuint64The deposit required for a new position.
targetUsdnPriceuint128The nominal (target) price of USDN (with _priceFeedDecimals).
usdnRebaseThresholduint128The USDN price threshold to trigger a rebase (with _priceFeedDecimals).
minLongPositionuint256The minimum long position size (with _assetDecimals).
EMAint256The exponential moving average of the funding (0.0003 at initialization).
protocolFallbackAddraddressThe address of the fallback contract.

Enums

ProtocolAction

All possible action types for the protocol.

This is used for pending actions and to interact with the oracle middleware.

enum ProtocolAction {
    None,
    Initialize,
    InitiateDeposit,
    ValidateDeposit,
    InitiateWithdrawal,
    ValidateWithdrawal,
    InitiateOpenPosition,
    ValidateOpenPosition,
    InitiateClosePosition,
    ValidateClosePosition,
    Liquidation
}

LongActionOutcome

The outcome of the call targeting a long position.

enum LongActionOutcome {
    Processed,
    Liquidated,
    PendingLiquidations
}

RebalancerAction

Classifies how far in its logic the _triggerRebalancer function made it to.

Used to estimate the gas spent by the function call to more accurately calculate liquidation rewards.

enum RebalancerAction {
    None,
    NoImbalance,
    PendingLiquidation,
    NoCloseNoOpen,
    Closed,
    Opened,
    ClosedOpened
}

IUsdnProtocolVault

Git Source

Interface for the vault layer of the USDN protocol.

Functions

usdnPrice

Calculates the predicted USDN token price based on the given asset price and timestamp.

The effects of the funding and the PnL of the long positions since the last contract state update are taken into account.

function usdnPrice(uint128 currentPrice, uint128 timestamp) external view returns (uint256 price_);

Parameters

NameTypeDescription
currentPriceuint128The current or predicted asset price.
timestampuint128The timestamp corresponding to currentPrice.

Returns

NameTypeDescription
price_uint256The predicted USDN token price.

usdnPrice

Calculates the USDN token price based on the given asset price at the current timestamp.

The effects of the funding and the PnL of the long positions since the last contract state update are taken into account.

function usdnPrice(uint128 currentPrice) external view returns (uint256 price_);

Parameters

NameTypeDescription
currentPriceuint128The asset price at block.timestamp.

Returns

NameTypeDescription
price_uint256The calculated USDN token price.

vaultAssetAvailableWithFunding

Gets the amount of assets in the vault for the given asset price and timestamp.

The effects of the funding, the PnL of the long positions and the accumulated fees since the last contract state update are taken into account, but not liquidations. If the provided timestamp is older than the last state update, the function reverts with UsdnProtocolTimestampTooOld.

function vaultAssetAvailableWithFunding(uint128 currentPrice, uint128 timestamp)
    external
    view
    returns (uint256 available_);

Parameters

NameTypeDescription
currentPriceuint128The current or predicted asset price.
timestampuint128The timestamp corresponding to currentPrice (must not be earlier than _lastUpdateTimestamp).

Returns

NameTypeDescription
available_uint256The available vault balance (cannot be less than 0).

Contents

IAutoSwapperWstethSdex

Git Source

Interface for the AutoSwapperWstethSdex contract that provides automated token swapping functionality.

Functions

swapWstethToSdex

Swap wstETH to SDEX.

function swapWstethToSdex() external;

sweep

Admin function to send the contract token balance to a specified address.

function sweep(address token, address to, uint256 amount) external;

Parameters

NameTypeDescription
tokenaddressThe address of the token to send.
toaddressThe recipient address.
amountuint256The amount of tokens to send.

updateSwapSlippage

Updates the allowed slippage percentage for swaps.

function updateSwapSlippage(uint256 swapSlippage) external;

Parameters

NameTypeDescription
swapSlippageuint256The new slippage value (in basis points).

Events

FailedSwap

Emitted when a swap fails.

event FailedSwap();

SwapSlippageUpdated

Emitted when the swap slippage percentage is updated.

event SwapSlippageUpdated(uint256 newSwapSlippage);

Parameters

NameTypeDescription
newSwapSlippageuint256The new swap slippage (in basis points).

Errors

AutoSwapperSwapFailed

Thrown when a swap fails.

error AutoSwapperSwapFailed();

AutoSwapperInvalidSwapSlippage

Thrown when slippage configuration is invalid.

error AutoSwapperInvalidSwapSlippage();

AutoSwapperInvalidCaller

Thrown when the caller is not authorized to perform the operation.

error AutoSwapperInvalidCaller();

IAutoSwapperWusdnSdex

Git Source

Interface for the AutoSwapperWusdnSdex contract that provides automated token swapping functionality.

Functions

swapWusdnToSdex

Swap WUSDN to SDEX.

function swapWusdnToSdex() external;

sweep

Admin function to send the contract token balance to a specified address.

function sweep(address token, address to, uint256 amount) external;

Parameters

NameTypeDescription
tokenaddressThe address of the token to send.
toaddressThe recipient address.
amountuint256The amount of tokens to send.

getSwapSlippage

Get the current swap slippage setting (in basis points)

function getSwapSlippage() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256Current slippage tolerance

updateSwapSlippage

Updates the allowed slippage percentage for swaps.

function updateSwapSlippage(uint256 swapSlippage) external;

Parameters

NameTypeDescription
swapSlippageuint256The new slippage value (in basis points).

Events

SwapSlippageUpdated

Emitted when the swap slippage percentage is updated.

event SwapSlippageUpdated(uint256 newSwapSlippage);

Parameters

NameTypeDescription
newSwapSlippageuint256The new swap slippage (in basis points).

FailedSwap

Emitted when a swap fails.

event FailedSwap();

Errors

AutoSwapperSwapFailed

Thrown when a swap fails.

error AutoSwapperSwapFailed();

AutoSwapperInvalidSwapSlippage

Thrown when slippage configuration is invalid.

error AutoSwapperInvalidSwapSlippage();

AutoSwapperInvalidCaller

Thrown when the caller is not authorized to perform the operation.

error AutoSwapperInvalidCaller();

ISetRebaseHandlerManager

Git Source

Functions

USDN

Gets the USDN token.

function USDN() external view returns (Usdn usdn_);

Returns

NameTypeDescription
usdn_UsdnThe USDN token.

setRebaseHandler

Sets the rebase handler for the USDN token.

function setRebaseHandler(IRebaseCallback newHandler) external;

Parameters

NameTypeDescription
newHandlerIRebaseCallbackThe address of the new rebase handler.

renounceUsdnOwnership

Revokes the DEFAULT_ADMIN_ROLE on the USDN token.

function renounceUsdnOwnership() external;

IStETH

Git Source

Inherits: IERC20, IERC20Permit

Functions

getTotalPooledEther

Gets the total amount of Ether controlled by the system

function getTotalPooledEther() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256total balance in wei

setStEthPerToken

Set the amount of stETH per wstETH token (only for owner)

function setStEthPerToken(uint256 stEthAmount, IWstETH wstETH) external returns (uint256);

Parameters

NameTypeDescription
stEthAmountuint256The new amount of stETH per wstETH token
wstETHIWstETHThe wstETH contract

Returns

NameTypeDescription
<none>uint256The new amount of stETH per token

mint

Mint stETH (only for owner)

function mint(address account, uint256 amount) external;

Parameters

NameTypeDescription
accountaddressThe account to mint stETH to
amountuint256The amount of stETH to mint

submit

Deposit ETH to mint stETH

function submit(address account) external payable;

Parameters

NameTypeDescription
accountaddressThe account to mint stETH to

sweep

Sweep ETH from the contract (only for owner)

function sweep(address payable to) external;

Parameters

NameTypeDescription
toaddress payableThe account to sweep ETH to

IWstETH

Git Source

Inherits: IERC20Metadata, IERC20Permit

Functions

wrap

Exchanges stETH to wstETH

*Requirements:

  • _stETHAmount must be non-zero
  • msg.sender must approve at least _stETHAmount stETH to this contract
  • msg.sender must have at least _stETHAmount of stETH User should first approve _stETHAmount to the wstETH contract*
function wrap(uint256 _stETHAmount) external returns (uint256);

Parameters

NameTypeDescription
_stETHAmountuint256The amount of stETH to wrap in exchange for wstETH

Returns

NameTypeDescription
<none>uint256Amount of wstETH user receives after wrap

unwrap

Exchanges wstETH to stETH

*Requirements:

  • _wstETHAmount must be non-zero
  • msg.sender must have at least _wstETHAmount wstETH*
function unwrap(uint256 _wstETHAmount) external returns (uint256);

Parameters

NameTypeDescription
_wstETHAmountuint256The amount of wstETH to unwrap in exchange for stETH

Returns

NameTypeDescription
<none>uint256The amount of stETH user receives after unwrap

getWstETHByStETH

Get the amount of wstETH for a given amount of stETH

function getWstETHByStETH(uint256 _stETHAmount) external view returns (uint256);

Parameters

NameTypeDescription
_stETHAmountuint256The amount of stETH

Returns

NameTypeDescription
<none>uint256The amount of wstETH for a given stETH amount

getStETHByWstETH

Get the amount of stETH for a given amount of wstETH

function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256);

Parameters

NameTypeDescription
_wstETHAmountuint256The amount of wstETH

Returns

NameTypeDescription
<none>uint256The amount of stETH for a given wstETH amount

stEthPerToken

Get the amount of stETH for a one wstETH

function stEthPerToken() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The amount of stETH for 1 wstETH

tokensPerStEth

Get the amount of wstETH for a one stETH

function tokensPerStEth() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The amount of wstETH for a 1 stETH

stETH

Get the address of stETH

function stETH() external view returns (address);

Returns

NameTypeDescription
<none>addressThe address of stETH

Contents

Accumulator

Git Source

Library to operate on the liquidation multiplier accumulator values (512-bit integers).

This is a wrapper for HugeUint that is deployed to its own address and called via delegatecall.

Functions

add

Calculates the sum a + b of two 512-bit unsigned integers.

function add(HugeUint.Uint512 memory a, HugeUint.Uint512 memory b)
    external
    pure
    returns (HugeUint.Uint512 memory res_);

Parameters

NameTypeDescription
aHugeUint.Uint512The first operand.
bHugeUint.Uint512The second operand.

Returns

NameTypeDescription
res_HugeUint.Uint512The sum of a and b.

sub

Calculates the difference a - b of two 512-bit unsigned integers.

function sub(HugeUint.Uint512 memory a, HugeUint.Uint512 memory b)
    external
    pure
    returns (HugeUint.Uint512 memory res_);

Parameters

NameTypeDescription
aHugeUint.Uint512The first operand.
bHugeUint.Uint512The second operand.

Returns

NameTypeDescription
res_HugeUint.Uint512The difference a - b.

mul

Calculates the product a * b of two 256-bit unsigned integers using the Chinese remainder theorem.

function mul(uint256 a, uint256 b) external pure returns (HugeUint.Uint512 memory res_);

Parameters

NameTypeDescription
auint256The first operand.
buint256The second operand.

Returns

NameTypeDescription
res_HugeUint.Uint512The product a * b of the operands as an unsigned 512-bit integer.

mul

Calculates the product a * b of a 512-bit unsigned integer and a 256-bit unsigned integer.

function mul(HugeUint.Uint512 memory a, uint256 b) external pure returns (HugeUint.Uint512 memory res_);

Parameters

NameTypeDescription
aHugeUint.Uint512The first operand.
buint256The second operand.

Returns

NameTypeDescription
res_HugeUint.Uint512The product a * b of the operands as an unsigned 512-bit integer.

div

Calculates the division floor(a / b) of a 512-bit unsigned integer by an unsigned 256-bit integer.

function div(HugeUint.Uint512 memory a, uint256 b) external pure returns (uint256 res_);

Parameters

NameTypeDescription
aHugeUint.Uint512The numerator as a 512-bit unsigned integer.
buint256The denominator as a 256-bit unsigned integer.

Returns

NameTypeDescription
res_uint256The division floor(a / b) of the operands as an unsigned 256-bit integer.

div

Computes the division floor(a/b) of two 512-bit integers, knowing the result fits inside a uint256.

function div(HugeUint.Uint512 memory a, HugeUint.Uint512 memory b) external pure returns (uint256 res_);

Parameters

NameTypeDescription
aHugeUint.Uint512The numerator as a 512-bit integer.
bHugeUint.Uint512The denominator as a 512-bit integer.

Returns

NameTypeDescription
res_uint256The quotient floor(a/b).

DoubleEndedQueue

Git Source

A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of the sequence (called front and back).

Storage use is optimized, and all operations are O(1) constant time. The struct is called Deque and holds PendingAction's. This data structure can only be used in storage, and not in memory.

Functions

pushBack

Inserts an item at the end of the queue. Reverts with QueueFull if the queue is full.

function pushBack(Deque storage deque, Types.PendingAction memory value) external returns (uint128 backIndex_);

Parameters

NameTypeDescription
dequeDequeThe queue.
valueTypes.PendingActionThe item to insert.

Returns

NameTypeDescription
backIndex_uint128The raw index of the inserted item.

popBack

Removes the item at the end of the queue and returns it. Reverts with QueueEmpty if the queue is empty.

function popBack(Deque storage deque) public returns (Types.PendingAction memory value_);

Parameters

NameTypeDescription
dequeDequeThe queue.

Returns

NameTypeDescription
value_Types.PendingActionThe removed item.

pushFront

Inserts an item at the beginning of the queue. Reverts with QueueFull if the queue is full.

function pushFront(Deque storage deque, Types.PendingAction memory value) external returns (uint128 frontIndex_);

Parameters

NameTypeDescription
dequeDequeThe queue.
valueTypes.PendingActionThe item to insert.

Returns

NameTypeDescription
frontIndex_uint128The raw index of the inserted item.

popFront

Removes the item at the beginning of the queue and returns it. Reverts with QueueEmpty if the queue is empty.

function popFront(Deque storage deque) public returns (Types.PendingAction memory value_);

Parameters

NameTypeDescription
dequeDequeThe queue.

Returns

NameTypeDescription
value_Types.PendingActionThe removed item.

front

Returns the item at the beginning of the queue. Reverts with QueueEmpty if the queue is empty.

function front(Deque storage deque) external view returns (Types.PendingAction memory value_, uint128 rawIndex_);

Parameters

NameTypeDescription
dequeDequeThe queue.

Returns

NameTypeDescription
value_Types.PendingActionThe item at the front of the queue.
rawIndex_uint128The raw index of the returned item.

back

Returns the item at the end of the queue. Reverts with QueueEmpty if the queue is empty.

function back(Deque storage deque) external view returns (Types.PendingAction memory value_, uint128 rawIndex_);

Parameters

NameTypeDescription
dequeDequeThe queue.

Returns

NameTypeDescription
value_Types.PendingActionThe item at the back of the queue.
rawIndex_uint128The raw index of the returned item.

at

Returns the item at a position in the queue given by index, with the first item at 0 and the last item at length(deque) - 1. Reverts with QueueOutOfBounds if the index is out of bounds.

function at(Deque storage deque, uint256 index)
    external
    view
    returns (Types.PendingAction memory value_, uint128 rawIndex_);

Parameters

NameTypeDescription
dequeDequeThe queue.
indexuint256The index of the item to return.

Returns

NameTypeDescription
value_Types.PendingActionThe item at the given index.
rawIndex_uint128The raw index of the item.

atRaw

Returns the item at a position in the queue given by rawIndex, indexing into the underlying storage array directly. Reverts with QueueOutOfBounds if the index is out of bounds.

function atRaw(Deque storage deque, uint128 rawIndex) external view returns (Types.PendingAction memory value_);

Parameters

NameTypeDescription
dequeDequeThe queue.
rawIndexuint128The index of the item to return.

Returns

NameTypeDescription
value_Types.PendingActionThe item at the given index.

clearAt

Deletes the item at a position in the queue given by rawIndex, indexing into the underlying storage array directly. If clearing the front or back item, then the bounds are updated. Otherwise, the values are simply set to zero and the queue's begin and end indices are not updated.

function clearAt(Deque storage deque, uint128 rawIndex) external;

Parameters

NameTypeDescription
dequeDequeThe queue.
rawIndexuint128The index of the item to delete.

isValid

Checks if the raw index is valid (in bounds).

function isValid(Deque storage deque, uint128 rawIndex) public view returns (bool valid_);

Parameters

NameTypeDescription
dequeDequeThe queue.
rawIndexuint128The raw index to check.

Returns

NameTypeDescription
valid_boolWhether the raw index is valid.

length

Returns the number of items in the queue.

function length(Deque storage deque) public view returns (uint256 length_);

Parameters

NameTypeDescription
dequeDequeThe queue.

Returns

NameTypeDescription
length_uint256The number of items in the queue.

empty

Returns true if the queue is empty.

function empty(Deque storage deque) internal view returns (bool empty_);

Parameters

NameTypeDescription
dequeDequeThe queue.

Returns

NameTypeDescription
empty_boolTrue if the queue is empty.

Errors

QueueEmpty

An operation (e.g. front) couldn't be completed due to the queue being empty.

error QueueEmpty();

QueueFull

A push operation couldn't be completed due to the queue being full.

error QueueFull();

QueueOutOfBounds

An operation (e.g. atRaw) couldn't be completed due to an index being out of bounds.

error QueueOutOfBounds();

Structs

Deque

Indices are 128 bits so begin and end are packed in a single storage slot for efficient access. Struct members have an underscore prefix indicating that they are "private" and should not be read or written to directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and lead to unexpected behavior. The first item is at data[begin] and the last item is at data[end - 1]. This range can wrap around.

struct Deque {
    uint128 _begin;
    uint128 _end;
    mapping(uint128 index => Types.PendingAction) _data;
}

Properties

NameTypeDescription
_beginuint128The index of the first item in the queue.
_enduint128The index of the item after the last item in the queue.
_datamapping(uint128 index => Types.PendingAction)The items in the queue.

SignedMath

Git Source

Performs signed math operations safely, reverting with a custom error in case of overflow.

Functions

safeAdd

Safely adds two signed integers, reverting on overflow.

function safeAdd(int256 lhs, int256 rhs) internal pure returns (int256 res_);

Parameters

NameTypeDescription
lhsint256The left-hand side operand.
rhsint256The right-hand side operand.

Returns

NameTypeDescription
res_int256The result of lhs + rhs.

safeSub

Safely subtracts two signed integers, reverting on overflow.

function safeSub(int256 lhs, int256 rhs) internal pure returns (int256 res_);

Parameters

NameTypeDescription
lhsint256The left-hand side operand.
rhsint256The right-hand side operand.

Returns

NameTypeDescription
res_int256The result of lhs - rhs.

safeMul

Safely multiplies two signed integers, reverting on overflow.

function safeMul(int256 lhs, int256 rhs) internal pure returns (int256 res_);

Parameters

NameTypeDescription
lhsint256The left-hand side operand.
rhsint256The right-hand side operand.

Returns

NameTypeDescription
res_int256The result of lhs * rhs.

safeDiv

Safely divides two signed integers, reverting on division by zero.

function safeDiv(int256 lhs, int256 rhs) internal pure returns (int256 res_);

Parameters

NameTypeDescription
lhsint256The left-hand side operand.
rhsint256The right-hand side operand.

Returns

NameTypeDescription
res_int256The result of lhs / rhs.

Errors

SignedMathOverflowedAdd

The signed add operation overflowed.

error SignedMathOverflowedAdd(int256 lhs, int256 rhs);

Parameters

NameTypeDescription
lhsint256The left-hand side operand.
rhsint256The right-hand side operand.

SignedMathOverflowedSub

The signed sub operation overflowed.

error SignedMathOverflowedSub(int256 lhs, int256 rhs);

Parameters

NameTypeDescription
lhsint256The left-hand side operand.
rhsint256The right-hand side operand.

SignedMathOverflowedMul

The signed mul operation overflowed.

error SignedMathOverflowedMul(int256 lhs, int256 rhs);

Parameters

NameTypeDescription
lhsint256The left-hand side operand.
rhsint256The right-hand side operand.

SignedMathOverflowedDiv

The signed div operation overflowed.

error SignedMathOverflowedDiv(int256 lhs, int256 rhs);

Parameters

NameTypeDescription
lhsint256The left-hand side operand.
rhsint256The right-hand side operand.

SignedMathDivideByZero

A division by zero occurred.

error SignedMathDivideByZero(int256 lhs);

Parameters

NameTypeDescription
lhsint256The left-hand side operand.

TickMath

Git Source

Converts between prices and ticks, where each tick represents an increase in price of 0.01%. Ticks are used instead of liquidation prices to limit the number of possible buckets where a position can land, and allows for batched liquidations.

The formula for calculating the price from a tick is: price = 1.0001^(tick). The formula for calculating the tick from a price is: tick = log_1.0001(price).

State Variables

MIN_TICK

The minimum price we want to resolve is 10_000 wei (1e-14 USD), which equates to 1.0001^-322378.

int24 public constant MIN_TICK = -322_378;

MAX_TICK

The maximum tick is determined by the limits of the libraries used for math and testing.

int24 public constant MAX_TICK = 980_000;

MIN_PRICE

The minimum representable values for the price.

uint256 public constant MIN_PRICE = 10_000;

MAX_PRICE

The maximum representable values for the price.

uint256 public constant MAX_PRICE = 3_620_189_675_065_328_806_679_850_654_316_367_931_456_599_175_372_999_068_724_197;

LN_BASE

Pre-computed value for ln(1.0001).

int256 public constant LN_BASE = 99_995_000_333_308;

Functions

maxUsableTick

Gets the largest usable tick, given a tick spacing.

function maxUsableTick(int24 tickSpacing) external pure returns (int24 tick_);

Parameters

NameTypeDescription
tickSpacingint24Only uses ticks that are a multiple of this value.

Returns

NameTypeDescription
tick_int24The largest tick that can be used.

minUsableTick

Gets the smallest usable tick, given a tick spacing.

function minUsableTick(int24 tickSpacing) external pure returns (int24 tick_);

Parameters

NameTypeDescription
tickSpacingint24Only uses ticks that are a multiple of this value.

Returns

NameTypeDescription
tick_int24The smallest tick that can be used.

getPriceAtTick

Gets the price at a given tick.

Calculates the price as 1.0001^tick = e^(tick * ln(1.0001)).

function getPriceAtTick(int24 tick) public pure returns (uint256 price_);

Parameters

NameTypeDescription
tickint24The tick.

Returns

NameTypeDescription
price_uint256The corresponding price.

getTickAtPrice

Gets the tick corresponding to a price, rounded down towards negative infinity.

log_1.0001(price) = ln(price)/ln(1.0001) gives the tick.

function getTickAtPrice(uint256 price) external pure returns (int24 tick_);

Parameters

NameTypeDescription
priceuint256The price.

Returns

NameTypeDescription
tick_int24The largest tick whose price is less than or equal to the given price.

Errors

TickMathInvalidTickSpacing

The provided tick spacing is invalid (zero).

error TickMathInvalidTickSpacing();

TickMathInvalidTick

The provided tick is out of bounds.

error TickMathInvalidTick();

TickMathInvalidPrice

The provided price is out of bounds.

error TickMathInvalidPrice();

Contents

AutoSwapperWstethSdex

Git Source

Inherits: Ownable2Step, IAutoSwapperWstethSdex, IFeeCollectorCallback, ERC165, ISmardexSwapCallback, IUniswapV3SwapCallback

Automates protocol fee conversion from wstETH to SDEX via Uniswap V3 and Smardex.

State Variables

BPS_DIVISOR

Decimal points for basis points (bps).

uint16 internal constant BPS_DIVISOR = 10_000;

WSTETH

Wrapped staked ETH token address.

IWstETH internal constant WSTETH = IWstETH(0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0);

WETH

Wrapped ETH token address.

IERC20 internal constant WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);

SMARDEX_WETH_SDEX_PAIR

SmarDex pair address for WETH/SDEX swaps.

ISmardexPair internal constant SMARDEX_WETH_SDEX_PAIR = ISmardexPair(0xf3a4B8eFe3e3049F6BC71B47ccB7Ce6665420179);

UNI_WSTETH_WETH_PAIR

Uniswap V3 pair address for WSTETH/WETH swaps.

IUniswapV3Pool internal constant UNI_WSTETH_WETH_PAIR = IUniswapV3Pool(0x109830a1AAaD605BbF02a9dFA7B0B92EC2FB7dAa);

_swapSlippage

Allowed slippage for swaps (in basis points).

uint256 internal _swapSlippage = 100;

Functions

constructor

constructor() Ownable(msg.sender);

feeCollectorCallback

Called by the USDN protocol on the fee collector contract when the fee threshold is reached.

function feeCollectorCallback(uint256) external;

Parameters

NameTypeDescription
<none>uint256

swapWstethToSdex

Swap wstETH to SDEX.

function swapWstethToSdex() external;

uniswapV3SwapCallback

Called to msg.sender after executing a swap via IUniswapV3Pool#swap.

In the implementation you must pay the pool tokens owed for the swap. The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. amount0Delta and amount1Delta can both be 0 if no tokens were swapped.

function uniswapV3SwapCallback(int256 amountWstethIn, int256, bytes calldata) external;

Parameters

NameTypeDescription
amountWstethInint256
<none>int256
<none>bytes

smardexSwapCallback

callback data for swap

function smardexSwapCallback(int256, int256 amountWethIn, bytes calldata) external;

Parameters

NameTypeDescription
<none>int256
amountWethInint256
<none>bytes

sweep

Admin function to send the contract token balance to a specified address.

function sweep(address token, address to, uint256 amount) external onlyOwner;

Parameters

NameTypeDescription
tokenaddressThe address of the token to send.
toaddressThe recipient address.
amountuint256The amount of tokens to send.

updateSwapSlippage

Updates the allowed slippage percentage for swaps.

function updateSwapSlippage(uint256 newSwapSlippage) external onlyOwner;

Parameters

NameTypeDescription
newSwapSlippageuint256

supportsInterface

See {IERC165-supportsInterface}.

function supportsInterface(bytes4 interfaceId) public view override(ERC165, IERC165) returns (bool);

_uniWstethToWeth

Swaps wstETH for WETH on Uniswap V3.

function _uniWstethToWeth() internal;

_smarDexWethToSdex

Swaps WETH for SDEX token using the SmarDex protocol.

function _smarDexWethToSdex() internal;

AutoSwapperWusdnSdex

Git Source

Inherits: Ownable2Step, IAutoSwapperWusdnSdex, IFeeCollectorCallback, ERC165, ISmardexSwapCallback

Automates protocol fee conversion from WUSDN to SDEX via Smardex.

State Variables

BPS_DIVISOR

Decimal points for basis points (bps).

uint16 internal constant BPS_DIVISOR = 10_000;

WUSDN

Wrapped USDN token address.

IERC20 internal constant WUSDN = IERC20(0x99999999999999Cc837C997B882957daFdCb1Af9);

SMARDEX_WUSDN_SDEX_PAIR

SmarDex pair address for WUSDN/SDEX swaps.

ISmardexPair internal constant SMARDEX_WUSDN_SDEX_PAIR = ISmardexPair(0x11443f5B134c37903705e64129BEFc20e35a3725);

FEE_LP

Fee rates for LP on the SmarDex pair.

uint128 internal immutable FEE_LP;

FEE_POOL

Fee rates for the pool on the SmarDex pair.

uint128 internal immutable FEE_POOL;

_swapSlippage

Allowed slippage for swaps (in basis points).

uint256 internal _swapSlippage = 100;

Functions

constructor

constructor() Ownable(msg.sender);

feeCollectorCallback

Called by the USDN protocol on the fee collector contract when the fee threshold is reached.

function feeCollectorCallback(uint256) external;

Parameters

NameTypeDescription
<none>uint256

swapWusdnToSdex

Swap WUSDN to SDEX.

function swapWusdnToSdex() external;

smardexSwapCallback

callback data for swap

function smardexSwapCallback(int256, int256 amountWusdnIn, bytes calldata) external;

Parameters

NameTypeDescription
<none>int256
amountWusdnInint256
<none>bytes

sweep

Admin function to send the contract token balance to a specified address.

function sweep(address token, address to, uint256 amount) external onlyOwner;

Parameters

NameTypeDescription
tokenaddressThe address of the token to send.
toaddressThe recipient address.
amountuint256The amount of tokens to send.

getSwapSlippage

Get the current swap slippage setting (in basis points)

function getSwapSlippage() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256Current slippage tolerance

updateSwapSlippage

Updates the allowed slippage percentage for swaps.

function updateSwapSlippage(uint256 newSwapSlippage) external onlyOwner;

Parameters

NameTypeDescription
newSwapSlippageuint256

supportsInterface

See {IERC165-supportsInterface}.

function supportsInterface(bytes4 interfaceId) public view override(ERC165, IERC165) returns (bool);

_quoteAmountOut

Calculates the amount of SDEX that can be obtained from a given amount of WUSDN.

function _quoteAmountOut(uint256 amountIn) internal view returns (uint256 amountOut_);

Parameters

NameTypeDescription
amountInuint256The amount of WUSDN to swap

Returns

NameTypeDescription
amountOut_uint256The amount of SDEX that can be obtained

FeeCollector

Git Source

Inherits: IFeeCollectorCallback, ERC165

Minimum implementation of the fee collector contract.

Functions

supportsInterface

See {IERC165-supportsInterface}.

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

feeCollectorCallback

Called by the USDN protocol on the fee collector contract when the fee threshold is reached.

function feeCollectorCallback(uint256 feeAmount) external virtual;

Parameters

NameTypeDescription
feeAmountuint256The amount of the fee that was transferred to the fee collector.

InitializableReentrancyGuard

Git Source

Contract module that helps prevent reentrant calls to a function and ensures the initializer has been called. Based on the OpenZeppelin implementation.

State Variables

UNINITIALIZED

The uninitialized state of the contract.

uint256 private constant UNINITIALIZED = 0;

NOT_ENTERED

The state of the contract before entering a function.

uint256 private constant NOT_ENTERED = 1;

ENTERED

The state of the contract after entering a function.

uint256 private constant ENTERED = 2;

STORAGE_STATUS

The storage slot of the InitializableReentrancyGuardStorage struct.

keccak256(abi.encode(uint256(keccak256("InitializableReentrancyGuard.storage.status")) - 1)) & ~bytes32(uint256(0xff))

bytes32 private constant STORAGE_STATUS = 0x6f33a3bc64034eea47937f56d5e165f09a61a6a995142939d6f3e40f101ea600;

Functions

_getInitializableReentrancyGuardStorage

Gets the struct pointer of the contract storage.

function _getInitializableReentrancyGuardStorage()
    internal
    pure
    returns (InitializableReentrancyGuardStorage storage s_);

Returns

NameTypeDescription
s_InitializableReentrancyGuardStorageThe pointer to the struct.

__initializeReentrancyGuard_init

Initializes the storage slot on first deployment.

function __initializeReentrancyGuard_init() internal;

initializedAndNonReentrant

Reverts if the contract is not initialized or in case of a reentrancy.

Prevents a contract from calling itself, directly or indirectly, or using it in an uninitialized state. Calling an initializedAndNonReentrant function before the initialize function was called will revert. Calling an initializedAndNonReentrant function from another initializedAndNonReentrant function is not supported.

modifier initializedAndNonReentrant();

protocolInitializer

Reverts if the contract is initialized, or sets it as initialized.

modifier protocolInitializer();

_checkInitialized

Reverts if the contract is not initialized.

function _checkInitialized() private view;

_checkUninitialized

Reverts if the contract is initialized.

function _checkUninitialized() internal view;

_nonReentrantBefore

Reverts if _status is ENTERED, or sets it to ENTERED.

function _nonReentrantBefore() private;

_nonReentrantAfter

Sets _status to NOT_ENTERED

function _nonReentrantAfter() private;

Errors

InitializableReentrancyGuardReentrantCall

Unauthorized reentrant call.

error InitializableReentrancyGuardReentrantCall();

InitializableReentrancyGuardUninitialized

Contract was not yet initialized.

error InitializableReentrancyGuardUninitialized();

InitializableReentrancyGuardInvalidInitialization

Contract was already initialized.

error InitializableReentrancyGuardInvalidInitialization();

Structs

InitializableReentrancyGuardStorage

The storage structure of the contract.

Booleans are more expensive than uint256 or any type that takes up a full word because each write operation emits an extra SLOAD to first read the slot's contents, replace the bits taken up by the boolean and then write back. This is the compiler's defense against contract upgrades and pointer aliasing, and it cannot be disabled.

Note: storage-location: erc7201:InitializableReentrancyGuard.storage.status

struct InitializableReentrancyGuardStorage {
    uint256 _status;
}

Properties

NameTypeDescription
_statusuint256The state of the contract.

SetRebaseHandlerManager

Git Source

Inherits: ISetRebaseHandlerManager, Ownable2Step

This contract is meant to be the DefaultAdmin role of the USDN token, and it should only have the ability to set the rebase handler.

State Variables

USDN

Gets the USDN token.

Usdn public immutable USDN;

Functions

constructor

constructor(Usdn usdn, address owner) Ownable(owner);

Parameters

NameTypeDescription
usdnUsdnThe address of the USDN token contract.
owneraddressThe address of the owner.

setRebaseHandler

Sets the rebase handler for the USDN token.

function setRebaseHandler(IRebaseCallback newHandler) external onlyOwner;

Parameters

NameTypeDescription
newHandlerIRebaseCallbackThe address of the new rebase handler.

renounceUsdnOwnership

Revokes the DEFAULT_ADMIN_ROLE on the USDN token.

function renounceUsdnOwnership() external onlyOwner;

IWusdnBalancerAdaptor

Git Source

Functions

WUSDN

Gets the WUSDN token.

function WUSDN() external view returns (IWusdn wusdn_);

Returns

NameTypeDescription
wusdn_IWusdnThe WUSDN token.

getRate

Gets the current redemption rate.

function getRate() external view returns (uint256 rate_);

Returns

NameTypeDescription
rate_uint256Number of USDN tokens per WUSDN token.

WusdnBalancerAdaptor

Git Source

Inherits: IWusdnBalancerAdaptor

State Variables

WUSDN

Gets the WUSDN token.

IWusdn public immutable WUSDN;

Functions

constructor

constructor(IWusdn wusdn);

Parameters

NameTypeDescription
wusdnIWusdnThe address of the WUSDN token.

getRate

Gets the current redemption rate.

function getRate() external view returns (uint256 rate_);

Returns

NameTypeDescription
rate_uint256Number of USDN tokens per WUSDN token.