Skip to content

Commit

Permalink
feat(incentives): no reuse of incentive clones
Browse files Browse the repository at this point in the history
  • Loading branch information
ccashwell committed Mar 15, 2024
1 parent 810f612 commit b496520
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 26 deletions.
7 changes: 7 additions & 0 deletions src/BoostCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,13 @@ contract BoostCore is Ownable, ReentrancyGuard {
incentives = new Incentive[](targets_.length);
for (uint256 i = 0; i < targets_.length; i++) {
// Deploy the clone, but don't initialize until it we've preflighted
_checkTarget(type(Incentive).interfaceId, targets_[i].instance);

// Ensure the target is a base implementation (incentive clones are not reusable)
if (!targets_[i].isBase) {
revert BoostError.InvalidInstance(type(Incentive).interfaceId, targets_[i].instance);
}

incentives[i] = Incentive(_makeTarget(type(Incentive).interfaceId, targets_[i], false));

bytes memory preflight = incentives[i].preflight(targets_[i].parameters);
Expand Down
2 changes: 1 addition & 1 deletion src/actions/ContractAction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ contract ContractAction is Action {
return (success, returnData);
}

function prepare(bytes calldata data_) public virtual view override returns (bytes memory bytes_) {
function prepare(bytes calldata data_) public view virtual override returns (bytes memory bytes_) {
return _buildPayload(selector, data_);
}

Expand Down
6 changes: 5 additions & 1 deletion test/BoostCore.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,11 @@ contract BoostCoreTest is Test {
return BoostLib.Target({
isBase: true,
instance: address(new ERC721MintAction()),
parameters: LibZip.cdCompress(abi.encode(ContractAction.InitPayload({chainId: block.chainid, target: target, selector: selector, value: value})))
parameters: LibZip.cdCompress(
abi.encode(
ContractAction.InitPayload({chainId: block.chainid, target: target, selector: selector, value: value})
)
)
});
}

Expand Down
7 changes: 5 additions & 2 deletions test/actions/ContractAction.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ contract ContractActionTest is Test {
////////////////////////////

function testPrepare() public {
assertEq(action.prepare(abi.encode(address(0xdeadbeef), 100 ether)), abi.encodeWithSelector(target.mintPayable.selector, address(0xdeadbeef), 100 ether));
assertEq(
action.prepare(abi.encode(address(0xdeadbeef), 100 ether)),
abi.encodeWithSelector(target.mintPayable.selector, address(0xdeadbeef), 100 ether)
);
}
}
}
45 changes: 29 additions & 16 deletions test/budgets/VestingBudget.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ contract VestingBudgetTest is Test {
vestingBudget = VestingBudget(payable(LibClone.clone(address(new VestingBudget()))));
vestingBudget.initialize(
LibZip.cdCompress(
abi.encode(VestingBudget.InitPayload({
owner: address(this),
authorized: new address[](0),
start: uint64(block.timestamp),
duration: uint64(1 days),
cliff: 0
}))
abi.encode(
VestingBudget.InitPayload({
owner: address(this),
authorized: new address[](0),
start: uint64(block.timestamp),
duration: uint64(1 days),
cliff: 0
})
)
)
);
}
Expand Down Expand Up @@ -87,7 +89,15 @@ contract VestingBudgetTest is Test {
function testInitialize() public {
// Initializer can only be called on clones, not the base contract
bytes memory data = LibZip.cdCompress(
abi.encode(VestingBudget.InitPayload({owner: address(this), authorized: new address[](0), start: 0, duration: 0, cliff: 0}))
abi.encode(
VestingBudget.InitPayload({
owner: address(this),
authorized: new address[](0),
start: 0,
duration: 0,
cliff: 0
})
)
);
VestingBudget clone = VestingBudget(payable(LibClone.clone(address(vestingBudget))));
clone.initialize(data);
Expand Down Expand Up @@ -208,9 +218,11 @@ contract VestingBudgetTest is Test {
_vestAll();

// Reclaim 99 tokens from the budget
assertTrue(vestingBudget.reclaim(
_makeFungibleTransfer(Budget.AssetType.ERC20, address(mockERC20), address(this), 99 ether)
));
assertTrue(
vestingBudget.reclaim(
_makeFungibleTransfer(Budget.AssetType.ERC20, address(mockERC20), address(this), 99 ether)
)
);

// Ensure the budget total is still 100
assertEq(vestingBudget.total(address(mockERC20)), 100 ether);
Expand Down Expand Up @@ -438,7 +450,8 @@ contract VestingBudgetTest is Test {
_vestAll();

// Try to disburse 100 tokens from the budget as a non-owner
bytes memory data = _makeFungibleTransfer(Budget.AssetType.ERC20, address(mockERC20), address(0xdeadbeef), 100 ether);
bytes memory data =
_makeFungibleTransfer(Budget.AssetType.ERC20, address(mockERC20), address(0xdeadbeef), 100 ether);
vm.prank(address(0xc0ffee));
vm.expectRevert();
vestingBudget.disburse(data);
Expand Down Expand Up @@ -571,9 +584,7 @@ contract VestingBudgetTest is Test {
assertEq(vestingBudget.available(address(0)), 100 ether);

// Disburse 25 ETH from the budget and ensure the budget has 75 ETH available
vestingBudget.disburse(
_makeFungibleTransfer(Budget.AssetType.ETH, address(0), address(0xdeadbeef), 25 ether)
);
vestingBudget.disburse(_makeFungibleTransfer(Budget.AssetType.ETH, address(0), address(0xdeadbeef), 25 ether));
assertEq(vestingBudget.available(address(0)), 75 ether);
}

Expand Down Expand Up @@ -752,7 +763,9 @@ contract VestingBudgetTest is Test {

function _allocate(address asset, uint256 value) internal returns (bool) {
if (asset == address(0)) {
return vestingBudget.allocate{value: value}(_makeFungibleTransfer(Budget.AssetType.ETH, asset, address(this), value));
return vestingBudget.allocate{value: value}(
_makeFungibleTransfer(Budget.AssetType.ETH, asset, address(this), value)
);
} else {
mockERC20.approve(address(vestingBudget), value);
return vestingBudget.allocate(_makeFungibleTransfer(Budget.AssetType.ERC20, asset, address(this), value));
Expand Down
16 changes: 10 additions & 6 deletions test/e2e/EndToEnd.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -285,12 +285,16 @@ contract EndToEnd is Test {
registry.getIdentifier(BoostRegistry.RegistryType.ACTION, "ERC721MintAction")
)
),
parameters: LibZip.cdCompress(abi.encode(ContractAction.InitPayload({
chainId: block.chainid,
target: address(erc721),
selector: MockERC721.mint.selector,
value: erc721.mintPrice()
})))
parameters: LibZip.cdCompress(
abi.encode(
ContractAction.InitPayload({
chainId: block.chainid,
target: address(erc721),
selector: MockERC721.mint.selector,
value: erc721.mintPrice()
})
)
)
}),
BoostLib.Target({
// "... and I don't have to specify a validator"
Expand Down

0 comments on commit b496520

Please sign in to comment.