Skip to content

Commit

Permalink
feat: Implement Curve Pool Booster.
Browse files Browse the repository at this point in the history
  • Loading branch information
clement-ux committed Dec 16, 2024
1 parent fa077cd commit 510755d
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 0 deletions.
37 changes: 37 additions & 0 deletions contracts/contracts/interfaces/ICampaignRemoteManager.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ICampaingRemoteManager {
function createCampaign(
CampaignCreationParams memory params,
uint256 destinationChainId,
uint256 additionalGasLimit
) external payable;

function manageCampaign(
CampaignManagementParams memory params,
uint256 destinationChainId,
uint256 additionalGasLimit
) external payable;

struct CampaignCreationParams {
uint256 chainId;
address gauge;
address manager;
address rewardToken;
uint8 numberOfPeriods;
uint256 maxRewardPerVote;
uint256 totalRewardAmount;
address[] addresses;
address hook;
bool isWhitelist;
}

struct CampaignManagementParams {
uint256 campaignId;
address rewardToken;
uint8 numberOfPeriods;
uint256 totalRewardAmount;
uint256 maxRewardPerVote;
}
}
143 changes: 143 additions & 0 deletions contracts/contracts/strategies/CurvePoolBooster.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Governable} from "../governance/Governable.sol";
import {Initializable} from "../utils/Initializable.sol";
import {ICampaingRemoteManager} from "../interfaces/ICampaignRemoteManager.sol";

contract CurvePoolBooster is Initializable, Governable {
address public immutable gauge;
address public immutable rewardToken;
address public immutable campaignRemoteManager;
uint256 public immutable targetChainId;

address public operator;
uint256 public campagnId;

modifier onlyOperator() {

Check warning on line 18 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L18

Added line #L18 was not covered by tests
require(msg.sender == operator || isGovernor(), "Only Operator or Governor");
_;

Check warning on line 20 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L20

Added line #L20 was not covered by tests
}

constructor(

Check warning on line 23 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L23

Added line #L23 was not covered by tests
uint256 _targetChainId,
address _campaignRemoteManager,
address _rewardToken,
address _gauge,
address _operator
) {
targetChainId = _targetChainId;
campaignRemoteManager = _campaignRemoteManager;
rewardToken = _rewardToken;
gauge = _gauge;
operator = _operator;

Check warning on line 34 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L30-L34

Added lines #L30 - L34 were not covered by tests
}

function createCampaign(

Check warning on line 37 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L37

Added line #L37 was not covered by tests
uint8 numberOfPeriods,
uint256 maxRewardPerVote,
uint256 bridgeFee,
uint256 additionalGasLimit
) external onlyOperator {
require(campagnId == 0, "Campaign already created");

// Cache current rewardToken balance
uint256 totalRewardAmount = IERC20(rewardToken).balanceOf(address(this));

Check warning on line 46 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L46

Added line #L46 was not covered by tests

// Approve the total reward amount to the campaign manager
IERC20(rewardToken).approve(campaignRemoteManager, totalRewardAmount);

Check warning on line 49 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L49

Added line #L49 was not covered by tests

// Create a new campaign
ICampaingRemoteManager(campaignRemoteManager).createCampaign{value: bridgeFee}(

Check warning on line 52 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L52

Added line #L52 was not covered by tests
ICampaingRemoteManager.CampaignCreationParams({
chainId: targetChainId,
gauge: gauge,
manager: address(this),
rewardToken: rewardToken,
numberOfPeriods: numberOfPeriods,
maxRewardPerVote: maxRewardPerVote,
totalRewardAmount: totalRewardAmount,
addresses: new address[](0),
hook: address(0),
isWhitelist: false
}),
targetChainId,
additionalGasLimit
);
}

function manageTotalRewardAmount(uint256 bridgeFee, uint256 additionalGasLimit) external onlyOperator {
require(campagnId != 0, "Campaign not created");

// Cache current rewardToken balance
uint256 extraTotalRewardAmount = IERC20(rewardToken).balanceOf(address(this));

Check warning on line 74 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L74

Added line #L74 was not covered by tests

// Approve the total reward amount to the campaign manager
require(extraTotalRewardAmount > 0, "No reward to manage");

// Approve the total reward amount to the campaign manager
IERC20(rewardToken).approve(campaignRemoteManager, extraTotalRewardAmount);

Check warning on line 80 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L80

Added line #L80 was not covered by tests

// Manage the campaign
ICampaingRemoteManager(campaignRemoteManager).manageCampaign{value: bridgeFee}(

Check warning on line 83 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L83

Added line #L83 was not covered by tests
ICampaingRemoteManager.CampaignManagementParams({
campaignId: campagnId,
rewardToken: rewardToken,
numberOfPeriods: 0,
totalRewardAmount: extraTotalRewardAmount,
maxRewardPerVote: 0
}),
targetChainId,
additionalGasLimit
);
}

function manageNumberOfPeriods(uint8 extraNumberOfPeriods, uint256 bridgeFee, uint256 additionalGasLimit)

Check warning on line 96 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L96

Added line #L96 was not covered by tests
external
onlyOperator
{
require(campagnId != 0, "Campaign not created");

ICampaingRemoteManager(campaignRemoteManager).manageCampaign{value: bridgeFee}(

Check warning on line 102 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L102

Added line #L102 was not covered by tests
ICampaingRemoteManager.CampaignManagementParams({
campaignId: campagnId,
rewardToken: rewardToken,
numberOfPeriods: extraNumberOfPeriods,
totalRewardAmount: 0,
maxRewardPerVote: 0
}),
targetChainId,
additionalGasLimit
);
}

function manageRewardPerVote(uint256 newMaxRewardPerVote, uint256 bridgeFee, uint256 additionalGasLimit)

Check warning on line 115 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L115

Added line #L115 was not covered by tests
external
onlyOperator
{
require(campagnId != 0, "Campaign not created");

ICampaingRemoteManager(campaignRemoteManager).manageCampaign{value: bridgeFee}(

Check warning on line 121 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L121

Added line #L121 was not covered by tests
ICampaingRemoteManager.CampaignManagementParams({
campaignId: campagnId,
rewardToken: rewardToken,
numberOfPeriods: 0,
totalRewardAmount: 0,
maxRewardPerVote: newMaxRewardPerVote
}),
targetChainId,
additionalGasLimit
);
}

function setCampaignId(uint256 _campaignId) external onlyOperator {
campagnId = _campaignId;

Check warning on line 135 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L135

Added line #L135 was not covered by tests
}

function setOperator(address _newOperator) external onlyGovernor {
operator = _newOperator;

Check warning on line 139 in contracts/contracts/strategies/CurvePoolBooster.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/strategies/CurvePoolBooster.sol#L139

Added line #L139 was not covered by tests
}

receive() external payable {}
}

0 comments on commit 510755d

Please sign in to comment.