Skip to content

Latest commit

 

History

History
978 lines (787 loc) · 29.5 KB

PriceFeeds.md

File metadata and controls

978 lines (787 loc) · 29.5 KB

PriceFeeds.sol

View Source: contracts/feeds/PriceFeeds.sol

↗ Extends: Constants, Ownable ↘ Derived Contracts: PriceFeedsLocal

PriceFeeds contract

Contract Members

Constants & Variables

mapping(address => contract IPriceFeedsExt) public pricesFeeds;
mapping(address => uint256) public decimals;
uint256 public protocolTokenEthPrice;
bool public globalPricingPaused;

Events

event GlobalPricingPaused(address indexed sender, bool indexed isPaused);

Functions


latestAnswer

function latestAnswer() external view
returns(uint256)
Source Code
function latestAnswer() external view returns (uint256);

constructor

Contract deployment requires 3 parameters. *

function (address _wrbtcTokenAddress, address _protocolTokenAddress, address _baseTokenAddress) public nonpayable

Arguments

Name Type Description
_wrbtcTokenAddress address The address of the wrapped wrBTC token.
_protocolTokenAddress address The address of the protocol token.
_baseTokenAddress address The address of the base token.
Source Code
constructor(
        address _wrbtcTokenAddress,
        address _protocolTokenAddress,
        address _baseTokenAddress
    ) public {
        /// Set decimals for this token.
        decimals[address(0)] = 18;
        decimals[_wrbtcTokenAddress] = 18;
        _setWrbtcToken(_wrbtcTokenAddress);
        _setProtocolTokenAddress(_protocolTokenAddress);
        _setBaseToken(_baseTokenAddress);
    }

queryRate

Calculate the price ratio between two tokens. *

function queryRate(address sourceToken, address destToken) public view
returns(rate uint256, precision uint256)

Arguments

Name Type Description
sourceToken address The address of the source tokens.
destToken address The address of the destiny tokens. *

Returns

rate The price ratio source/dest.

Source Code
function queryRate(address sourceToken, address destToken)
        public
        view
        returns (uint256 rate, uint256 precision)
    {
        return _queryRate(sourceToken, destToken);
    }

queryPrecision

Calculate the relative precision between two tokens. *

function queryPrecision(address sourceToken, address destToken) public view
returns(uint256)

Arguments

Name Type Description
sourceToken address The address of the source tokens.
destToken address The address of the destiny tokens. *

Returns

The precision ratio source/dest.

Source Code
function queryPrecision(address sourceToken, address destToken) public view returns (uint256) {
        return sourceToken != destToken ? _getDecimalPrecision(sourceToken, destToken) : 10**18;
    }

queryReturn

Price conversor: Calculate the price of an amount of source tokens in destiny token units. *

function queryReturn(address sourceToken, address destToken, uint256 sourceAmount) public view
returns(destAmount uint256)

Arguments

Name Type Description
sourceToken address The address of the source tokens.
destToken address The address of the destiny tokens.
sourceAmount uint256 The amount of the source tokens. *

Returns

destAmount The amount of destiny tokens equivalent in price to the amount of source tokens.

Source Code
function queryReturn(
        address sourceToken,
        address destToken,
        uint256 sourceAmount
    ) public view returns (uint256 destAmount) {
        if (globalPricingPaused) {
            return 0;
        }

        (uint256 rate, uint256 precision) = _queryRate(sourceToken, destToken);

        destAmount = sourceAmount.mul(rate).div(precision);
    }

checkPriceDisagreement

Calculate the swap rate between two tokens. * Regarding slippage, there is a hardcoded slippage limit of 5%, enforced by this function for all borrowing, lending and margin trading originated swaps performed in the Sovryn exchange. * This means all operations in the Sovryn exchange are subject to losing up to 5% from the internal swap performed. *

function checkPriceDisagreement(address sourceToken, address destToken, uint256 sourceAmount, uint256 destAmount, uint256 maxSlippage) public view
returns(sourceToDestSwapRate uint256)

Arguments

