Skip to content

Commit

Permalink
added a test net myso oracle in
Browse files Browse the repository at this point in the history
  • Loading branch information
jpick713 committed Apr 8, 2024
1 parent f0caf0c commit 059a41e
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 0 deletions.
4 changes: 4 additions & 0 deletions contracts/peer-to-peer/oracles/custom/MysoOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ contract MysoOracle is ChainlinkBase, Ownable {
* @param _oracleAddrs array of oracle addresses
* @param _owner owner of the contract
* @param _mysoTokenManager address of myso token manager contract
* @param _maxPrice max price in 8 decimals
* @param _k k in 18 decimals
* @param _a a in terms of 1000
* @param _b b in terms of 1000
*/
constructor(
address[] memory _tokenAddrs,
Expand Down
170 changes: 170 additions & 0 deletions contracts/test/TestMysoOracle.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.19;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IMysoTokenManager} from "../peer-to-peer/interfaces/oracles/IMysoTokenManager.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {LogExpMath} from "../peer-to-peer/oracles/custom/utils/LogExpMath.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

/**
* @dev supports oracles which are compatible with v2v3 or v3 interfaces
*/
contract TestnetMysoOracle is Ownable {
struct PriceParams {
// maxPrice is in 8 decimals for chainlink consistency
uint96 maxPrice;
// k is in 18 decimals
// e.g. 8e17 is 0.8 in decimal
uint96 k;
// a and b are in terms of 1000
// e.g. 1770 is 1.77 in decimal
uint32 a;
uint32 b;
}
// solhint-disable var-name-mixedcase
address internal constant MYSO = 0x8fF1307ba7e5FDc3A411d259bAe641e2B1d897c4; // myso sepolia address
address internal constant WETH = 0x3564c06EfEe0FeB0af5EF59dc5440bC45A265dA5;
address internal constant USDC = 0x2296282e2e2a4158140E3b4B99855ADa4a06a4B8;
address internal constant USDT = 0xdc2E37A79Ee93906c4665e49f82C1b895dFc7092;
address internal constant DAI = 0x40aD85ab1aA2a5bA61a2a026cfe1F4fd859eA188;

uint256 internal constant MYSO_PRICE_TIME_LOCK = 5 minutes;

address public mysoTokenManager;

PriceParams public mysoPriceParams;

event MysoTokenManagerUpdated(address newMysoTokenManager);

error NoMyso();
error NoOracle();

/**
* @dev constructor for TestMysoOracle
* @param _owner owner of the contract
* @param _mysoTokenManager address of myso token manager contract
* @param _maxPrice max price in 8 decimals
* @param _k k in 18 decimals
* @param _a a in terms of 1000
* @param _b b in terms of 1000
*/
constructor(
address _owner,
address _mysoTokenManager,
uint96 _maxPrice,
uint96 _k,
uint32 _a,
uint32 _b
) Ownable() {
mysoTokenManager = _mysoTokenManager;
mysoPriceParams = PriceParams(_maxPrice, _k, _a, _b);
_transferOwnership(_owner);
}

/**
* @dev updates myso token manager contract address
* @param _newMysoTokenManager new myso token manager contract address
*/

function setMysoTokenManager(
address _newMysoTokenManager
) external onlyOwner {
mysoTokenManager = _newMysoTokenManager;
emit MysoTokenManagerUpdated(_newMysoTokenManager);
}

/**
* @dev updates myso price params
* @param _maxPrice max price in 8 decimals
* @param _k k in 18 decimals
* @param _a a in terms of 1000
* @param _b b in terms of 1000
*/
function setMysoPriceParams(
uint96 _maxPrice,
uint96 _k,
uint32 _a,
uint32 _b
) external onlyOwner {
mysoPriceParams = PriceParams(_maxPrice, _k, _a, _b);
}

function getPrice(
address collToken,
address loanToken
) external view returns (uint256 collTokenPriceInLoanToken) {
(uint256 priceOfCollToken, uint256 priceOfLoanToken) = getRawPrices(
collToken,
loanToken
);
uint256 loanTokenDecimals = (loanToken == MYSO)
? 18
: IERC20Metadata(loanToken).decimals();
collTokenPriceInLoanToken =
(priceOfCollToken * 10 ** loanTokenDecimals) /
priceOfLoanToken;
}

function getRawPrices(
address collToken,
address loanToken
)
public
view
returns (uint256 collTokenPriceRaw, uint256 loanTokenPriceRaw)
{
// must have at least one token is MYSO to use this oracle
if (collToken != MYSO && loanToken != MYSO) {
revert NoMyso();
}
(collTokenPriceRaw, loanTokenPriceRaw) = (
_getPriceOfToken(collToken),
_getPriceOfToken(loanToken)
);
}

function _getPriceOfToken(
address token
) internal view virtual returns (uint256 tokenPriceRaw) {
if (token == MYSO) {
tokenPriceRaw = _getMysoPriceInEth();
} else if (token == WETH) {
tokenPriceRaw = 1e18;
} else if (token == USDC || token == USDT || token == DAI) {
tokenPriceRaw = Math.mulDiv(1e8, 1e18, 3300 * 1e8);
} else {
revert NoOracle();
}
}

function _getMysoPriceInEth()
internal
view
returns (uint256 mysoPriceInEth)
{
uint256 ethPriceInUsd = 3300 * 1e8;
uint256 _totalMysoLoanAmount = IMysoTokenManager(mysoTokenManager)
.totalMysoLoanAmount();
uint256 mysoPriceInUsd = _getMysoPriceInUsd(_totalMysoLoanAmount);
mysoPriceInEth = Math.mulDiv(mysoPriceInUsd, 1e18, ethPriceInUsd);
}

function _getMysoPriceInUsd(
uint256 totalMysoLoanAmount
) internal view returns (uint256 mysoPriceInUsd) {
PriceParams memory params = mysoPriceParams;
uint256 maxPrice = uint256(params.maxPrice);
uint256 k = uint256(params.k);
uint256 a = uint256(params.a);
uint256 b = uint256(params.b);
uint256 numerator = k * b;
uint256 denominator = uint256(
LogExpMath.exp(
int256(Math.mulDiv(totalMysoLoanAmount, a, 1000000000))
)
) + (2 * b - 1000) * 1e15;
mysoPriceInUsd = maxPrice - Math.mulDiv(numerator, 1e5, denominator);
}
}

0 comments on commit 059a41e

Please sign in to comment.