Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removal of SortedOracle multiplier #10931

Merged
merged 6 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 8 additions & 22 deletions packages/protocol/contracts/stability/SortedOracles.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ contract SortedOracles is ISortedOracles, ICeloVersionedContract, Ownable, Initi

struct EquivalentToken {
address token;
uint256 multiplier;
}

uint256 private constant FIXED1_UINT = 1e24;
Expand Down Expand Up @@ -232,17 +231,11 @@ contract SortedOracles is ISortedOracles, ICeloVersionedContract, Ownable, Initi
* @notice Sets the equivalent token for a token.
* @param token The address of the token.
* @param equivalentToken The address of the equivalent token.
* @param multiplier The multiplier to convert the equivalent token median value to the token value (fixidity).
* @dev For tokens with 6 decimals multiplier is 1e18 / 1e6 = 1e12
*/
function setEquivalentToken(address token, address equivalentToken, uint256 multiplier)
external
onlyOwner
{
function setEquivalentToken(address token, address equivalentToken) external onlyOwner {
require(token != address(0), "token address cannot be 0");
require(equivalentToken != address(0), "equivalentToken address cannot be 0");
require(multiplier > 0, "multiplier must be > 0");
equivalentTokens[token] = EquivalentToken(equivalentToken, multiplier);
equivalentTokens[token] = EquivalentToken(equivalentToken);
emit EquivalentTokenSet(token, equivalentToken);
}

Expand All @@ -260,10 +253,9 @@ contract SortedOracles is ISortedOracles, ICeloVersionedContract, Ownable, Initi
* @notice Gets the equivalent token for a token.
* @param token The address of the token.
* @return The address of the equivalent token.
* @return The multiplier to convert the equivalent token median value to the token value (fixidity).
*/
function getEquivalentToken(address token) external view returns (address, uint256) {
return (equivalentTokens[token].token, equivalentTokens[token].multiplier);
function getEquivalentToken(address token) external view returns (address) {
return (equivalentTokens[token].token);
}

/**
Expand Down Expand Up @@ -330,7 +322,7 @@ contract SortedOracles is ISortedOracles, ICeloVersionedContract, Ownable, Initi
* @dev Does not take account of equivalentTokens mapping.
* @param token The rateFeedId of the rates for which the median value is being retrieved.
* @return uint256 The median exchange rate for rateFeedId (fixidity).
* @return uint256 num of rates
* @return uint256 denominator
*/
function medianRateWithoutEquivalentMapping(address token)
public
Expand All @@ -346,21 +338,15 @@ contract SortedOracles is ISortedOracles, ICeloVersionedContract, Ownable, Initi
* return the median identified as an equivalent to the supplied rateFeedId.
* @param token The rateFeedId of the rates for which the median value is being retrieved.
* @return uint256 The median exchange rate for rateFeedId (fixidity).
* @return uint256 num of rates
* @return uint256 denominator
*/
function medianRate(address token) external view returns (uint256, uint256) {
EquivalentToken storage equivalentToken = equivalentTokens[token];
if (equivalentToken.token != address(0)) {
(uint256 equivalentMedianRate, uint256 numRates) = medianRateWithoutEquivalentMapping(
(uint256 equivalentMedianRate, uint256 denominator) = medianRateWithoutEquivalentMapping(
equivalentToken.token
);
return (
FixidityLib
.wrap(equivalentMedianRate)
.multiply(FixidityLib.wrap(equivalentToken.multiplier))
.unwrap(),
numRates
);
return (equivalentMedianRate, denominator);
}

return medianRateWithoutEquivalentMapping(token);
Expand Down
73 changes: 12 additions & 61 deletions packages/protocol/test-sol/stability/SortedOracles.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -86,44 +86,42 @@ contract SortedOracles_SetEquivalentToken is SortedOraclesTest {
address bToken = actor("bToken");

function test_ShouldSetReportExpiry() public {
sortedOracle.setEquivalentToken(aToken, bToken, FIXED1);
(address equivalentToken, uint256 multiplier) = sortedOracle.getEquivalentToken(aToken);
sortedOracle.setEquivalentToken(aToken, bToken);
address equivalentToken = sortedOracle.getEquivalentToken(aToken);
assertEq(equivalentToken, bToken);
assertEq(multiplier, FIXED1);
}

function test_ShouldRevert_WhenToken0() public {
vm.expectRevert("token address cannot be 0");
sortedOracle.setEquivalentToken(address(0), bToken, FIXED1);
sortedOracle.setEquivalentToken(address(0), bToken);
}

function test_ShouldRevert_WhenEquivalentToken0() public {
vm.expectRevert("equivalentToken address cannot be 0");
sortedOracle.setEquivalentToken(aToken, address(0), FIXED1);
sortedOracle.setEquivalentToken(aToken, address(0));
}

function test_ShouldEmitEquivalentTokenSet() public {
vm.expectEmit(true, true, true, true);
emit EquivalentTokenSet(aToken, bToken);
sortedOracle.setEquivalentToken(aToken, bToken, FIXED1);
sortedOracle.setEquivalentToken(aToken, bToken);
}

function test_ShouldRevertWhenNotOwner() public {
vm.expectRevert("Ownable: caller is not the owner");
vm.prank(oracleAccount);
sortedOracle.setEquivalentToken(aToken, bToken, FIXED1);
sortedOracle.setEquivalentToken(aToken, bToken);
}
}

contract SortedOracles_DeleteEquivalentToken is SortedOraclesTest {
address bToken = actor("bToken");

function test_ShouldDeleteEquivalentToken() public {
sortedOracle.setEquivalentToken(aToken, bToken, FIXED1);
sortedOracle.setEquivalentToken(aToken, bToken);
sortedOracle.deleteEquivalentToken(aToken);
(address equivalentToken, uint256 multiplier) = sortedOracle.getEquivalentToken(aToken);
address equivalentToken = sortedOracle.getEquivalentToken(aToken);
assertEq(equivalentToken, address(0));
assertEq(multiplier, 0);
}

function test_ShouldRevert_WhenEquivalentToken0() public {
Expand All @@ -132,7 +130,7 @@ contract SortedOracles_DeleteEquivalentToken is SortedOraclesTest {
}

function test_ShouldEmitEquivalentTokenSet() public {
sortedOracle.setEquivalentToken(aToken, bToken, FIXED1);
sortedOracle.setEquivalentToken(aToken, bToken);
vm.expectEmit(true, true, true, true);
emit EquivalentTokenSet(aToken, address(0));
sortedOracle.deleteEquivalentToken(aToken);
Expand Down Expand Up @@ -568,63 +566,16 @@ contract Report is SortedOraclesTest {
function test_ShouldReturnTheMedianRate_WhenEquivalentTokenIsSet() public {
vm.prank(oracleAccount);
sortedOracle.report(aToken, value, address(0), address(0));
sortedOracle.setEquivalentToken(bToken, aToken, FIXED1);
sortedOracle.setEquivalentToken(bToken, aToken);
(uint256 medianRate, uint256 denominator) = sortedOracle.medianRate(bToken);
assertEq(medianRate, value);
assertEq(denominator, FIXED1);
}

function setEquivalentTokenFuzzyHelper(
uint256 oneCeloDigits,
uint256 oneUSDDigits,
uint256 onecUSDDigits
) public {
uint256 cUSDRate = 700000000000000000000000;

uint256 oneCELO = 10**oneCeloDigits;
uint256 oneUSD = 10**oneUSDDigits;
uint256 onecUSD = 10**onecUSDDigits;
uint256 diff = oneCELO / oneUSD;

uint256 celoFromcUSD = FixidityLib
.wrap(cUSDRate)
.multiply(FixidityLib.newFixed(onecUSD))
.fromFixed();

vm.prank(oracleAccount);
sortedOracle.report(aToken, cUSDRate, address(0), address(0));
uint256 usdMultiplier = FixidityLib.newFixedFraction(diff, 1).unwrap();
sortedOracle.setEquivalentToken(bToken, aToken, usdMultiplier);
(uint256 medianRate, uint256 denominator) = sortedOracle.medianRate(bToken);
assertEq(medianRate, cUSDRate * diff);
assertEq(denominator, FIXED1);
uint256 celoFromUSD = FixidityLib
.wrap(medianRate)
.multiply(FixidityLib.newFixed(oneUSD))
.fromFixed();
assertEq(celoFromUSD, celoFromcUSD);
}

function test_ShouldReturnTheMedianRateWithDifferentMultiplier_WhenEquivalentTokenIsSet() public {
setEquivalentTokenFuzzyHelper(18, 6, 18);
}

function test_ShouldReturnTheMedianRateWithDifferentMultiplier_WhenEquivalentTokenIsSet_WhenMultiplierIsOneBigger()
public
{
setEquivalentTokenFuzzyHelper(18, 17, 18);
}

function test_ShouldReturnTheMedianRateWithDifferentMultiplier_WhenEquivalentTokenIsSet_WhenMultiplierIsALotBigger()
public
{
setEquivalentTokenFuzzyHelper(18, 0, 18);
}

function test_ShouldNotReturnTheMedianRate_WhenEquivalentTokenIsSet() public {
vm.prank(oracleAccount);
sortedOracle.report(aToken, value, address(0), address(0));
sortedOracle.setEquivalentToken(bToken, aToken, FIXED1);
sortedOracle.setEquivalentToken(bToken, aToken);
(uint256 medianRate, uint256 denominator) = sortedOracle.medianRateWithoutEquivalentMapping(
bToken
);
Expand All @@ -637,7 +588,7 @@ contract Report is SortedOraclesTest {
{
vm.prank(oracleAccount);
sortedOracle.report(aToken, value, address(0), address(0));
sortedOracle.setEquivalentToken(bToken, aToken, FIXED1);
sortedOracle.setEquivalentToken(bToken, aToken);
uint256 medianRate;
uint256 denominator;
(medianRate, denominator) = sortedOracle.medianRate(bToken);
Expand Down
Loading