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

v2.3 #94

Merged
merged 49 commits into from
Oct 30, 2024
Merged

v2.3 #94

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
982d0ac
add noop adiabatic
kbrizzle Apr 25, 2024
00419b6
update tests
kbrizzle Apr 30, 2024
19f33fb
Merge pull request #91 from equilibria-xyz/britz-noop-adiabatic
kbrizzle Apr 30, 2024
7cbe2a7
started work on verifier folder
EdNoepel May 1, 2024
a9fd9db
doco
EdNoepel May 1, 2024
2e4cf72
moved logic into VerifierBase
EdNoepel May 1, 2024
67e3868
documented IVerifierBase
EdNoepel May 1, 2024
1ba4db1
common unit tests
EdNoepel May 1, 2024
08bc223
nonce cancellation tests
EdNoepel May 1, 2024
e11de48
run CI on v2.3 branch
EdNoepel May 1, 2024
5d1c7fa
removed TODO
EdNoepel May 1, 2024
c8a7201
resolved some issues from PR review
EdNoepel May 1, 2024
13e9fee
missing trailing newline
EdNoepel May 1, 2024
552f612
improve readability
EdNoepel May 2, 2024
683e499
Merge pull request #92 from equilibria-xyz/ed/verifier
EdNoepel May 9, 2024
6fa0b83
add signer to common
kbrizzle May 26, 2024
b4375bd
bump version
kbrizzle May 26, 2024
768e26b
Merge pull request #93 from equilibria-xyz/britz-add-signer-to-common
kbrizzle Jun 10, 2024
a820ce0
don't update for param change
kbrizzle Jun 12, 2024
9bc6eca
bump version
kbrizzle Jun 12, 2024
efdaa2b
Merge pull request #95 from equilibria-xyz/britz-adiabatic-no-update
kbrizzle Jun 14, 2024
7221e88
add total supply
kbrizzle Jun 14, 2024
339ef61
bump version
kbrizzle Jun 14, 2024
835c3b6
Merge branch 'v2.3' into britz-add-total-supply
kbrizzle Jun 14, 2024
03d844c
Merge pull request #96 from equilibria-xyz/britz-add-total-supply
kbrizzle Jun 14, 2024
0e10b92
extend factory to support create2
EdNoepel Jun 26, 2024
fc59146
compute create2 address
EdNoepel Jun 26, 2024
bf95d50
tidy
EdNoepel Jun 26, 2024
22786a5
improved comments
EdNoepel Jun 27, 2024
7337876
Merge pull request #97 from equilibria-xyz/ed/factory-create2
EdNoepel Jul 8, 2024
5f4b33b
corrected error sig
EdNoepel Jul 16, 2024
a14abc6
Merge pull request #98 from equilibria-xyz/ed/correct-error-sig
EdNoepel Jul 17, 2024
e8ced57
add gas oracle
kbrizzle Aug 11, 2024
a8a4b07
fix tests
kbrizzle Aug 14, 2024
83baf15
Merge pull request #99 from equilibria-xyz/britz-add-gas-oracle
kbrizzle Aug 15, 2024
1c2fa10
add check
kbrizzle Aug 23, 2024
e258735
Merge pull request #101 from equilibria-xyz/britz-reinitialize-check
kbrizzle Aug 23, 2024
22bc3ea
add nonce and group
kbrizzle Aug 23, 2024
734ff2d
bump version
kbrizzle Aug 23, 2024
b323676
Merge pull request #102 from equilibria-xyz/britz-update-iverifier
kbrizzle Aug 24, 2024
511f804
add authorization check
prateekdefi Sep 23, 2024
b20d267
bump version
prateekdefi Sep 23, 2024
4afbbad
v2.3 Audit Fixes
prateekdefi Sep 23, 2024
9dcdaf5
_authorized returns whether the signer is authorized
prateekdefi Sep 25, 2024
cfcb8b1
fix signer check and tests
prateekdefi Sep 25, 2024
474aad0
Merge pull request #104 from equilibria-xyz/prateek/add-authorization
arjun-io Oct 9, 2024
561ca04
re-add sc signer tests
EdNoepel Oct 10, 2024
ce9308e
Merge pull request #105 from equilibria-xyz/ed/readd-sc-verifier-tests
arjun-io Oct 10, 2024
67f9493
Merge pull request #103 from equilibria-xyz/v2.3-fix-review
arjun-io Oct 16, 2024
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
2 changes: 2 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:
- master
- dev
- v2
- v2.3
- v2.3-fix-review

