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

Fixing _doCheckValueType #806

Merged
merged 9 commits into from
Jul 25, 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
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 }}
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);
}
6 changes: 3 additions & 3 deletions packages/contracts/contracts/LeverageMacroBase.sol
Original file line number Diff line number Diff line change
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
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