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

L2 Experimental Validators #10983

Merged
merged 22 commits into from
May 17, 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
22 changes: 11 additions & 11 deletions packages/protocol/contracts-0.8/common/FeeCurrencyDirectory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ contract FeeCurrencyDirectory is IFeeCurrencyDirectory, Initializable, Ownable {
currencyList.pop();
}

/**
* @notice Returns the storage, major, minor, and patch version of the contract.
* @return Storage version of the contract.
* @return Major version of the contract.
* @return Minor version of the contract.
* @return Patch version of the contract.
*/
function getVersionNumber() external pure returns (uint256, uint256, uint256, uint256) {
return (1, 1, 0, 0);
}

/**
* @notice Returns the list of all currency addresses.
* @return An array of addresses.
Expand Down Expand Up @@ -83,15 +94,4 @@ contract FeeCurrencyDirectory is IFeeCurrencyDirectory, Initializable, Ownable {
require(currencies[token].oracle != address(0), "Currency not in the directory");
(numerator, denominator) = IOracle(currencies[token].oracle).getExchangeRate(token);
}

/**
* @notice Returns the storage, major, minor, and patch version of the contract.
* @return Storage version of the contract.
* @return Major version of the contract.
* @return Minor version of the contract.
* @return Patch version of the contract.
*/
function getVersionNumber() external pure returns (uint256, uint256, uint256, uint256) {
return (1, 1, 0, 0);
}
}
21 changes: 13 additions & 8 deletions packages/protocol/contracts-0.8/common/IsL2Check.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity >=0.8.0 <0.8.20;
pragma solidity >=0.5.13 <0.8.20;

/**
* @title Based on predeploy returns whether this is L1 or L2.
Expand All @@ -7,17 +7,22 @@ contract IsL2Check {
address constant proxyAdminAddress = 0x4200000000000000000000000000000000000018;

modifier onlyL1() {
if (IsL2()) {
revert("This method is not supported in L2 anymore.");
}
allowOnlyL1();
_;
}

function IsL2() public view returns (bool) {
return address(proxyAdminAddress).code.length > 0;
function isL2() public view returns (bool) {
uint32 size;
address _addr = proxyAdminAddress;
assembly {
size := extcodesize(_addr)
}
return (size > 0);
}

function IsL1() public view returns (bool) {
return !IsL2();
function allowOnlyL1() internal view {
if (isL2()) {
revert("This method is not supported in L2 anymore.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,17 @@ contract MentoFeeCurrencyAdapter is IOracle, Initializable, Ownable {
currencyList.pop();
}

/**
* @notice Returns the storage, major, minor, and patch version of the contract.
* @return Storage version of the contract.
* @return Major version of the contract.
* @return Minor version of the contract.
* @return Patch version of the contract.
*/
function getVersionNumber() external pure returns (uint256, uint256, uint256, uint256) {
return (1, 1, 0, 0);
}

/**
* @notice Returns the list of all currency addresses.
* @return An array of addresses.
Expand Down Expand Up @@ -93,15 +104,4 @@ contract MentoFeeCurrencyAdapter is IOracle, Initializable, Ownable {
currencyConfig.currencyIdentifier
);
}

/**
* @notice Returns the storage, major, minor, and patch version of the contract.
* @return Storage version of the contract.
* @return Major version of the contract.
* @return Minor version of the contract.
* @return Patch version of the contract.
*/
function getVersionNumber() external pure returns (uint256, uint256, uint256, uint256) {
return (1, 1, 0, 0);
}
}
10 changes: 5 additions & 5 deletions packages/protocol/contracts-0.8/common/mocks/MockOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ contract MockOracle is IOracle {
uint256 lastUpdateTimestamp;
address token;

function getExchangeRate(address _token) external view returns (uint256, uint256) {
require(token == _token, "Token not supported");
return (numerator, denominator);
}

function setExchangeRate(address _token, uint256 _numerator, uint256 _denominator) public {
numerator = _numerator;
denominator = _denominator;
lastUpdateTimestamp = block.timestamp;
token = _token;
}

function getExchangeRate(address _token) external view returns (uint256, uint256) {
require(token == _token, "Token not supported");
return (numerator, denominator);
}
}
210 changes: 105 additions & 105 deletions packages/protocol/contracts/CompileExchange.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,6 @@ contract CompileExchange is
using SafeMath for uint256;
using FixidityLib for FixidityLib.Fraction;

event Exchanged(address indexed exchanger, uint256 sellAmount, uint256 buyAmount, bool soldGold);
event UpdateFrequencySet(uint256 updateFrequency);
event MinimumReportsSet(uint256 minimumReports);
event StableTokenSet(address indexed stable);
event SpreadSet(uint256 spread);
event ReserveFractionSet(uint256 reserveFraction);
event BucketsUpdated(uint256 goldBucket, uint256 stableBucket);

FixidityLib.Fraction public spread;

