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

resolves issue 5.2 #185

Merged
merged 1 commit into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
29 changes: 17 additions & 12 deletions src/RevenueHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ contract RevenueHandler is IRevenueHandler, Ownable {

address public immutable veALCX;
address[] public revenueTokens;
mapping(address => bool) public alchemicTokens; // token => is alchemic-token (true/false)
mapping(address => address) public alchemists; // alchemist => alchemic-token
mapping(address => RevenueTokenConfig) public revenueTokenConfigs; // token => RevenueTokenConfig
mapping(uint256 => mapping(address => uint256)) public epochRevenues; // epoch => (debtToken => epoch revenue)
mapping(uint256 => mapping(address => Claimable)) public userCheckpoints; // tokenId => (debtToken => Claimable)
Expand Down Expand Up @@ -108,19 +108,25 @@ contract RevenueHandler is IRevenueHandler, Ownable {
}

/// @inheritdoc IRevenueHandler
function addAlchemicToken(address alchemicToken) external override onlyOwner {
require(!alchemicTokens[alchemicToken], "alchemic token already exists");
alchemicTokens[alchemicToken] = true;
function addAlchemicToken(address alchemist) external override onlyOwner {
require(alchemists[alchemist] == address(0), "alchemic token already exists");

emit AlchemicTokenAdded(alchemicToken);
address alchemicToken = IAlchemistV2(alchemist).debtToken();

alchemists[alchemist] = alchemicToken;

emit AlchemicTokenAdded(alchemist, alchemicToken);
}

/// @inheritdoc IRevenueHandler
function removeAlchemicToken(address alchemicToken) external override onlyOwner {
require(alchemicTokens[alchemicToken], "alchemic token does not exist");
alchemicTokens[alchemicToken] = false;
function removeAlchemicToken(address alchemist) external override onlyOwner {
address alchemicToken = alchemists[alchemist];

require(alchemicToken != address(0), "alchemic token does not exist");

emit AlchemicTokenRemoved(alchemicToken);
alchemists[alchemist] = address(0);

emit AlchemicTokenRemoved(alchemist, alchemicToken);
}

/// @inheritdoc IRevenueHandler
Expand Down Expand Up @@ -186,9 +192,8 @@ contract RevenueHandler is IRevenueHandler, Ownable {
userCheckpoints[tokenId][token].lastClaimEpoch = currentEpoch;
userCheckpoints[tokenId][token].unclaimed = amountClaimable - amount;

if (alchemicTokens[token]) {
require(alchemist != address(0), "if token is alchemic-token, alchemist must be set");

// If the alchemist is defined we know it has an alchemic-token
if (alchemists[alchemist] != address(0)) {
(, address[] memory deposits) = IAlchemistV2(alchemist).accounts(recipient);
IERC20(token).approve(alchemist, amount);

Expand Down
18 changes: 11 additions & 7 deletions src/interfaces/IRevenueHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,18 @@ interface IRevenueHandler {
/**
* @notice Emitted when alchemic-token is added.
*
* @param alchemicToken The alchemic-token to add
* @param alchemist The address of the alchemist to add.
* @param alchemicToken The alchemic-token to add.
*/
event AlchemicTokenAdded(address alchemicToken);
event AlchemicTokenAdded(address alchemist, address alchemicToken);

/**
* @notice Emitted when alchemic-token is removed.
*
* @param alchemist The address of the alchemist to add.
* @param alchemicToken The alchemic-token to remove.
*/
event AlchemicTokenRemoved(address alchemicToken);
event AlchemicTokenRemoved(address alchemist, address alchemicToken);

/**
* @notice Emitted when poolAdapter parameters are set for a revenue token.
Expand Down Expand Up @@ -134,17 +136,19 @@ interface IRevenueHandler {
* @notice Add an alchemic-token to the list of recognized alchemic-tokens.
* @notice This function is only callable by the contract owner.
*
* @param alchemicToken The address of the alchemic-token to add.
* @param alchemist The address of the alchemist to add.
* @dev the alchemic-token will be derived from the alchemist.
*/
function addAlchemicToken(address alchemicToken) external;
function addAlchemicToken(address alchemist) external;

/**
* @notice Remove an alchemic-token from the list of recognized alchemic-tokens.
* @notice This function is only callable by the contract owner.
*
* @param alchemicToken The address of the alchemic-token to remove.
* @param alchemist The address of the alchemist to remove.
* @dev the alchemic-token will be derived from the alchemist.
*/
function removeAlchemicToken(address alchemicToken) external;
function removeAlchemicToken(address alchemist) external;

/**
* @dev Add an ERC20 token to the list of recognized revenue tokens.
Expand Down
27 changes: 14 additions & 13 deletions src/test/RevenueHandler.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ contract RevenueHandlerTest is BaseTest {
uint256 DELTA = 65;

IAlchemistV2 public alusdAlchemist = IAlchemistV2(0x5C6374a2ac4EBC38DeA0Fc1F8716e5Ea1AdD94dd);
IAlchemistV2 public alethAlchemist = IAlchemistV2(0x062Bf725dC4cDF947aa79Ca2aaCCD4F385b13b5c);
IWhitelist public whitelist = IWhitelist(0x78537a6CeBa16f412E123a90472C6E0e9A8F1132);

// RevenueHandler revenueHandler;
Expand Down Expand Up @@ -42,7 +43,7 @@ contract RevenueHandlerTest is BaseTest {
revenueHandler.setPoolAdapter(usdc, address(cpa));

revenueHandler.addRevenueToken(bal);
revenueHandler.addAlchemicToken(alusd);
revenueHandler.addAlchemicToken(address(alusdAlchemist));

hevm.prank(devmsig);
whitelist.disable();
Expand Down Expand Up @@ -145,29 +146,29 @@ contract RevenueHandlerTest is BaseTest {
}

function testAddAlchemicToken() external {
revenueHandler.addAlchemicToken(aleth);
bool isAlchemicToken = revenueHandler.alchemicTokens(aleth);
assertEq(isAlchemicToken, true);
revenueHandler.addAlchemicToken(address(alethAlchemist));
address alchemicToken = revenueHandler.alchemists(address(alethAlchemist));
assertEq(alchemicToken, aleth);
}

function testAddAlchemicTokenFail() external {
revenueHandler.addAlchemicToken(aleth);
revenueHandler.addAlchemicToken(address(alethAlchemist));
expectError("alchemic token already exists");
revenueHandler.addAlchemicToken(aleth);
revenueHandler.addAlchemicToken(address(alethAlchemist));
}

function testRemoveAlchemicToken() external {
revenueHandler.addAlchemicToken(aleth);
revenueHandler.removeAlchemicToken(aleth);
bool isAlchemicToken = revenueHandler.alchemicTokens(aleth);
assertEq(isAlchemicToken, false);
revenueHandler.addAlchemicToken(address(alethAlchemist));
revenueHandler.removeAlchemicToken(address(alethAlchemist));
address alchemicToken = revenueHandler.alchemists(address(alethAlchemist));
assertEq(alchemicToken, address(0));
}

function testRemoveAlchemicTokenFail() external {
revenueHandler.addAlchemicToken(aleth);
revenueHandler.removeAlchemicToken(aleth);
revenueHandler.addAlchemicToken(address(alethAlchemist));
revenueHandler.removeAlchemicToken(address(alethAlchemist));
expectError("alchemic token does not exist");
revenueHandler.removeAlchemicToken(aleth);
revenueHandler.removeAlchemicToken(address(alethAlchemist));
}

function testSetDebtToken() external {
Expand Down
Loading