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

Swivel v3: ExchangeRate Adapters, Protocol Enum, Custom Errors #197

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0ef4d7d
VaultTracker: Add Compound & Rari Adapters
JTraversa Apr 16, 2022
2c51054
fix constructor use of adapter
JTraversa Apr 16, 2022
0d7c95a
Yearn adapter Pog
JTraversa Apr 17, 2022
fb5e19a
adapter param type CERC20 -> address
JTraversa Apr 17, 2022
b5a41d1
Aave adapter
JTraversa Apr 17, 2022
07b6d3a
Lido Adapter
JTraversa Apr 17, 2022
993abfc
Euler Adapter + License updates
JTraversa Apr 17, 2022
b6e8f73
Fix Euler Adapter Name
JTraversa Apr 17, 2022
a92e579
Increase EToken & Lido ETH rate precision
JTraversa Apr 17, 2022
e7917f9
Update Marketplace for adapter pattern
JTraversa Apr 17, 2022
ca82a60
prepare Swivel.sol for adapter addition
JTraversa Apr 17, 2022
20c9e84
constructor adapter fix
JTraversa Apr 17, 2022
2bc7509
calculateReturn -> view method
JTraversa Apr 17, 2022
a9edf13
mint and redeem: Aave Yearn Lido Euler
JTraversa Apr 24, 2022
9bf0fdf
Update Interfaces
JTraversa Apr 24, 2022
16f39a7
Fix Imports
JTraversa Apr 24, 2022
217ea0a
Custom Revert Errors
JTraversa Apr 24, 2022
74b2780
Marketplace Custom Reverts
JTraversa Apr 24, 2022
252ad80
VaultTracker Custom Reverts
JTraversa Apr 24, 2022
fa76e84
Mirror math precision
JTraversa Apr 24, 2022
fe0380e
Authorized -> Unauthorized
JTraversa Apr 24, 2022
4fbe8c4
Swivel Events
JTraversa Apr 25, 2022
f0bcc68
remove adapters mapping
JTraversa Apr 25, 2022
50e4537
associate adapters and enum, separate adapters
JTraversa Apr 27, 2022
42178f8
add protocol to mapping
JTraversa Apr 28, 2022
48985ae
add protocol param to marketplace calls in Swivel.sol
JTraversa Apr 28, 2022
f9dd948
natspec additions
JTraversa Apr 28, 2022
7bc8dbc
fix marketplace interface
JTraversa Apr 28, 2022
358fbc0
simplify aave adapter
JTraversa May 24, 2022
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
14 changes: 14 additions & 0 deletions test/adapters/AaveAdapter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.4;

import "./IAToken.sol";
import "./IAavePool.sol";

contract AaveAdapter {

uint8 public protocol = 4;

function exchangeRateCurrent(address a) external view returns (uint256){
return(IAavePool(IAToken(a).POOL()).getReserveNormalizedIncome(aToken.UNDERLYING_ASSET_ADDRESS()));
}
}
47 changes: 47 additions & 0 deletions test/adapters/CERC20.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
pragma solidity >=0.8.4;

import {PErc20} from "../tokens/PErc20.sol";

import {InterestRateModel} from "./InterestRateModel.sol";

abstract contract CERC20 is Erc20 {
function mint(uint256) external virtual returns (uint256);

function borrow(uint256) external virtual returns (uint256);

function underlying() external view virtual returns (Erc20);

function totalBorrows() external view virtual returns (uint256);

function totalFuseFees() external view virtual returns (uint256);

function repayBorrow(uint256) external virtual returns (uint256);

function totalReserves() external view virtual returns (uint256);

function exchangeRateCurrent() external virtual returns (uint256);

function totalAdminFees() external view virtual returns (uint256);

function fuseFeeMantissa() external view virtual returns (uint256);

function adminFeeMantissa() external view virtual returns (uint256);

function exchangeRateStored() external view virtual returns (uint256);

function accrualBlockNumber() external view virtual returns (uint256);

function redeemUnderlying(uint256) external virtual returns (uint256);

function balanceOfUnderlying(address) external virtual returns (uint256);

function reserveFactorMantissa() external view virtual returns (uint256);

function borrowBalanceCurrent(address) external virtual returns (uint256);

function interestRateModel() external view virtual returns (InterestRateModel);

function initialExchangeRateMantissa() external view virtual returns (uint256);

function repayBorrowBehalf(address, uint256) external virtual returns (uint256);
}
13 changes: 13 additions & 0 deletions test/adapters/CompoundAdapter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >= 0.8.10;

import "./LibCompound.sol";

contract CompoundAdapter {

uint8 public protocol = 1;

function exchangeRateCurrent(address a) external view returns (uint256){
return(LibCompound.viewExchangeRate(CERC20(a)));
}
}
13 changes: 13 additions & 0 deletions test/adapters/ERC4626Adapter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.8.4;

import "./IERC4626.sol";

contract ERC4626Adapter {

uint8 public protocol = 6;

function exchangeRateCurrent(address a) public view returns (uint256){
return (IERC4626(a).convertToAssets(1e26));
}
}
14 changes: 14 additions & 0 deletions test/adapters/EulerAdapter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.8.4;

