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

daoFeeShare functionality per KIP-33 #34

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
5 changes: 5 additions & 0 deletions contracts/infinity/C.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ library C {
address private constant STAKING = 0x25d28a24Ceb6F81015bB0b2007D795ACAc411b4d;
address private constant STAKING_HELPER = 0x4D70a031Fc76DA6a9bC0C922101A05FA95c3A227;
address private constant TREASURY = 0x7Dd4f0B986F032A44F913BF92c9e8b7c17D77aD7;
address private constant DAO = 0x65A5076C0BA74e5f3e069995dc3DAB9D197d995c;

// Standard Swap ERC20s
address private constant USDC = 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174;
Expand Down Expand Up @@ -65,6 +66,10 @@ library C {
return TREASURY;
}

function dao() internal pure returns (address) {
return DAO;
}

function klima() internal pure returns (address) {
return KLIMA;
}
Expand Down
1 change: 1 addition & 0 deletions contracts/infinity/diamond/AppStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ struct AppStorage {
mapping(address => Account.State) a; // Mapping of a user address to account state.
uint256 lastERC721Received; // Last ERC721 Toucan Retirement Certificate received.
uint256 fee; // Aggregator fee charged on all retirements to 3 decimals. 1000 = 1%
uint256 daoFeeShare; // Share of 'fee' for the DAO wallet, per KIP-33. 3 decimals. 1000 = 1%
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a feeDivisor field and remove the magic numbers from the libraries?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, definitely, I was thinking that as well as I was typing it in. I'll add it.

uint256 reentrantStatus; // An intra-transaction state variable to protect against reentrance.
// Internal Balances
mapping(address => mapping(IERC20 => uint256)) internalTokenBalance; // A mapping from Klimate address to Token address to Internal Balance. It stores the amount of the Token that the Klimate has stored as an Internal Balance in Klima Infinity.
Expand Down
22 changes: 18 additions & 4 deletions contracts/infinity/diamond/facets/Retire/RetireCarbonFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,16 @@ contract RetireCarbonFacet is ReentrancyGuard {
retirementMessage
);

// Send any aggregator fees to treasury
uint256 daoFee;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can break this out into its own function with LibRetire, perhaps LibRetire.sendFee(uint256 totalFee)

uint256 treasuryFee;

// Send any aggregator fees to treasury and the DAO wallet
if (totalCarbon - retireAmount > 0)
LibTransfer.sendToken(IERC20(poolToken), totalCarbon - retireAmount, C.treasury(), LibTransfer.To.EXTERNAL);

daoFee = LibRetire.getFeeShareDAO(totalCarbon - retireAmount);
treasuryFee = totalCarbon - retireAmount - daoFee;
LibTransfer.sendToken(IERC20(poolToken), daoFee, C.dao(), LibTransfer.To.EXTERNAL);
LibTransfer.sendToken(IERC20(poolToken), treasuryFee, C.treasury(), LibTransfer.To.EXTERNAL);

return LibRetire.getTotalRetirements(beneficiaryAddress);
}
Expand Down Expand Up @@ -138,9 +145,16 @@ contract RetireCarbonFacet is ReentrancyGuard {
retirementMessage
);

// Send any aggregator fees to treasury
uint256 daoFee;
uint256 treasuryFee;

// Send any aggregator fees to treasury and the DAO wallet
if (totalCarbon - redeemedPool > 0)
LibTransfer.sendToken(IERC20(poolToken), totalCarbon - redeemedPool, C.treasury(), LibTransfer.To.EXTERNAL);

daoFee = LibRetire.getFeeShareDAO(totalCarbon - redeemedPool);
treasuryFee = totalCarbon - redeemedPool - daoFee;
LibTransfer.sendToken(IERC20(poolToken), daoFee, C.dao(), LibTransfer.To.EXTERNAL);
LibTransfer.sendToken(IERC20(poolToken), treasuryFee, C.treasury(), LibTransfer.To.EXTERNAL);

return LibRetire.getTotalRetirements(beneficiaryAddress);
}
Expand Down
27 changes: 18 additions & 9 deletions contracts/infinity/diamond/facets/Retire/RetireSourceFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,16 @@ contract RetireSourceFacet is ReentrancyGuard {
retirementMessage
);

// Send any aggregator fees to treasury
uint256 daoFee;
uint256 treasuryFee;

// Send any aggregator fees to treasury and the DAO wallet
if (totalCarbon - retireAmount > 0)
LibTransfer.sendToken(IERC20(poolToken), totalCarbon - retireAmount, C.treasury(), LibTransfer.To.EXTERNAL);

daoFee = LibRetire.getFeeShareDAO(totalCarbon - retireAmount);
treasuryFee = totalCarbon - retireAmount - daoFee;
LibTransfer.sendToken(IERC20(poolToken), daoFee, C.dao(), LibTransfer.To.EXTERNAL);
LibTransfer.sendToken(IERC20(poolToken), treasuryFee, C.treasury(), LibTransfer.To.EXTERNAL);

return LibRetire.getTotalRetirements(beneficiaryAddress);
}
Expand Down Expand Up @@ -128,14 +135,16 @@ contract RetireSourceFacet is ReentrancyGuard {
retirementMessage
);

// Send any aggregator fees to treasury
uint256 daoFee;
uint256 treasuryFee;

// Send any aggregator fees to treasury and the DAO wallet
if (totalCarbon - redeemedAmount > 0)
LibTransfer.sendToken(
IERC20(poolToken),
totalCarbon - redeemedAmount,
C.treasury(),
LibTransfer.To.EXTERNAL
);

daoFee = LibRetire.getFeeShareDAO(totalCarbon - redeemedAmount);
treasuryFee = totalCarbon - redeemedAmount - daoFee;
LibTransfer.sendToken(IERC20(poolToken), daoFee, C.dao(), LibTransfer.To.EXTERNAL);
LibTransfer.sendToken(IERC20(poolToken), treasuryFee, C.treasury(), LibTransfer.To.EXTERNAL);

return LibRetire.getTotalRetirements(beneficiaryAddress);
}
Expand Down
1 change: 1 addition & 0 deletions contracts/infinity/diamond/init/DiamondInit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ contract DiamondInit {

// Retirement convenience fee
s.fee = 1000;
s.daoFeeShare = 80000;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should spin up a new init contract with only the changes and args needed for this diamond cut


// Default BCT Swap setup
s.swap[C.bct()][C.usdc()].swapDexes = [0];
Expand Down
10 changes: 10 additions & 0 deletions contracts/infinity/libraries/LibRetire.sol
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,16 @@ library LibRetire {
fee = (carbonAmount * s.fee) / 100000;
}

/**
* @notice Returns the total fee needed to retire x number of tokens
* @param feeAmount Amount of aggregator fee
* @return feeShare Total DAO fee share
*/
function getFeeShareDAO(uint256 feeAmount) internal view returns (uint256 feeShare) {
AppStorage storage s = LibAppStorage.diamondStorage();
feeShare = (feeAmount * s.daoFeeShare) / 100000;
}

/**
* @notice Saves the details of the retirement over to KlimaCarbonRetirements and project details within AppStorage
* @param poolToken Pool token used to retire
Expand Down