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

feat: BlastYield contract #103

Merged
merged 39 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
b93db9e
feat: BlastYield contract
stonehengeLR Jun 30, 2024
8445190
fix: Compilier error
stonehengeLR Jul 1, 2024
f9fcf92
fix: Compilier error
stonehengeLR Jul 1, 2024
2edb97e
test: BlastYield Tests
stonehengeLR Jul 2, 2024
edbe35f
test: BlastYield Test Fixes
stonehengeLR Jul 3, 2024
fe415c3
fix: Prettier and Mocks
stonehengeLR Jul 3, 2024
b7e2d0d
fix: Increase node version for github actions
stonehengeLR Jul 3, 2024
d1c8d3f
fix: Increase node version for github actions
stonehengeLR Jul 3, 2024
9ca51b7
fix: Update Access Control to OwnableTwoSteps
stonehengeLR Jul 4, 2024
6f67949
feat: Private function to allow both access control and ownable two s…
stonehengeLR Jul 4, 2024
e9cb33e
fix: Remove virtual from _claim
stonehengeLR Jul 4, 2024
cc82877
fix: Rename _owner to _governor
stonehengeLR Jul 4, 2024
e7dcbeb
fix: Fix _claim notice
stonehengeLR Jul 4, 2024
2517444
fix: Pass mockPoints
stonehengeLR Jul 4, 2024
88ee19b
fix: Remove operator role
stonehengeLR Jul 4, 2024
ce33daf
fix: Mock naming
stonehengeLR Jul 4, 2024
591cf53
fix: Get modifier from TestHelpers
stonehengeLR Jul 4, 2024
0ba5d3a
chore: Update solmate to openzeppelin
stonehengeLR Jul 4, 2024
acda72e
fix: Governor comment
stonehengeLR Jul 4, 2024
4143be9
fix: TestHelpers inheritance
stonehengeLR Jul 4, 2024
5946c5f
feat: Split BlastYield into multiple contracts
stonehengeLR Jul 5, 2024
06cebd1
fix: Remove event
stonehengeLR Jul 5, 2024
70b57dd
fix: Remove empty line
stonehengeLR Jul 5, 2024
f80299b
fix: YieldMode GasMode fix
stonehengeLR Jul 5, 2024
96c81ec
fix: Fix blast points notice
stonehengeLR Jul 5, 2024
ed78762
fix: Refix YieldMode GasMode
stonehengeLR Jul 5, 2024
bc6d3e8
fix: Test names
stonehengeLR Jul 5, 2024
3d7fac2
fix: Improve notices
stonehengeLR Jul 5, 2024
666c866
fix: Fix native yield and points tests
stonehengeLR Jul 5, 2024
c01c63d
fix: YieldMode GasMode naming BlastNativeYield_Test
stonehengeLR Jul 5, 2024
68bb39c
fix: Unused variables and imports
stonehengeLR Jul 6, 2024
1d6537f
fix: Remove variable alias
stonehengeLR Jul 6, 2024
0729c1a
fix: Another unused import
stonehengeLR Jul 6, 2024
9183289
fix: Remove variable alias
stonehengeLR Jul 6, 2024
602487e
fix: Fix _claim notice
stonehengeLR Jul 6, 2024
534d053
fix: Fix _claim notice
stonehengeLR Jul 6, 2024
39e688a
fix: Renaming
stonehengeLR Jul 7, 2024
763c63d
fix: Notice length
stonehengeLR Jul 7, 2024
3cfa074
fix: Whitespace formatting
stonehengeLR Jul 7, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@

pragma solidity ^0.8.20;

import {IBlast, YieldMode as IBlast__YieldMode, GasMode as IBlast__GasMode} from "./interfaces/IBlast.sol";
import {IBlastPoints} from "./interfaces/IBlastPoints.sol";
import {BlastNativeYield} from "./BlastNativeYield.sol";
import {IERC20Rebasing, YieldMode as IERC20Rebasing__YieldMode} from "./interfaces/IERC20Rebasing.sol";