Name Type Description
sourceToken address The address of the source tokens.
destToken address The address of the destiny tokens.
sourceAmount uint256 The amount of source tokens.
destAmount uint256 The amount of destiny tokens.
maxSlippage uint256 The maximum slippage limit. *

Returns

sourceToDestSwapRate The swap rate between tokens.

Source Code
function checkPriceDisagreement(
        address sourceToken,
        address destToken,
        uint256 sourceAmount,
        uint256 destAmount,
        uint256 maxSlippage
    ) public view returns (uint256 sourceToDestSwapRate) {
        require(!globalPricingPaused, "pricing is paused");
        (uint256 rate, uint256 precision) = _queryRate(sourceToken, destToken);

        sourceToDestSwapRate = destAmount.mul(precision).div(sourceAmount);

        if (rate > sourceToDestSwapRate) {
            uint256 spreadValue = rate - sourceToDestSwapRate;
            spreadValue = spreadValue.mul(10**20).div(sourceToDestSwapRate);
            require(spreadValue <= maxSlippage, "price disagreement");
        }
    }

amountInEth

Calculate the rBTC amount equivalent to a given token amount. Native coin on RSK is rBTC. This code comes from Ethereum applications, so Eth refers to 10**18 weis of native coin, i.e.: 1 rBTC. *

function amountInEth(address tokenAddress, uint256 amount) public view
returns(ethAmount uint256)

Arguments

Name Type Description
tokenAddress address The address of the token to calculate price.
amount uint256 The amount of tokens to calculate price. *

Returns

ethAmount The amount of rBTC equivalent.

Source Code
function amountInEth(address tokenAddress, uint256 amount)
        public
        view
        returns (uint256 ethAmount)
    {
        /// Token is wrBTC, amount in rBTC is the same.
        if (tokenAddress == address(wrbtcToken)) {
            ethAmount = amount;
        } else {
            (uint256 toEthRate, uint256 toEthPrecision) =
                queryRate(tokenAddress, address(wrbtcToken));
            ethAmount = amount.mul(toEthRate).div(toEthPrecision);
        }
    }

getMaxDrawdown

Calculate the maximum drawdown of a loan. * A drawdown is commonly defined as the decline from a high peak to a pullback low of a specific investment or equity in an account. * Drawdown magnitude refers to the amount of value that a user loses during the drawdown period. *

function getMaxDrawdown(address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount, uint256 margin) public view
returns(maxDrawdown uint256)

Arguments

Name Type Description
loanToken address The address of the loan token.
collateralToken address The address of the collateral token.
loanAmount uint256 The amount of the loan.
collateralAmount uint256 The amount of the collateral.
margin uint256 The relation between the position size and the loan. margin = (total position size - loan) / loan *

Returns

maxDrawdown The maximum drawdown.

Source Code
function getMaxDrawdown(
        address loanToken,
        address collateralToken,
        uint256 loanAmount,
        uint256 collateralAmount,
        uint256 margin
    ) public view returns (uint256 maxDrawdown) {
        uint256 loanToCollateralAmount;
        if (collateralToken == loanToken) {
            loanToCollateralAmount = loanAmount;
        } else {
            (uint256 rate, uint256 precision) = queryRate(loanToken, collateralToken);
            loanToCollateralAmount = loanAmount.mul(rate).div(precision);
        }

        uint256 combined =
            loanToCollateralAmount.add(loanToCollateralAmount.mul(margin).div(10**20));

        maxDrawdown = collateralAmount > combined ? collateralAmount - combined : 0;
    }

getCurrentMarginAndCollateralSize

Calculate the margin and the collateral on rBTC. *

function getCurrentMarginAndCollateralSize(address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount) public view
returns(currentMargin uint256, collateralInEthAmount uint256)

Arguments

Name Type Description
loanToken address The address of the loan token.
collateralToken address The address of the collateral token.
loanAmount uint256 The amount of the loan.
collateralAmount uint256 The amount of the collateral. *

Returns

currentMargin The margin of the loan.

