Skip to content

Commit

Permalink
Merge pull request #804 from ebtc-protocol/release-0.8
Browse files Browse the repository at this point in the history
Release 0.8
  • Loading branch information
wtj2021 authored Jul 25, 2024
2 parents bfbe735 + 6f108cb commit 703261b
Show file tree
Hide file tree
Showing 15 changed files with 489 additions and 58 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/foundry-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ jobs:

- name: Foundry Test
working-directory: ./packages/contracts/
run: forge test -vvv ${{ github.base_ref == 'main' && '--fuzz-runs 200' || '' }}
run: forge test -vv ${{ github.base_ref == 'main' && '--fuzz-runs 200' || '' }}
env:
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
38 changes: 0 additions & 38 deletions .github/workflows/invariant-test.yml

This file was deleted.

32 changes: 32 additions & 0 deletions packages/contracts/contracts/ChronicleAdapter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import {IPriceFetcher} from "./Interfaces/IOracleCaller.sol";
import {IChronicle} from "./Interfaces/IChronicle.sol";

/// @notice Chronicle oracle adapter for EbtcFeed
/// @notice https://etherscan.io/address/0x02238bb0085395ae52cd4755456891fc2fd5934d
contract ChronicleAdapter is IPriceFetcher {
uint256 public constant MAX_STALENESS = 24 hours;
uint256 public constant ADAPTER_PRECISION = 1e18;

address public immutable BTC_STETH_FEED;
uint256 public immutable FEED_PRECISION;

constructor(address _btcStEthFeed) {
BTC_STETH_FEED = _btcStEthFeed;

uint256 feedDecimals = IChronicle(BTC_STETH_FEED).decimals();
require(feedDecimals > 0 && feedDecimals <= 18);

FEED_PRECISION = 10 ** feedDecimals;
}

function fetchPrice() external returns (uint256) {
(uint256 price, uint256 age) = IChronicle(BTC_STETH_FEED).readWithAge();
uint256 staleness = block.timestamp - age;
if (staleness > MAX_STALENESS) revert("ChronicleAdapter: stale price");

return (price * ADAPTER_PRECISION) / FEED_PRECISION;
}
}
17 changes: 17 additions & 0 deletions packages/contracts/contracts/Interfaces/IChronicle.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

