Skip to content

Commit

Permalink
Full fuzz-invariant-integration testing for an open position
Browse files Browse the repository at this point in the history
  • Loading branch information
mario-eth committed Mar 7, 2024
1 parent f855002 commit 4b13a49
Show file tree
Hide file tree
Showing 7 changed files with 484 additions and 18 deletions.
9 changes: 5 additions & 4 deletions contracts/mock/MockOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "@openzeppelin/contracts/access/Ownable.sol";

import "../utils/BlueberryErrors.sol" as Errors;
import "../interfaces/IBaseOracle.sol";
import { console2 } from "forge-std/console2.sol";

contract MockOracle is IBaseOracle, Ownable {
mapping(address => uint256) public prices; // Mapping from token to price (times 1e18).
Expand All @@ -16,6 +17,7 @@ contract MockOracle is IBaseOracle, Ownable {
/// @dev Return the USD based price of the given input, multiplied by 10**18.
/// @param token The ERC-20 token to check the value.
function getPrice(address token) external view override returns (uint256) {
console2.log("getting price for ", token);
return prices[token];
}

Expand All @@ -26,12 +28,11 @@ contract MockOracle is IBaseOracle, Ownable {
/// @dev Set the prices of the given token addresses.
/// @param tokens The token addresses to set the prices.
/// @param pxs The price data points, representing token value in USD, based 1e18.
function setPrice(
address[] memory tokens,
uint256[] memory pxs
) external onlyOwner {
function setPrice(address[] memory tokens, uint256[] memory pxs) external onlyOwner {
if (tokens.length != pxs.length) revert Errors.INPUT_ARRAY_MISMATCH();
for (uint256 i = 0; i < tokens.length; i++) {
console2.log("set price", tokens[i], pxs[i]);

prices[tokens[i]] = pxs[i];
emit SetPrice(tokens[i], pxs[i]);
}
Expand Down
6 changes: 3 additions & 3 deletions contracts/wrapper/WConvexBooster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ contract WConvexBooster is IWConvexBooster, BaseWrapper, ReentrancyGuardUpgradea
/// @dev Mapping from token id to initialTokenPerShare
mapping(uint256 => mapping(address => uint256)) private _initialTokenPerShare;
/// @dev CVX reward per share by pid
mapping(uint256 => uint256) private _cvxPerShareByPid;
mapping(uint256 => uint256) internal _cvxPerShareByPid;
/// token id => cvxPerShareDebt;
mapping(uint256 => uint256) private _cvxPerShareDebt;
mapping(uint256 => uint256) internal _cvxPerShareDebt;
/// @dev pid => last crv reward per token
mapping(uint256 => uint256) private _lastCrvPerTokenByPid;
mapping(uint256 => uint256) internal _lastCrvPerTokenByPid;
/// @dev pid => escrow contract address
mapping(uint256 => address) private _escrows;
/// @dev pid => A set of extra rewarders
Expand Down
364 changes: 353 additions & 11 deletions test/foundry/fork/spell/BankConvexSpell.t.sol

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions test/foundry/fork/spell/SpellBaseTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,9 @@ abstract contract SpellBaseTest is BaseTest {

vm.label(address(0x737df47A4BdDB0D71b5b22c72B369d0B29329b40), "bankImpl");
}

/**
* @dev Sets the mock oracle for various tokens
*/
function _setMockOracle() internal virtual;
}
23 changes: 23 additions & 0 deletions test/foundry/fork/spell/mocks/WConvexBoosterMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: MIT

import { WConvexBooster } from "@contracts/wrapper/WConvexBooster.sol";

pragma solidity 0.8.22;

contract WConvexBoosterMock is WConvexBooster {
function cvxPerShareByPid(uint256 pid) public returns (uint256) {
return _cvxPerShareByPid[pid];
}

function cvxPerShareDebt(uint256 pid) public returns (uint256) {
return _cvxPerShareDebt[pid];
}

function lastCrvPerTokenByPid(uint256 pid) public returns (uint256) {
return _lastCrvPerTokenByPid[pid];
}

function getCvxPendingReward(uint256 amount) public returns (uint256) {
return _getCvxPendingReward(amount);
}
}
68 changes: 68 additions & 0 deletions test/foundry/interfaces/IExtCoreOracle.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.22;

import { IBaseOracle } from "@contracts/interfaces/IBaseOracle.sol";

/**
* @title IExtCoreOracle
* @notice Interface for the CoreOracle contract which provides price feed data for assets in the Blueberry protocol.
*/
interface IExtCoreOracle is IBaseOracle {
/*//////////////////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////////////////*/

/**
* @notice Event emitted when the owner sets a new oracle route for a given token.
* @param token The ERC20 token for which the oracle route is set.
* @param route The address of the oracle route.
*/
event SetRoute(address indexed token, address route);

/*//////////////////////////////////////////////////////////////////////////
FUNCTIONS
//////////////////////////////////////////////////////////////////////////*/

/**
* @notice Check if the given ERC20 token is supported by the oracle.
* @param token The ERC20 token to check support for.
* @return A boolean indicating whether the token is supported or not.
*/
function isTokenSupported(address token) external view returns (bool);

/**
* @notice Check if the oracle supports the underlying token of a given ERC1155 wrapper.
* @dev Only meant to validate wrappers of the Blueberry protocol, such as WERC20.
* @param token ERC1155 token address to check support for.
* @param tokenId ERC1155 token id to check support for.
* @return A boolean indicating whether the wrapped token is supported or not.
*/
function isWrappedTokenSupported(address token, uint256 tokenId) external view returns (bool);

/**
* @notice Returns the USD value of a specific wrapped ERC1155 token.
* @param token ERC1155 token address.
* @param id ERC1155 token id.
* @param amount Amount of the token for which to get the USD value, normalized to 1e18 decimals.
* @return The USD value of the given wrapped token amount.
*/
function getWrappedTokenValue(address token, uint256 id, uint256 amount) external view returns (uint256);

/**
* @notice Returns the USD value of a given amount of a specific ERC20 token.
* @param token ERC20 token address.
* @param amount Amount of the ERC20 token for which to get the USD value.
* @return The USD value of the given token amount.
*/
function getTokenValue(address token, uint256 amount) external view returns (uint256);

/**
* @notice Fetches the oracle route for the given token.
* @param token Address of the token to get the route for.
* @return The address of the oracle route for the given token.
*/
function getRoute(address token) external view returns (address);

function setRoutes(address[] calldata tokens, address[] calldata oracleRoutes) external;
}
27 changes: 27 additions & 0 deletions test/foundry/interfaces/IStakingRewards.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

interface IStakingRewards {
// Views
function lastTimeRewardApplicable() external view returns (uint256);

function rewardPerToken() external view returns (uint256);

function earned(address account) external view returns (uint256);

function getRewardForDuration() external view returns (uint256);

function totalSupply() external view returns (uint256);

function balanceOf(address account) external view returns (uint256);

// Mutative

function stake(uint256 amount) external;

function withdraw(uint256 amount) external;

function getReward() external;

function exit() external;
}

0 comments on commit 4b13a49

Please sign in to comment.