env:
CI: true
Expand Down
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

Core library for DeFi.

## Facilities
| Name | Purpose |
| ---:|------------------------------------------------|
| **accumulator** | tracks cumulative changes to a value |
| **attribute** | abstract contracts with foundational patterns |
| **number** | fixed decimal types and math functions |
| **pid** | proportional integral derivative controller |
| **token** | helpers for working with fungible tokens |
| **utilization** | calculates rates based on a utilization curve |
| **verifier** | helps create and verify EIP712 signed messages |

## Installation

```
Expand All @@ -10,7 +21,7 @@ npm install @equilibria/root

## Contributing

### Pre Requisites
### Prerequisites

This repo works best with Node.js v16.x.x, this is preconfigured for users of [asdf](https://asdf-vm.com/).

Expand Down Expand Up @@ -51,7 +62,7 @@ To get a gas report based on unit test calls:
$ yarn gasReport
```

### Deploy contract to netowrk (requires Mnemonic and infura API key)
### Deploy contract to network (requires Mnemonic and infura API key)

```
npx hardhat run --network rinkeby ./scripts/deploy.ts
Expand Down
111 changes: 0 additions & 111 deletions contracts/adiabatic/types/InverseAdiabatic6.sol

This file was deleted.

33 changes: 15 additions & 18 deletions contracts/adiabatic/types/LinearAdiabatic6.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,21 @@ library LinearAdiabatic6Lib {
return compute(self, Fixed6Lib.ZERO, latest, UFixed6Lib.ONE);
}

/// @dev Computes the change in exposure from a new configuration
/// @param self The latest fee configuration
/// @param newConfig The new fee configuration
/// @param latest The latest skew in asset terms
/// @param price The price of the underlying asset
/// @return The update fee in underlying terms
function exposure(
LinearAdiabatic6 memory self,
LinearAdiabatic6 memory newConfig,
Fixed6 latest,
UFixed6 price
) internal pure returns (Fixed6) {
return compute(newConfig, Fixed6Lib.ZERO, latest, price).sub(compute(self, Fixed6Lib.ZERO, latest, price));
}

/// @notice Computes the linear fee
/// @param self The adiabatic configuration
/// @param change The change in skew in asset terms
Expand Down Expand Up @@ -86,22 +101,4 @@ library LinearAdiabatic6Lib {
) internal pure returns (Fixed6) {
return compute(self, latest, change, price);
}

/// @dev Updates the scale and compute the resultant change fee
/// @param self The adiabatic configuration
/// @param newConfig The new fee config
/// @param latest The latest skew in asset terms
/// @param price The price of the underlying asset
/// @return The update fee in underlying terms
function update(
LinearAdiabatic6 memory self,
LinearAdiabatic6 memory newConfig,
Fixed6 latest,
UFixed6 price
) internal pure returns (Fixed6) {
Fixed6 prior = compute(self, Fixed6Lib.ZERO, latest, price);
(self.linearFee, self.proportionalFee, self.adiabaticFee, self.scale) =
(newConfig.linearFee, newConfig.proportionalFee, newConfig.adiabaticFee, newConfig.scale);
return compute(self, Fixed6Lib.ZERO, latest, price).sub(prior);
}
}
40 changes: 40 additions & 0 deletions contracts/adiabatic/types/NoopAdiabatic6.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.13;

import "../../number/types/Fixed6.sol";
import "../../number/types/UFixed6.sol";
import "../AdiabaticMath6.sol";

/// @dev NoopAdiabatic6 type
struct NoopAdiabatic6 {
UFixed6 linearFee;
UFixed6 proportionalFee;
UFixed6 scale;
}
using NoopAdiabatic6Lib for NoopAdiabatic6 global;

/**
* @title NoopAdiabatic6Lib
* @notice Library that that manages the no-op adiabatic fee algorithm
* @dev This algorithm specifies a fee schedule without an adiabatic fee. This is used for fees that need unsigned
* fee impact without a signed shift fee based on skew.
*/
library NoopAdiabatic6Lib {
/// @notice Computes the linear fee
/// @param self The adiabatic configuration
/// @param change The change in skew in asset terms
/// @param price The price of the underlying asset
/// @return The linear fee in underlying terms
function linear(NoopAdiabatic6 memory self, Fixed6 change, UFixed6 price) internal pure returns (UFixed6) {
return AdiabaticMath6.linearFee(self.linearFee, change, price);
}

/// @notice Computes the proportional fee
/// @param self The adiabatic configuration
/// @param change The change in skew in asset terms
/// @param price The price of the underlying asset
/// @return The proportional fee in underlying terms
function proportional(NoopAdiabatic6 memory self, Fixed6 change, UFixed6 price) internal pure returns (UFixed6) {
return AdiabaticMath6.proportionalFee(self.scale, self.proportionalFee, change, price);
}
}
22 changes: 22 additions & 0 deletions contracts/attribute/Factory.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.13;

import "@openzeppelin/contracts/utils/Create2.sol";
import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
import "./interfaces/IFactory.sol";
import "./interfaces/IInstance.sol";
Expand Down Expand Up @@ -40,6 +41,27 @@ abstract contract Factory is IFactory, Ownable, Pausable {
newInstance = IInstance(address(new BeaconProxy(address(this), data)));
_register(newInstance);
}
/// @notice Creates a new instance at a deterministic address
/// @dev Deploys a BeaconProxy with the this contract as the beacon
/// @param data The initialization data
/// @param salt Used along with initialization data to determine a unique BeaconProxy address
/// @return newInstance The new instance
function _create2(bytes memory data, bytes32 salt) internal returns (IInstance newInstance) {
newInstance = IInstance(address(new BeaconProxy{salt: salt}(address(this), data)));
_register(newInstance);
}

// @notice Calculates the address at which the instance will be deployed
// @dev Passes the proxy's creation code along with this factory's address
// @param data The same initialization data used in the _create2 call
// @param salt Used along with initialization data to determine a unique BeaconProxy address
function _computeCreate2Address(bytes memory data, bytes32 salt) internal view returns (address) {
bytes memory bytecode = abi.encodePacked(
type(BeaconProxy).creationCode,
abi.encode(address(this), data)
);
return Create2.computeAddress(salt, keccak256(bytecode));
}

/// @notice Registers a new instance
/// @dev Called by _create automatically, or can be called manually in an extending implementation
Expand Down
7 changes: 1 addition & 6 deletions contracts/attribute/Kept/Kept_Arbitrum.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@
pragma solidity ^0.8.13;

import "./Kept.sol";

// https://github.com/OffchainLabs/nitro/blob/v2.0.14/contracts/src/precompiles/ArbGasInfo.sol#L93
interface ArbGasInfo {
/// @notice Get ArbOS's estimate of the L1 basefee in wei
function getL1BaseFeeEstimate() external view returns (uint256);
}
import { ArbGasInfo } from "../../gas/GasOracle_Arbitrum.sol";

/// @dev Arbitrum Kept implementation
abstract contract Kept_Arbitrum is Kept {
Expand Down
10 changes: 1 addition & 9 deletions contracts/attribute/Kept/Kept_Optimism.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,7 @@
pragma solidity ^0.8.13;

import "./Kept.sol";

interface OptGasInfo {
function getL1GasUsed(bytes memory) external view returns (uint256);
function l1BaseFee() external view returns (uint256);
function baseFeeScalar() external view returns (uint256);
function blobBaseFee() external view returns (uint256);
function blobBaseFeeScalar() external view returns (uint256);
function decimals() external view returns (uint256);
}
import { OptGasInfo } from "../../gas/GasOracle_Optimism.sol";

/// @dev Optimism Kept implementation
abstract contract Kept_Optimism is Kept {
Expand Down
1 change: 1 addition & 0 deletions contracts/attribute/Ownable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ abstract contract Ownable is IOwnable, Initializable {
* @notice Initializes the contract setting `msg.sender` as the initial owner
*/
function __Ownable__initialize() internal onlyInitializer {
if (owner() != address(0)) revert OwnableAlreadyInitializedError();
_updateOwner(_sender());
}

Expand Down
1 change: 1 addition & 0 deletions contracts/attribute/interfaces/IOwnable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface IOwnable is IInitializable {

error OwnableNotOwnerError(address sender);
error OwnableNotPendingOwnerError(address sender);
error OwnableAlreadyInitializedError();

function owner() external view returns (address);
function pendingOwner() external view returns (address);
Expand Down
68 changes: 68 additions & 0 deletions contracts/gas/GasOracle.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.13;

import { AggregatorV3Interface } from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import { UFixed18, UFixed18Lib } from "../number/types/UFixed18.sol";
import { Fixed18Lib } from "../number/types/Fixed18.sol";
import { IGasOracle } from "./interfaces/IGasOracle.sol";

/// @title GasOracle
/// @notice Standalone gas oracle for externally computing keeper rewards based on ether gas costs
contract GasOracle is IGasOracle {
/// @notice The total compute gas rewarded
UFixed18 public immutable COMPUTE_GAS;

/// @notice The total calldata gas rewarded
UFixed18 public immutable CALLDATA_GAS;

/// @notice Chainlink ETH-Token feed, where cost is expressed in terms of Token
AggregatorV3Interface public immutable FEED;

/// @notice The precomputed offset of the Chainlink feed (10 ^ decimals)
int256 public immutable FEED_OFFSET;

constructor(
AggregatorV3Interface feed,
uint256 decimals,
uint256 computeGas,
UFixed18 computeMultiplier,
uint256 computeBase,
uint256 calldataGas,
UFixed18 calldataMultiplier,
uint256 calldataBase
) {
FEED = feed;
FEED_OFFSET = int256(10 ** decimals);
COMPUTE_GAS = _precompute(computeGas, computeMultiplier, computeBase);
CALLDATA_GAS = _precompute(calldataGas, calldataMultiplier, calldataBase);
}

/// @inheritdoc IGasOracle
function cost(uint256 value) external view returns (UFixed18) {
(UFixed18 baseFee, UFixed18 calldataFee) =
(UFixed18.wrap(block.basefee).mul(COMPUTE_GAS), UFixed18.wrap(_calldataBaseFee()).mul(CALLDATA_GAS));

return UFixed18.wrap(value).add(baseFee).add(calldataFee).mul(_etherPrice());
}

/// @notice Precomputes the total rewarded gas cost
/// @param gas The applicable gas cost
/// @param multiplier The reward multiplier to apply to the gas cost
/// @param base The base gas reward to add on to the gas cost
/// @return The total rewarded gas cost
function _precompute(uint256 gas, UFixed18 multiplier, uint256 base) private pure returns (UFixed18) {
return UFixed18Lib.from(gas).mul(multiplier).add(UFixed18Lib.from(base));
}

/// @notice Returns the price of ether in terms of the underlying token
/// @return The price of ether in terms of the underlyingtoken
function _etherPrice() private view returns (UFixed18) {
(, int256 answer, , ,) = FEED.latestRoundData();
return UFixed18Lib.from(Fixed18Lib.ratio(answer, FEED_OFFSET));
}

/// @notice Returns the base fee of the calldata
/// @dev Can be overridden to provide a non-zero calldata base fee for L2 implementations
/// @return The base fee of the calldata
function _calldataBaseFee() internal virtual view returns (uint256) { return 0; }
}
Loading
Loading