-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #151 from gildlab/2024-10-27-groom
2024 10 27 groom
- Loading branch information
Showing
20 changed files
with
328 additions
and
330 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// SPDX-License-Identifier: LicenseRef-DCL-1.0 | ||
// SPDX-FileCopyrightText: Copyright (c) 2020 thedavidmeister | ||
pragma solidity =0.8.25; | ||
|
||
import {IPriceOracleV2} from "../interface/IPriceOracleV2.sol"; | ||
import {Address} from "openzeppelin-contracts/contracts/utils/Address.sol"; | ||
|
||
abstract contract PriceOracleV2 is IPriceOracleV2 { | ||
/// Hook for implementing contracts to define their own price logic. | ||
function _price() internal virtual returns (uint256); | ||
|
||
/// @inheritdoc IPriceOracleV2 | ||
function price() external payable override returns (uint256) { | ||
uint256 val = _price(); | ||
Address.sendValue(payable(msg.sender), address(this).balance); | ||
return val; | ||
} | ||
|
||
/// Need to accept refunds from the oracle. | ||
fallback() external payable {} | ||
|
||
/// Need to accept refunds from the oracle. | ||
receive() external payable {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// SPDX-License-Identifier: LicenseRef-DCL-1.0 | ||
// SPDX-FileCopyrightText: Copyright (c) 2020 thedavidmeister | ||
pragma solidity =0.8.25; | ||
|
||
import {PriceOracleV2} from "src/abstract/PriceOracleV2.sol"; | ||
import {Test} from "forge-std/Test.sol"; | ||
|
||
contract PriceOracleV2TestImpl is PriceOracleV2 { | ||
uint256 internal sPrice; | ||
|
||
constructor(uint256 price) { | ||
sPrice = price; | ||
} | ||
|
||
function _price() internal view override returns (uint256) { | ||
return sPrice; | ||
} | ||
|
||
function setPrice(uint256 price) external { | ||
sPrice = price; | ||
} | ||
} | ||
|
||
contract PriceOracleV2Test is Test { | ||
address constant ALICE = address(uint160(uint256(keccak256("ALICE")))); | ||
|
||
function testPriceOracleV2(uint256 priceA, uint256 priceB) external { | ||
PriceOracleV2TestImpl oracle = new PriceOracleV2TestImpl(priceA); | ||
|
||
vm.prank(ALICE); | ||
assertEq(oracle.price(), priceA); | ||
|
||
oracle.setPrice(priceB); | ||
|
||
vm.prank(ALICE); | ||
assertEq(oracle.price(), priceB); | ||
} | ||
|
||
function testPriceOracleV2Refund(uint256 priceA) external { | ||
PriceOracleV2TestImpl oracle = new PriceOracleV2TestImpl(priceA); | ||
|
||
vm.deal(ALICE, 1e18); | ||
vm.prank(ALICE); | ||
assertEq(oracle.price{value: 1e18}(), priceA); | ||
assertEq(ALICE.balance, 1e18); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// SPDX-License-Identifier: LicenseRef-DCL-1.0 | ||
// SPDX-FileCopyrightText: Copyright (c) 2020 thedavidmeister | ||
pragma solidity =0.8.25; | ||
|
||
import {Test, console2} from "forge-std/Test.sol"; | ||
import {FtsoV2LTSFeedOracle, FtsoV2LTSFeedOracleConfig} from "src/concrete/oracle/FtsoV2LTSFeedOracle.sol"; | ||
import {FLR_USD_FEED_ID} from "rain.flare/lib/lts/LibFtsoV2LTS.sol"; | ||
import {LibFork} from "rain.flare/../test/fork/LibFork.sol"; | ||
import {StalePrice} from "rain.flare/err/ErrFtso.sol"; | ||
import {IFeeCalculator} from "flare-smart-contracts-v2/userInterfaces/IFeeCalculator.sol"; | ||
import {LibFlareContractRegistry} from "rain.flare/lib/registry/LibFlareContractRegistry.sol"; | ||
import {IGoverned, IGovernanceSettings} from "rain.flare/interface/IGoverned.sol"; | ||
import {IGovernedFeeCalculator} from "rain.flare/interface/IGovernedFeeCalculator.sol"; | ||
|
||
uint256 constant BLOCK_NUMBER = 31993648; | ||
|
||
contract FtsoV2LTSFeedOracleTest is Test { | ||
address constant ALICE = address(uint160(uint256(keccak256("ALICE")))); | ||
|
||
function testFtsoV2LTSFeedOracle() external { | ||
vm.createSelectFork(LibFork.rpcUrlFlare(vm), BLOCK_NUMBER); | ||
|
||
FtsoV2LTSFeedOracle oracle = | ||
new FtsoV2LTSFeedOracle(FtsoV2LTSFeedOracleConfig({feedId: FLR_USD_FEED_ID, staleAfter: 60})); | ||
|
||
vm.prank(ALICE); | ||
assertEq(oracle.price(), 0.0141082e18); | ||
} | ||
|
||
function testFtsoV2LTSFeedOracleStale() external { | ||
vm.createSelectFork(LibFork.rpcUrlFlare(vm), BLOCK_NUMBER); | ||
|
||
FtsoV2LTSFeedOracle oracle = | ||
new FtsoV2LTSFeedOracle(FtsoV2LTSFeedOracleConfig({feedId: FLR_USD_FEED_ID, staleAfter: 60})); | ||
|
||
uint256 feedTime = 1730042030; | ||
|
||
vm.warp(block.timestamp + 61); | ||
vm.prank(ALICE); | ||
vm.expectRevert(abi.encodeWithSelector(StalePrice.selector, feedTime, 60)); | ||
oracle.price(); | ||
} | ||
|
||
/// forge-config: default.fuzz.runs = 1 | ||
function testFtsoV2LTSFeedOraclePaid(uint128 fee) external { | ||
vm.assume(fee > 0); | ||
vm.createSelectFork(LibFork.rpcUrlFlare(vm), BLOCK_NUMBER); | ||
|
||
uint256 timelock; | ||
{ | ||
IFeeCalculator feeCalculator = LibFlareContractRegistry.getFeeCalculator(); | ||
address gov = IGoverned(address(feeCalculator)).governance(); | ||
IGovernanceSettings govSettings = IGoverned(address(feeCalculator)).governanceSettings(); | ||
address[] memory executors = govSettings.getExecutors(); | ||
timelock = govSettings.getTimelock(); | ||
vm.prank(gov); | ||
bytes21[] memory feeds = new bytes21[](1); | ||
feeds[0] = bytes21(FLR_USD_FEED_ID); | ||
uint256[] memory fees = new uint256[](1); | ||
fees[0] = fee; | ||
bytes4 setFeedsFeesSelector = bytes4(0x755fcecd); | ||
IGovernedFeeCalculator(address(feeCalculator)).setFeedsFees(feeds, fees); | ||
vm.warp(block.timestamp + timelock); | ||
vm.prank(executors[0]); | ||
IGoverned(address(feeCalculator)).executeGovernanceCall(setFeedsFeesSelector); | ||
} | ||
|
||
FtsoV2LTSFeedOracle oracle = | ||
new FtsoV2LTSFeedOracle(FtsoV2LTSFeedOracleConfig({feedId: FLR_USD_FEED_ID, staleAfter: 60 + timelock})); | ||
|
||
vm.deal(ALICE, fee); | ||
vm.prank(ALICE); | ||
assertEq(oracle.price{value: fee}(), 0.0141082e18); | ||
assertEq(ALICE.balance, 0); | ||
|
||
vm.deal(ALICE, fee + 5); | ||
vm.prank(ALICE); | ||
assertEq(oracle.price{value: fee + 5}(), 0.0141082e18); | ||
assertEq(ALICE.balance, 5); | ||
|
||
vm.deal(ALICE, fee); | ||
vm.prank(ALICE); | ||
// Out of funds here due to insufficient value for fee. | ||
vm.expectRevert(); | ||
oracle.price{value: fee - 1}(); | ||
} | ||
} |
Oops, something went wrong.