import "./IEToken.sol";

contract EulerAdapter {

uint8 public protocol = 5;

function exchangeRateCurrent(address a) external view returns (uint256){
return(IEToken(a).convertBalanceToUnderlying(1e27));
}
}

222 changes: 222 additions & 0 deletions test/adapters/FixedPointMathLib.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.8.0;

/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
/*//////////////////////////////////////////////////////////////
SIMPLIFIED FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/

uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.

function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
}

function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
}

function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
}

function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
}

/*//////////////////////////////////////////////////////////////
LOW LEVEL FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/

function mulDivDown(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
assembly {
// Store x * y in z for now.
z := mul(x, y)

// Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
revert(0, 0)
}

// Divide z by the denominator.
z := div(z, denominator)
}
}

function mulDivUp(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
assembly {
// Store x * y in z for now.
z := mul(x, y)

// Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
revert(0, 0)
}

// First, divide z - 1 by the denominator and add 1.
// We allow z - 1 to underflow if z is 0, because we multiply the
// end result by 0 if z is zero, ensuring we return 0 if z is zero.
z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))
}
}

function rpow(
uint256 x,
uint256 n,
uint256 scalar
) internal pure returns (uint256 z) {
assembly {
switch x
case 0 {
switch n
case 0 {
// 0 ** 0 = 1
z := scalar
}
default {
// 0 ** n = 0
z := 0
}
}
default {
switch mod(n, 2)
case 0 {
// If n is even, store scalar in z for now.
z := scalar
}
default {
// If n is odd, store x in z for now.
z := x
}

// Shifting right by 1 is like dividing by 2.
let half := shr(1, scalar)

for {
// Shift n right by 1 before looping to halve it.
n := shr(1, n)
} n {
// Shift n right by 1 each iteration to halve it.
n := shr(1, n)
} {
// Revert immediately if x ** 2 would overflow.
// Equivalent to iszero(eq(div(xx, x), x)) here.
if shr(128, x) {
revert(0, 0)
}

// Store x squared.
let xx := mul(x, x)

// Round to the nearest number.
let xxRound := add(xx, half)

// Revert if xx + half overflowed.
if lt(xxRound, xx) {
revert(0, 0)
}

// Set x to scaled xxRound.
x := div(xxRound, scalar)

// If n is even:
if mod(n, 2) {
// Compute z * x.
let zx := mul(z, x)

// If z * x overflowed:
if iszero(eq(div(zx, x), z)) {
// Revert if x is non-zero.
if iszero(iszero(x)) {
revert(0, 0)
}
}

// Round to the nearest number.
let zxRound := add(zx, half)

// Revert if zx + half overflowed.
if lt(zxRound, zx) {
revert(0, 0)
}

// Return properly scaled zxRound.
z := div(zxRound, scalar)
}
}
}
}
}

/*//////////////////////////////////////////////////////////////
GENERAL NUMBER UTILITIES
//////////////////////////////////////////////////////////////*/

function sqrt(uint256 x) internal pure returns (uint256 z) {
assembly {
// Start off with z at 1.
z := 1

// Used below to help find a nearby power of 2.
let y := x

// Find the lowest power of 2 that is at least sqrt(x).
if iszero(lt(y, 0x100000000000000000000000000000000)) {
y := shr(128, y) // Like dividing by 2 ** 128.
z := shl(64, z) // Like multiplying by 2 ** 64.
}
if iszero(lt(y, 0x10000000000000000)) {
y := shr(64, y) // Like dividing by 2 ** 64.
z := shl(32, z) // Like multiplying by 2 ** 32.
}
if iszero(lt(y, 0x100000000)) {
y := shr(32, y) // Like dividing by 2 ** 32.
z := shl(16, z) // Like multiplying by 2 ** 16.
}
if iszero(lt(y, 0x10000)) {
y := shr(16, y) // Like dividing by 2 ** 16.
z := shl(8, z) // Like multiplying by 2 ** 8.
}
if iszero(lt(y, 0x100)) {
y := shr(8, y) // Like dividing by 2 ** 8.
z := shl(4, z) // Like multiplying by 2 ** 4.
}
if iszero(lt(y, 0x10)) {
y := shr(4, y) // Like dividing by 2 ** 4.
z := shl(2, z) // Like multiplying by 2 ** 2.
}
if iszero(lt(y, 0x8)) {
// Equivalent to 2 ** z.
z := shl(1, z)
}

// Shifting right by 1 is like dividing by 2.
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))

// Compute a rounded down version of z.
let zRoundDown := div(x, z)

// If zRoundDown is smaller, use it.
if lt(zRoundDown, z) {
z := zRoundDown
}
}
}
}
7 changes: 7 additions & 0 deletions test/adapters/IAToken.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.8.4;

interface IAToken {
function POOL() external view returns (address);
function UNDERLYING_ASSET_ADDRESS() external view returns (address);
}
12 changes: 12 additions & 0 deletions test/adapters/IAavePool.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.8.4;

interface IAavePool {
/**
* @notice Returns the normalized income normalized income of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The reserve's normalized income
*/
function getReserveNormalizedIncome(address asset) external view returns (uint256);

}
Loading