/**
* @title BlastYield
* @notice This contract is a base contract for future contracts that wish to claim Blast WETH or USDB yield to inherit from.
* @title BlastERC20RebasingYield
* @notice This contract is a base contract for future contracts that wish to claim Blast WETH or USDB yield to inherit from
* @author LooksRare protocol team (👀,💎)
*/
contract BlastYield {
contract BlastERC20RebasingYield is BlastNativeYield {
address public immutable WETH;
address public immutable USDB;

Expand All @@ -30,12 +29,10 @@ contract BlastYield {
address _governor,
address _usdb,
address _weth
) {
) BlastNativeYield(_blast, _blastPoints, _blastPointsOperator, _governor) {
WETH = _weth;
USDB = _usdb;

IBlast(_blast).configure(IBlast__YieldMode.CLAIMABLE, IBlast__GasMode.CLAIMABLE, _governor);
IBlastPoints(_blastPoints).configurePointsOperator(_blastPointsOperator);
IERC20Rebasing(_weth).configure(IERC20Rebasing__YieldMode.CLAIMABLE);
IERC20Rebasing(_usdb).configure(IERC20Rebasing__YieldMode.CLAIMABLE);
}
Expand Down
27 changes: 27 additions & 0 deletions contracts/BlastNativeYield.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import {IBlast, YieldMode as IBlast__YieldMode, GasMode as IBlast__GasMode} from "./interfaces/IBlast.sol";
0xhiroshi marked this conversation as resolved.
Show resolved Hide resolved
import {BlastPoints} from "./BlastPoints.sol";
/**
0xhiroshi marked this conversation as resolved.
Show resolved Hide resolved
* @title BlastNativeYield
* @notice This contract is a base contract for future contracts that wish to claim native yield and Blast points to inherit from
* @author LooksRare protocol team (👀,💎)
*/
contract BlastNativeYield is BlastPoints {
/**
* @param _blast Blast precompile
* @param _blastPoints Blast points
* @param _blastPointsOperator Blast points operator
* @param _governor The address that’s allowed to claim the contract’s yield and gas
*/
constructor(
address _blast,
address _blastPoints,
address _blastPointsOperator,
address _governor
) BlastPoints(_blastPoints, _blastPointsOperator) {
IBlast(_blast).configure(IBlast__YieldMode.CLAIMABLE, IBlast__GasMode.CLAIMABLE, _governor);
}
}
20 changes: 20 additions & 0 deletions contracts/BlastPoints.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import {IBlastPoints} from "./interfaces/IBlastPoints.sol";

/**
* @title BlastPoints
* @notice This contract is a base contract for future contracts that wish to claim Blast points to inherit from
0xhiroshi marked this conversation as resolved.
Show resolved Hide resolved
* @author LooksRare protocol team (👀,💎)
*/
contract BlastPoints {
/**
* @param _blastPoints Blast points
* @param _blastPointsOperator Blast points operator
*/
constructor(address _blastPoints, address _blastPointsOperator) {
IBlastPoints(_blastPoints).configurePointsOperator(_blastPointsOperator);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ pragma solidity ^0.8.20;

import {IOwnableTwoSteps} from "../../contracts/interfaces/IOwnableTwoSteps.sol";
import {OwnableTwoSteps} from "../../contracts/OwnableTwoSteps.sol";
import {BlastYield} from "../../contracts/BlastYield.sol";
import {Test} from "../../lib/forge-std/src/Test.sol";
import {BlastERC20RebasingYield} from "../../contracts/BlastERC20RebasingYield.sol";
import {TestHelpers} from "./utils/TestHelpers.sol";
import {YieldMode as IBlast__YieldMode, GasMode as IBlast__GasMode} from "../../contracts/interfaces/IBlast.sol";
import {YieldMode as IERC20Rebasing__YieldMode} from "../../contracts/interfaces/IERC20Rebasing.sol";
Expand All @@ -15,27 +14,30 @@ import {MockBlastPoints} from "../mock/MockBlastPoints.sol";
import {MockBlastWETH} from "../mock/MockBlastWETH.sol";
import {MockBlastYield} from "../mock/MockBlastYield.sol";

contract BlastYieldOwnableTwoSteps is BlastYield, OwnableTwoSteps {
contract BlastERC20RebasingYieldOwnableTwoSteps is BlastERC20RebasingYield, OwnableTwoSteps {
constructor(
address _blast,
address _blastPoints,
address _blastPointsOperator,
address _owner,
address _usdb,
address _weth
) BlastYield(_blast, _blastPoints, _blastPointsOperator, _owner, _usdb, _weth) OwnableTwoSteps(_owner) {}
)
BlastERC20RebasingYield(_blast, _blastPoints, _blastPointsOperator, _owner, _usdb, _weth)
OwnableTwoSteps(_owner)
{}

function claim(address wethReceiver, address usdbReceiver) public onlyOwner {
_claim(wethReceiver, usdbReceiver);
}
}

contract BlastYieldOwnableTwoSteps_Test is TestHelpers {
contract BlastERC20RebasingYieldOwnableTwoStepsOwnableTwoSteps_Test is TestHelpers {
0xhiroshi marked this conversation as resolved.
Show resolved Hide resolved
MockBlastWETH private weth;
MockBlastERC20 private usdb;
MockBlastYield private mockBlastYield;
MockBlastPoints private mockBlastPoints;
BlastYieldOwnableTwoSteps private blastYieldOwnableTwoSteps;
BlastERC20RebasingYieldOwnableTwoSteps private blastERC20RebasingYieldOwnableTwoSteps;

address public owner = address(69);
address public operator = address(420);
Expand All @@ -47,7 +49,7 @@ contract BlastYieldOwnableTwoSteps_Test is TestHelpers {
usdb = new MockBlastERC20("USDB", "USDB");
mockBlastYield = new MockBlastYield();
mockBlastPoints = new MockBlastPoints();
blastYieldOwnableTwoSteps = new BlastYieldOwnableTwoSteps(
blastERC20RebasingYieldOwnableTwoSteps = new BlastERC20RebasingYieldOwnableTwoSteps(
address(mockBlastYield),
address(mockBlastPoints),
operator,
Expand All @@ -58,34 +60,27 @@ contract BlastYieldOwnableTwoSteps_Test is TestHelpers {
}

function test_setUpState() public {
assertEq(blastYieldOwnableTwoSteps.WETH(), address(weth));
assertEq(blastYieldOwnableTwoSteps.USDB(), address(usdb));
assertEq(blastERC20RebasingYieldOwnableTwoSteps.WETH(), address(weth));
assertEq(blastERC20RebasingYieldOwnableTwoSteps.USDB(), address(usdb));

(IBlast__YieldMode yieldMode, IBlast__GasMode gasMode, address governor) = mockBlastYield.config(
address(blastYieldOwnableTwoSteps)
);
assertEq(uint8(yieldMode), uint8(IBlast__YieldMode.CLAIMABLE));
assertEq(uint8(gasMode), uint8(IBlast__GasMode.CLAIMABLE));
assertEq(governor, owner);

IERC20Rebasing__YieldMode wethYieldMode = weth.yieldMode(address(blastYieldOwnableTwoSteps));
IERC20Rebasing__YieldMode wethYieldMode = weth.yieldMode(address(blastERC20RebasingYieldOwnableTwoSteps));
assertEq(uint8(wethYieldMode), uint8(IERC20Rebasing__YieldMode.CLAIMABLE));

IERC20Rebasing__YieldMode usdbYieldMode = usdb.yieldMode(address(blastYieldOwnableTwoSteps));
IERC20Rebasing__YieldMode usdbYieldMode = usdb.yieldMode(address(blastERC20RebasingYieldOwnableTwoSteps));
assertEq(uint8(usdbYieldMode), uint8(IERC20Rebasing__YieldMode.CLAIMABLE));
}

function test_claim() public asPrankedUser(owner) {
blastYieldOwnableTwoSteps.claim(TREASURY, TREASURY);
blastERC20RebasingYieldOwnableTwoSteps.claim(TREASURY, TREASURY);

assertEq(weth.balanceOf(address(blastYieldOwnableTwoSteps)), 0);
assertEq(usdb.balanceOf(address(blastYieldOwnableTwoSteps)), 0);
assertEq(weth.balanceOf(address(blastERC20RebasingYieldOwnableTwoSteps)), 0);
assertEq(usdb.balanceOf(address(blastERC20RebasingYieldOwnableTwoSteps)), 0);
assertEq(weth.balanceOf(TREASURY), 1 ether);
assertEq(usdb.balanceOf(TREASURY), 1 ether);
}

function test_claim_RevertIf_NotOwner() public asPrankedUser(user1) {
vm.expectRevert(IOwnableTwoSteps.NotOwner.selector);
blastYieldOwnableTwoSteps.claim(TREASURY, TREASURY);
blastERC20RebasingYieldOwnableTwoSteps.claim(TREASURY, TREASURY);
}
}
51 changes: 51 additions & 0 deletions test/foundry/BlastNativeYield.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import {IOwnableTwoSteps} from "../../contracts/interfaces/IOwnableTwoSteps.sol";
import {OwnableTwoSteps} from "../../contracts/OwnableTwoSteps.sol";
import {BlastNativeYield} from "../../contracts/BlastNativeYield.sol";
import {TestHelpers} from "./utils/TestHelpers.sol";
import {YieldMode as IBlast__YieldMode, GasMode as IBlast__GasMode} from "../../contracts/interfaces/IBlast.sol";

import {MockBlastPoints} from "../mock/MockBlastPoints.sol";
import {MockBlastYield} from "../mock/MockBlastYield.sol";

contract BlastNativeYieldOwnableTwoSteps is BlastNativeYield, OwnableTwoSteps {
0xhiroshi marked this conversation as resolved.
Show resolved Hide resolved
constructor(
address _blast,
address _blastPoints,
address _blastPointsOperator,
address _owner
) BlastNativeYield(_blast, _blastPoints, _blastPointsOperator, _owner) OwnableTwoSteps(_owner) {}
}

contract BlastNativeYieldOwnableTwoSteps_Test is TestHelpers {
0xhiroshi marked this conversation as resolved.
Show resolved Hide resolved
MockBlastYield private mockBlastYield;
MockBlastPoints private mockBlastPoints;
BlastNativeYieldOwnableTwoSteps private blastNativeYieldOwnableTwoSteps;

address public owner = address(69);
address public operator = address(420);
address private constant TREASURY = address(69420);
0xhiroshi marked this conversation as resolved.
Show resolved Hide resolved

function setUp() public {
mockBlastPoints = new MockBlastPoints();
mockBlastYield = new MockBlastYield();
blastNativeYieldOwnableTwoSteps = new BlastNativeYieldOwnableTwoSteps(
address(mockBlastYield),
address(mockBlastPoints),
operator,
owner
);
}

function test_setUpState() public {
(IBlast__YieldMode yieldMode, IBlast__GasMode gasMode, address governor) = mockBlastYield.config(
address(blastNativeYieldOwnableTwoSteps)
);
assertEq(uint8(yieldMode), uint8(IBlast__YieldMode.CLAIMABLE));
assertEq(uint8(gasMode), uint8(IBlast__GasMode.CLAIMABLE));
assertEq(governor, owner);
}
}
33 changes: 33 additions & 0 deletions test/foundry/BlastPoints.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import {OwnableTwoSteps} from "../../contracts/OwnableTwoSteps.sol";
import {BlastPoints} from "../../contracts/BlastPoints.sol";
import {TestHelpers} from "./utils/TestHelpers.sol";

import {MockBlastPoints} from "../mock/MockBlastPoints.sol";

contract BlastPointsOwnableTwoSteps is BlastPoints, OwnableTwoSteps {
0xhiroshi marked this conversation as resolved.
Show resolved Hide resolved
constructor(
address _blastPoints,
address _blastPointsOperator
) BlastPoints(_blastPoints, _blastPointsOperator) OwnableTwoSteps(_blastPointsOperator) {}
}

contract BlastPointsOwnableTwoSteps_Test is TestHelpers {
0xhiroshi marked this conversation as resolved.
Show resolved Hide resolved
MockBlastPoints private mockBlastPoints;
BlastPointsOwnableTwoSteps private blastPointsOwnableTwoSteps;

address public operator = address(420);
address private constant TREASURY = address(69420);
0xhiroshi marked this conversation as resolved.
Show resolved Hide resolved

function setUp() public {
mockBlastPoints = new MockBlastPoints();
blastPointsOwnableTwoSteps = new BlastPointsOwnableTwoSteps(address(mockBlastPoints), operator);
}

function test_setUpState() public {
assertEq(mockBlastPoints.contractOperators(address(blastPointsOwnableTwoSteps)), operator);
}
}
7 changes: 6 additions & 1 deletion test/mock/MockBlastPoints.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@
pragma solidity ^0.8.0;

contract MockBlastPoints {
function configurePointsOperator(address operator) external {}
mapping(address _contract => address operator) public contractOperators;
event LogAddress(address);
0xhiroshi marked this conversation as resolved.
Show resolved Hide resolved

function configurePointsOperator(address operator) external {
contractOperators[msg.sender] = operator;
}
}
Loading