Skip to content

Commit

Permalink
L2 Experimental Validators (#10983)
Browse files Browse the repository at this point in the history
* L2 Experimentall Validators

* integration tests

* Release gold tests

* prettify

* version update

* optimizing the check

* removal of modifier

* prettify

* workflow update

* workflow update2

* validator bytecode size fix

* removal of tmate

* hardcode gas limit

* make release

* rever of migrations

* hardcode gas

* Added logging

* validators

* refactor
  • Loading branch information
pahor167 authored May 17, 2024
1 parent 43a3146 commit a4c608b
Show file tree
Hide file tree
Showing 21 changed files with 1,284 additions and 360 deletions.
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.");
}
}
}
22 changes: 11 additions & 11 deletions packages/protocol/contracts-0.8/common/MentoFeeCurrencyAdapter.sol
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

0 comments on commit a4c608b

Please sign in to comment.