Source Code
function getCurrentMarginAndCollateralSize(
        address loanToken,
        address collateralToken,
        uint256 loanAmount,
        uint256 collateralAmount
    ) public view returns (uint256 currentMargin, uint256 collateralInEthAmount) {
        (currentMargin, ) = getCurrentMargin(
            loanToken,
            collateralToken,
            loanAmount,
            collateralAmount
        );

        collateralInEthAmount = amountInEth(collateralToken, collateralAmount);
    }

getCurrentMargin

Calculate the margin of a loan. *

function getCurrentMargin(address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount) public view
returns(currentMargin uint256, collateralToLoanRate uint256)

Arguments

Name Type Description
loanToken address The address of the loan token.
collateralToken address The address of the collateral token.
loanAmount uint256 The amount of the loan.
collateralAmount uint256 The amount of the collateral. *

Returns

currentMargin The margin of the loan.

Source Code
function getCurrentMargin(
        address loanToken,
        address collateralToken,
        uint256 loanAmount,
        uint256 collateralAmount
    ) public view returns (uint256 currentMargin, uint256 collateralToLoanRate) {
        uint256 collateralToLoanAmount;
        if (collateralToken == loanToken) {
            collateralToLoanAmount = collateralAmount;
            collateralToLoanRate = 10**18;
        } else {
            uint256 collateralToLoanPrecision;
            (collateralToLoanRate, collateralToLoanPrecision) = queryRate(
                collateralToken,
                loanToken
            );

            collateralToLoanRate = collateralToLoanRate.mul(10**18).div(collateralToLoanPrecision);

            collateralToLoanAmount = collateralAmount.mul(collateralToLoanRate).div(10**18);
        }

        if (loanAmount != 0 && collateralToLoanAmount >= loanAmount) {
            return (
                collateralToLoanAmount.sub(loanAmount).mul(10**20).div(loanAmount),
                collateralToLoanRate
            );
        } else {
            return (0, collateralToLoanRate);
        }
    }

shouldLiquidate

Get assessment about liquidating a loan. *

function shouldLiquidate(address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount, uint256 maintenanceMargin) public view
returns(bool)

Arguments

Name Type Description
loanToken address The address of the loan token.
collateralToken address The address of the collateral token.
loanAmount uint256 The amount of the loan.
collateralAmount uint256 The amount of the collateral.
maintenanceMargin uint256 The minimum margin before liquidation. *

Returns

True/false to liquidate the loan.

Source Code
function shouldLiquidate(
        address loanToken,
        address collateralToken,
        uint256 loanAmount,
        uint256 collateralAmount,
        uint256 maintenanceMargin
    ) public view returns (bool) {
        (uint256 currentMargin, ) =
            getCurrentMargin(loanToken, collateralToken, loanAmount, collateralAmount);

        return currentMargin <= maintenanceMargin;
    }

setProtocolTokenEthPrice

Set new value for protocolTokenEthPrice *

function setProtocolTokenEthPrice(uint256 newPrice) external nonpayable onlyOwner 

Arguments

Name Type Description
newPrice uint256 The new value for protocolTokenEthPrice
Source Code
function setProtocolTokenEthPrice(uint256 newPrice) external onlyOwner {
        require(newPrice != 0, "invalid price");
        protocolTokenEthPrice = newPrice;
    }

setPriceFeed

Populate pricesFeeds mapping w/ values from feeds[] *

function setPriceFeed(address[] tokens, IPriceFeedsExt[] feeds) external nonpayable onlyOwner 

Arguments

Name Type Description
tokens address[] The array of tokens to loop and get addresses.
feeds IPriceFeedsExt[] The array of contract instances for every token.
Source Code
function setPriceFeed(address[] calldata tokens, IPriceFeedsExt[] calldata feeds)
        external
        onlyOwner
    {
        require(tokens.length == feeds.length, "count mismatch");

        for (uint256 i = 0; i < tokens.length; i++) {
            pricesFeeds[tokens[i]] = feeds[i];
        }
    }

setDecimals

Populate decimals mapping w/ values from tokens[].decimals *

function setDecimals(IERC20[] tokens) external nonpayable onlyOwner 

Arguments

