add: PriceIndexQuote.sol
This commit is contained in:
commit
7cdea201ac
117
PriceIndexQuote.sol
Normal file
117
PriceIndexQuote.sol
Normal file
@ -0,0 +1,117 @@
|
||||
/**
|
||||
*Submitted for verification at celoscan.io on 2023-12-12
|
||||
*/
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
// Author: Louis Holbrook <dev@holbrook.no> 0826EDA1702D1E87C6E2875121D2E7BB88C2A746
|
||||
// Author: Mohamed Sohail <sohail@grassecon.org>
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
// File-Version: 1
|
||||
// Description: ACL-enabled ERC20 token swap quoter that queries a price index for the latest exchange rates.
|
||||
|
||||
contract PriceIndexQuote {
|
||||
// Implements EIP173
|
||||
address public owner;
|
||||
// consts
|
||||
uint256 constant EXCHANGE_RATE_PRECISION = 10 ** 4;
|
||||
|
||||
mapping(address => uint256) public priceIndex;
|
||||
|
||||
event PriceIndexUpdated(address _tokenAddress, uint256 _exchangeRate);
|
||||
// Implements ERC173
|
||||
event OwnershipTransferred(
|
||||
address indexed previousOwner,
|
||||
address indexed newOwner
|
||||
);
|
||||
|
||||
constructor() {
|
||||
owner = msg.sender;
|
||||
}
|
||||
|
||||
function setPriceIndexValue(
|
||||
address _tokenAddress,
|
||||
uint256 _exchangeRate
|
||||
) public returns (uint256) {
|
||||
require(owner == msg.sender, "ERR_NOT_OWNER");
|
||||
priceIndex[_tokenAddress] = _exchangeRate;
|
||||
emit PriceIndexUpdated(_tokenAddress, _exchangeRate);
|
||||
return _exchangeRate;
|
||||
}
|
||||
|
||||
// Implements TokenQuote
|
||||
function valueFor(
|
||||
address _outToken,
|
||||
address _inToken,
|
||||
uint256 _value
|
||||
) public returns (uint256) {
|
||||
uint8 dout;
|
||||
uint8 din;
|
||||
bool r;
|
||||
bytes memory v;
|
||||
|
||||
uint256 exchangeRate = priceIndex[_inToken] > 0
|
||||
? priceIndex[_inToken]
|
||||
: priceIndex[_outToken];
|
||||
|
||||
(r, v) = _outToken.call(abi.encodeWithSignature("decimals()"));
|
||||
require(r, "ERR_TOKEN_OUT");
|
||||
dout = abi.decode(v, (uint8));
|
||||
|
||||
(r, v) = _inToken.call(abi.encodeWithSignature("decimals()"));
|
||||
require(r, "ERR_TOKEN_IN");
|
||||
din = abi.decode(v, (uint8));
|
||||
|
||||
if (din == dout) {
|
||||
uint256 x = _value;
|
||||
if (exchangeRate > 0) {
|
||||
x = (x * exchangeRate) / EXCHANGE_RATE_PRECISION;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
uint256 d = din > dout ? 10 ** ((din - dout)) : 10 ** ((dout - din));
|
||||
if (din > dout) {
|
||||
uint256 x = _value / d;
|
||||
if (exchangeRate > 0) {
|
||||
x = (x * exchangeRate) / EXCHANGE_RATE_PRECISION;
|
||||
}
|
||||
return x;
|
||||
} else {
|
||||
uint256 x = _value * d;
|
||||
if (exchangeRate > 0) {
|
||||
x = (x / exchangeRate) * EXCHANGE_RATE_PRECISION;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
// Implements EIP173
|
||||
function transferOwnership(address _newOwner) public returns (bool) {
|
||||
address oldOwner;
|
||||
require(msg.sender == owner, "ERR_AXX");
|
||||
|
||||
oldOwner = owner;
|
||||
owner = _newOwner;
|
||||
|
||||
emit OwnershipTransferred(oldOwner, owner);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Implements EIP165
|
||||
function supportsInterface(bytes4 _sum) public pure returns (bool) {
|
||||
if (_sum == 0x01ffc9a7) {
|
||||
// ERC165
|
||||
return true;
|
||||
}
|
||||
if (_sum == 0x9493f8b2) {
|
||||
// ERC173
|
||||
return true;
|
||||
}
|
||||
if (_sum == 0xdbb21d40) {
|
||||
// TokenQuote
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user