// Fraction of the Reserve that is committed to the gold bucket when updating
Expand All @@ -54,22 +46,19 @@ contract CompileExchange is

bytes32 public stableTokenRegistryId;

event Exchanged(address indexed exchanger, uint256 sellAmount, uint256 buyAmount, bool soldGold);
event UpdateFrequencySet(uint256 updateFrequency);
event MinimumReportsSet(uint256 minimumReports);
event StableTokenSet(address indexed stable);
event SpreadSet(uint256 spread);
event ReserveFractionSet(uint256 reserveFraction);
event BucketsUpdated(uint256 goldBucket, uint256 stableBucket);

modifier updateBucketsIfNecessary() {
_updateBucketsIfNecessary();
_;
}

/**
* @notice Returns the storage, major, minor, and patch version of the contract.
* @return Storage version of the contract.
* @return Major version of the contract.
* @return Minor version of the contract.
* @return Patch version of the contract.
*/
function getVersionNumber() external pure returns (uint256, uint256, uint256, uint256) {
return (1, 1, 0, 0);
}

/**
* @notice Sets initialized == true on implementation contracts
* @param test Set to true to skip implementation initialization
Expand Down Expand Up @@ -115,30 +104,6 @@ contract CompileExchange is
_updateBucketsIfNecessary();
}

/**
* @notice Exchanges a specific amount of one token for an unspecified amount
* (greater than a threshold) of another.
* @param sellAmount The number of tokens to send to the exchange.
* @param minBuyAmount The minimum number of tokens for the exchange to send in return.
* @param sellGold True if the caller is sending CELO to the exchange, false otherwise.
* @return The number of tokens sent by the exchange.
* @dev The caller must first have approved `sellAmount` to the exchange.
* @dev This function can be frozen via the Freezable interface.
*/
function sell(
uint256 sellAmount,
uint256 minBuyAmount,
bool sellGold
) public onlyWhenNotFrozen updateBucketsIfNecessary nonReentrant returns (uint256) {
(uint256 buyTokenBucket, uint256 sellTokenBucket) = _getBuyAndSellBuckets(sellGold);
uint256 buyAmount = _getBuyTokenAmount(buyTokenBucket, sellTokenBucket, sellAmount);

require(buyAmount >= minBuyAmount, "Calculated buyAmount was less than specified minBuyAmount");

_exchange(sellAmount, buyAmount, sellGold);
return buyAmount;
}

/**
* @dev DEPRECATED - Use `buy` or `sell`.
* @notice Exchanges a specific amount of one token for an unspecified amount
Expand Down Expand Up @@ -186,38 +151,6 @@ contract CompileExchange is
return sellAmount;
}

/**
* @notice Exchanges a specific amount of one token for a specific amount of another.
* @param sellAmount The number of tokens to send to the exchange.
* @param buyAmount The number of tokens for the exchange to send in return.
* @param sellGold True if the msg.sender is sending CELO to the exchange, false otherwise.
*/
function _exchange(uint256 sellAmount, uint256 buyAmount, bool sellGold) private {
IReserve reserve = IReserve(registry.getAddressForOrDie(RESERVE_REGISTRY_ID));

if (sellGold) {
goldBucket = goldBucket.add(sellAmount);
stableBucket = stableBucket.sub(buyAmount);
require(
getGoldToken().transferFrom(msg.sender, address(reserve), sellAmount),
"Transfer of sell token failed"
);
require(IStableToken(stable).mint(msg.sender, buyAmount), "Mint of stable token failed");
} else {
stableBucket = stableBucket.add(sellAmount);
goldBucket = goldBucket.sub(buyAmount);
require(
IERC20(stable).transferFrom(msg.sender, address(this), sellAmount),
"Transfer of sell token failed"
);
IStableToken(stable).burn(sellAmount);

require(reserve.transferExchangeGold(msg.sender, buyAmount), "Transfer of buyToken failed");
}

emit Exchanged(msg.sender, sellAmount, buyAmount, sellGold);
}