/// @title IChronicle
/// @author chronicleprotocol (https://github.com/chronicleprotocol/chronicle-std/blob/ea9afe78a1d33245afcdbcc3f530ee9cbd7cde28/src/IChronicle.sol)
/// @notice Partial interface for Chronicle Protocol's oracle products.
interface IChronicle {
/// @notice Returns the oracle's current value and its age.
/// @dev Reverts if no value set.
/// @return value The oracle's current value.
/// @return age The value's age.
function readWithAge() external view returns (uint256 value, uint256 age);

/// @notice Returns the oracle's decimals.
/// @return The decimals of the oracle.
function decimals() external view returns (uint8);
}
18 changes: 9 additions & 9 deletions packages/contracts/contracts/LeverageMacroBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ abstract contract LeverageMacroBase {
LeverageMacroOperation calldata operation,
PostOperationCheck postCheckType,
PostCheckParams calldata checkParams
) external {
) external virtual {
_assertOwner();

// Figure out the expected CDP ID using sortedCdps.toCdpId
Expand Down Expand Up @@ -279,11 +279,11 @@ abstract contract LeverageMacroBase {
// Early return
return;
} else if (check.operator == Operator.gte) {
require(check.value >= valueToCheck, "!LeverageMacroReference: gte post check");
require(valueToCheck >= check.value, "!LeverageMacroBase: gte post check");
} else if (check.operator == Operator.lte) {
require(check.value <= valueToCheck, "!LeverageMacroReference: let post check");
require(valueToCheck <= check.value, "!LeverageMacroBase: lte post check");
} else if (check.operator == Operator.equal) {
require(check.value == valueToCheck, "!LeverageMacroReference: equal post check");
require(check.value == valueToCheck, "!LeverageMacroBase: equal post check");
} else {
revert("Operator not found");
}
Expand Down Expand Up @@ -507,7 +507,7 @@ abstract contract LeverageMacroBase {
}

/// @dev Must be memory since we had to decode it
function _openCdpCallback(bytes memory data) internal {
function _openCdpCallback(bytes memory data) internal virtual {
OpenCdpOperation memory flData = abi.decode(data, (OpenCdpOperation));

/**
Expand All @@ -521,7 +521,7 @@ abstract contract LeverageMacroBase {
);
}

function _openCdpForCallback(bytes memory data) internal {
function _openCdpForCallback(bytes memory data) internal virtual {
OpenCdpForOperation memory flData = abi.decode(data, (OpenCdpForOperation));

/**
Expand All @@ -537,15 +537,15 @@ abstract contract LeverageMacroBase {
}

/// @dev Must be memory since we had to decode it
function _closeCdpCallback(bytes memory data) internal {
function _closeCdpCallback(bytes memory data) internal virtual {
CloseCdpOperation memory flData = abi.decode(data, (CloseCdpOperation));

// Initiator must be added by this contract, else it's not trusted
borrowerOperations.closeCdp(flData._cdpId);
}

/// @dev Must be memory since we had to decode it
function _adjustCdpCallback(bytes memory data) internal {
function _adjustCdpCallback(bytes memory data) internal virtual {
AdjustCdpOperation memory flData = abi.decode(data, (AdjustCdpOperation));

borrowerOperations.adjustCdpWithColl(
Expand All @@ -559,7 +559,7 @@ abstract contract LeverageMacroBase {
);
}

function _claimSurplusCallback() internal {
function _claimSurplusCallback() internal virtual {
borrowerOperations.claimSurplusCollShares();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ contract CollateralTokenTester is ICollateralToken, ICollateralTokenOracle, Owna
uint256 private slotsPerEpoch = 32;
uint256 private secondsPerSlot = 12;

bool public submitShouldRevert;

receive() external payable {
deposit();
}
Expand All @@ -53,6 +55,18 @@ contract CollateralTokenTester is ICollateralToken, ICollateralTokenOracle, Owna
emit Deposit(msg.sender, msg.value, _share);
}

function submit(address _referral) public payable returns (uint256) {
if (submitShouldRevert) {
revert();
}

deposit();
}

function setSubmitShouldRevert(bool _submitShouldRevert) public {
submitShouldRevert = _submitShouldRevert;
}

/// @dev Deposit collateral without ether for testing purposes
function forceDeposit(uint256 ethToDeposit) external {
if (!isUncappedMinter[msg.sender]) {
Expand Down
4 changes: 4 additions & 0 deletions packages/contracts/contracts/TestContracts/MockAggregator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ contract MockAggregator is AggregatorV3Interface {
return (prevRoundId, prevPrice, 0, updateTime, 0);
}

function readWithAge() external view returns (uint256 value, uint256 age) {
return (uint256(price), updateTime);
}

function description() external pure override returns (string memory) {
return "";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ contract CDPManagerRedemptionsTest is eBTCBaseInvariants {
}

function testMultipleRedemption(uint256 _cdpNumber, uint256 _collAmt) public {
_cdpNumber = bound(_cdpNumber, 2, 1000);
_cdpNumber = bound(_cdpNumber, 2, 500);
_collAmt = bound(_collAmt, 22e17 + 1, 10000e18);
uint256 _price = priceFeedMock.getPrice();

Expand Down
44 changes: 44 additions & 0 deletions packages/contracts/foundry_test/ChronicleAdapter.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.17;

import "forge-std/Test.sol";
import {MockAggregator} from "../contracts/TestContracts/MockAggregator.sol";
import {ChronicleAdapter} from "../contracts/ChronicleAdapter.sol";

contract ChainlinkAdapterTest is Test {
MockAggregator internal stEthBtcAggregator;
ChronicleAdapter internal chronicleAdapter;

constructor() {}

function testSuccessPrecision8() public {
stEthBtcAggregator = new MockAggregator(8);
chronicleAdapter = new ChronicleAdapter(address(stEthBtcAggregator));

stEthBtcAggregator.setUpdateTime(block.timestamp);
stEthBtcAggregator.setPrice(5341495);

assertEq(chronicleAdapter.fetchPrice(), 53414950000000000);
}

function testSuccessPrecision18() public {
stEthBtcAggregator = new MockAggregator(18);
chronicleAdapter = new ChronicleAdapter(address(stEthBtcAggregator));

stEthBtcAggregator.setUpdateTime(block.timestamp);
stEthBtcAggregator.setPrice(53414952714851023);

assertEq(chronicleAdapter.fetchPrice(), 53414952714851023);
}

function testFailureFreshness() public {
stEthBtcAggregator = new MockAggregator(18);
chronicleAdapter = new ChronicleAdapter(address(stEthBtcAggregator));

stEthBtcAggregator.setUpdateTime(block.timestamp - 24 hours - 1);
stEthBtcAggregator.setPrice(100e18);

vm.expectRevert("ChronicleAdapter: stale price");
chronicleAdapter.fetchPrice();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,8 @@ contract SimplifiedDiamondLikeLeverageTests is eBTCBaseInvariants {
uint256 debt = 1e18;
uint256 margin = 5 ether;
uint256 flAmount = _debtToCollateral(debt);
uint256 totalCollateral = ((flAmount + margin) * 9995) / 1e4;
// remove 3 basis points from flAmount to account for flash loan fee
uint256 totalCollateral = ((flAmount * 9997) / 10000) + margin;

LeverageMacroBase.OpenCdpForOperation memory cdp;

Expand All @@ -477,6 +478,15 @@ contract SimplifiedDiamondLikeLeverageTests is eBTCBaseInvariants {
address(eBTCToken),
address(collateral),
debt
),
_postCheckParams: _getPostCheckParams(
bytes32(0),
debt,
// expected collateral should exclude LIQUIDATOR_REWARD and be converted to shares
collateral.getSharesByPooledEth(
totalCollateral - borrowerOperations.LIQUIDATOR_REWARD()
),
ICdpManagerData.Status.active
)
});
}
Expand Down Expand Up @@ -505,7 +515,8 @@ contract SimplifiedDiamondLikeLeverageTests is eBTCBaseInvariants {
LeverageMacroBase.OpenCdpForOperation memory _cdp,
uint256 _flAmount,
uint256 _stEthBalance,
bytes memory _exchangeData
bytes memory _exchangeData,
LeverageMacroBase.PostCheckParams memory _postCheckParams
) internal {
LeverageMacroBase.LeverageMacroOperation memory op;

Expand All @@ -521,12 +532,7 @@ contract SimplifiedDiamondLikeLeverageTests is eBTCBaseInvariants {
_flAmount,
op,
LeverageMacroBase.PostOperationCheck.openCdp,
_getPostCheckParams(
bytes32(0),
_cdp.eBTCToMint,
_cdp.stETHToDeposit,
ICdpManagerData.Status.active
)
_postCheckParams
);
}

Expand Down
Loading

0 comments on commit 703261b

Please sign in to comment.