Name Type Description
tokens IERC20[] The array of tokens to loop and get values from.
Source Code
function setDecimals(IERC20[] calldata tokens) external onlyOwner {
        for (uint256 i = 0; i < tokens.length; i++) {
            decimals[address(tokens[i])] = tokens[i].decimals();
        }
    }

setGlobalPricingPaused

Set flag globalPricingPaused *

function setGlobalPricingPaused(bool isPaused) external nonpayable onlyOwner 

Arguments

Name Type Description
isPaused bool The new status of pause (true/false).
Source Code
function setGlobalPricingPaused(bool isPaused) external onlyOwner {
        if (globalPricingPaused != isPaused) {
            globalPricingPaused = isPaused;

            emit GlobalPricingPaused(msg.sender, isPaused);
        }
    }

_queryRate

⤿ Overridden Implementation(s): PriceFeedsLocal._queryRate

Calculate the price ratio between two tokens. *

function _queryRate(address sourceToken, address destToken) internal view
returns(rate uint256, precision uint256)

Arguments

Name Type Description
sourceToken address The address of the source tokens.
destToken address The address of the destiny tokens. *

Returns

rate The price ratio source/dest.

Source Code
function _queryRate(address sourceToken, address destToken)
        internal
        view
        returns (uint256 rate, uint256 precision)
    {
        require(!globalPricingPaused, "pricing is paused");

        /// Different tokens, query prices and perform division.
        if (sourceToken != destToken) {
            uint256 sourceRate;
            if (sourceToken != address(baseToken) && sourceToken != protocolTokenAddress) {
                IPriceFeedsExt _sourceFeed = pricesFeeds[sourceToken];
                require(address(_sourceFeed) != address(0), "unsupported src feed");

                /// Query token price on priceFeedsExt instance.
                sourceRate = _sourceFeed.latestAnswer();
                require(sourceRate != 0 && (sourceRate >> 128) == 0, "price error");
            } else {
                sourceRate = sourceToken == protocolTokenAddress ? protocolTokenEthPrice : 10**18;
            }

            uint256 destRate;
            if (destToken != address(baseToken) && destToken != protocolTokenAddress) {
                IPriceFeedsExt _destFeed = pricesFeeds[destToken];
                require(address(_destFeed) != address(0), "unsupported dst feed");

                /// Query token price on priceFeedsExt instance.
                destRate = _destFeed.latestAnswer();
                require(destRate != 0 && (destRate >> 128) == 0, "price error");
            } else {
                destRate = destToken == protocolTokenAddress ? protocolTokenEthPrice : 10**18;
            }

            rate = sourceRate.mul(10**18).div(destRate);

            precision = _getDecimalPrecision(sourceToken, destToken);

            /// Same tokens, return 1 with decimals.
        } else {
            rate = 10**18;
            precision = 10**18;
        }
    }

_getDecimalPrecision

Calculate the relative precision between two tokens. *

function _getDecimalPrecision(address sourceToken, address destToken) internal view
returns(uint256)

Arguments

Name Type Description
sourceToken address The address of the source tokens.
destToken address The address of the destiny tokens. *

Returns

The precision ratio source/dest.

Source Code
function _getDecimalPrecision(address sourceToken, address destToken)
        internal
        view
        returns (uint256)
    {
        /// Same tokens, return 1 with decimals.
        if (sourceToken == destToken) {
            return 10**18;

            /// Different tokens, query ERC20 precisions and return 18 +- diff.
        } else {
            uint256 sourceTokenDecimals = decimals[sourceToken];
            if (sourceTokenDecimals == 0) sourceTokenDecimals = IERC20(sourceToken).decimals();

            uint256 destTokenDecimals = decimals[destToken];
            if (destTokenDecimals == 0) destTokenDecimals = IERC20(destToken).decimals();

            if (destTokenDecimals >= sourceTokenDecimals)
                return 10**(SafeMath.sub(18, destTokenDecimals - sourceTokenDecimals));
            else return 10**(SafeMath.add(18, sourceTokenDecimals - destTokenDecimals));
        }
    }

Contracts