/**
* @notice Returns the amount of buy tokens a user would get for sellAmount of the sell token.
* @param sellAmount The amount of sellToken the user is selling to the exchange.
Expand All @@ -242,25 +175,38 @@ contract CompileExchange is
}

/**
* @notice Returns the buy token and sell token bucket sizes, in order. The ratio of
* the two also represents the exchange rate between the two.
* @param sellGold `true` if gold is the sell token.
* @return buyTokenBucket
* @return sellTokenBucket
* @notice Returns the storage, major, minor, and patch version of the contract.
* @return Storage version of the contract.
* @return Major version of the contract.
* @return Minor version of the contract.
* @return Patch version of the contract.
*/
function getBuyAndSellBuckets(bool sellGold) public view returns (uint256, uint256) {
uint256 currentGoldBucket = goldBucket;
uint256 currentStableBucket = stableBucket;
function getVersionNumber() external pure returns (uint256, uint256, uint256, uint256) {
return (1, 1, 0, 0);
}

if (shouldUpdateBuckets()) {
(currentGoldBucket, currentStableBucket) = getUpdatedBuckets();
}
/**
* @notice Exchanges a specific amount of one token for an unspecified amount
* (greater than a threshold) of another.
* @param sellAmount The number of tokens to send to the exchange.
* @param minBuyAmount The minimum number of tokens for the exchange to send in return.
* @param sellGold True if the caller is sending CELO to the exchange, false otherwise.
* @return The number of tokens sent by the exchange.
* @dev The caller must first have approved `sellAmount` to the exchange.
* @dev This function can be frozen via the Freezable interface.
*/
function sell(
uint256 sellAmount,
uint256 minBuyAmount,
bool sellGold
) public onlyWhenNotFrozen updateBucketsIfNecessary nonReentrant returns (uint256) {
(uint256 buyTokenBucket, uint256 sellTokenBucket) = _getBuyAndSellBuckets(sellGold);
uint256 buyAmount = _getBuyTokenAmount(buyTokenBucket, sellTokenBucket, sellAmount);

if (sellGold) {
return (currentStableBucket, currentGoldBucket);
} else {
return (currentGoldBucket, currentStableBucket);
}
require(buyAmount >= minBuyAmount, "Calculated buyAmount was less than specified minBuyAmount");

_exchange(sellAmount, buyAmount, sellGold);
return buyAmount;
}

/**
Expand Down Expand Up @@ -312,11 +258,79 @@ contract CompileExchange is
emit ReserveFractionSet(newReserveFraction);
}

/**
* @notice Returns the buy token and sell token bucket sizes, in order. The ratio of
* the two also represents the exchange rate between the two.
* @param sellGold `true` if gold is the sell token.
* @return buyTokenBucket
* @return sellTokenBucket
*/
function getBuyAndSellBuckets(bool sellGold) public view returns (uint256, uint256) {
uint256 currentGoldBucket = goldBucket;
uint256 currentStableBucket = stableBucket;

if (shouldUpdateBuckets()) {
(currentGoldBucket, currentStableBucket) = getUpdatedBuckets();
}

if (sellGold) {
return (currentStableBucket, currentGoldBucket);
} else {
return (currentGoldBucket, currentStableBucket);
}
}

function _setStableToken(address newStableToken) internal {
stable = newStableToken;
emit StableTokenSet(newStableToken);
}

/**
* @notice If conditions are met, updates the Uniswap bucket sizes to track
* the price reported by the Oracle.
*/
function _updateBucketsIfNecessary() private {
if (shouldUpdateBuckets()) {
// solhint-disable-next-line not-rely-on-time
lastBucketUpdate = now;

(goldBucket, stableBucket) = getUpdatedBuckets();
emit BucketsUpdated(goldBucket, stableBucket);
}
}

/**
* @notice Exchanges a specific amount of one token for a specific amount of another.
* @param sellAmount The number of tokens to send to the exchange.
* @param buyAmount The number of tokens for the exchange to send in return.
* @param sellGold True if the msg.sender is sending CELO to the exchange, false otherwise.
*/
function _exchange(uint256 sellAmount, uint256 buyAmount, bool sellGold) private {
IReserve reserve = IReserve(registry.getAddressForOrDie(RESERVE_REGISTRY_ID));

if (sellGold) {
goldBucket = goldBucket.add(sellAmount);
stableBucket = stableBucket.sub(buyAmount);
require(
getGoldToken().transferFrom(msg.sender, address(reserve), sellAmount),
"Transfer of sell token failed"
);
require(IStableToken(stable).mint(msg.sender, buyAmount), "Mint of stable token failed");
} else {
stableBucket = stableBucket.add(sellAmount);
goldBucket = goldBucket.sub(buyAmount);
require(
IERC20(stable).transferFrom(msg.sender, address(this), sellAmount),
"Transfer of sell token failed"
);
IStableToken(stable).burn(sellAmount);

require(reserve.transferExchangeGold(msg.sender, buyAmount), "Transfer of buyToken failed");
}

emit Exchanged(msg.sender, sellAmount, buyAmount, sellGold);
}

/**
* @notice Returns the buy token and sell token bucket sizes, in order. The ratio of
* the two also represents the exchange rate between the two.
Expand Down Expand Up @@ -405,20 +419,6 @@ contract CompileExchange is
return reserveFraction.multiply(FixidityLib.newFixed(reserveGoldBalance)).fromFixed();
}

/**
* @notice If conditions are met, updates the Uniswap bucket sizes to track
* the price reported by the Oracle.
*/
function _updateBucketsIfNecessary() private {
if (shouldUpdateBuckets()) {
// solhint-disable-next-line not-rely-on-time
lastBucketUpdate = now;

(goldBucket, stableBucket) = getUpdatedBuckets();
emit BucketsUpdated(goldBucket, stableBucket);
}
}

/**
* @notice Calculates the sell amount reduced by the spread.
* @param sellAmount The original sell amount.
Expand Down
Loading
Loading