diff --git a/src/RevenueHandler.sol b/src/RevenueHandler.sol index a891d71..2448ab0 100644 --- a/src/RevenueHandler.sol +++ b/src/RevenueHandler.sol @@ -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) @@ -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 @@ -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); diff --git a/src/interfaces/IRevenueHandler.sol b/src/interfaces/IRevenueHandler.sol index de7cd93..18d0e9b 100644 --- a/src/interfaces/IRevenueHandler.sol +++ b/src/interfaces/IRevenueHandler.sol @@ -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. @@ -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. diff --git a/src/test/RevenueHandler.t.sol b/src/test/RevenueHandler.t.sol index fb3b278..f3251ac 100644 --- a/src/test/RevenueHandler.t.sol +++ b/src/test/RevenueHandler.t.sol @@ -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; @@ -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(); @@ -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 {