-
Notifications
You must be signed in to change notification settings - Fork 39
Integrate CMARK credit retirements into RA #74
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
Merged
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
bf3a289
Initial pass at integrating CMARK credit retirements into RA
0xAurelius ceb76c1
Fix compilation issues
0xAurelius 9768f08
Add proper handling for retirement details
0xAurelius 6de5472
Remove improper usage pattern
0xAurelius 4af8f70
Fix compilation issues and test harness
0xAurelius c39ff46
Incorporate minor feedback
0xAurelius 4541d9d
Minor feedback adjustment
0xAurelius 95e1f0d
Add upgrade logic and test
0xAurelius 89358d4
RA testing progress
0xAurelius c5f216c
More testing fixes
0xAurelius d844141
Get tests to compile
0xAurelius fcd94f6
Finally get test working
0xAurelius 738bacc
Add upgrade test script
0xAurelius 7fdb04d
Add additional test for other facet
0xAurelius df72b23
Add call data and invocation script
0xAurelius File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| import SafeApiKit from "@safe-global/api-kit"; | ||
| import Safe from "@safe-global/protocol-kit"; | ||
| import { | ||
| MetaTransactionData, | ||
| OperationType, | ||
| } from "@safe-global/safe-core-sdk-types"; | ||
|
|
||
| const RPC_URL = process.env.POLYGON_URL; | ||
| const SAFE_ADDRESS = process.env.CONTRACT_MULTISIG; | ||
| const OWNER_1_PRIVATE_KEY = process.env.PRIVATE_KEY; | ||
| const OWNER_1_ADDRESS = process.env.PUBLIC_KEY; | ||
| const RETIREMENT_AGGREGATOR = process.env.RETIREMENT_AGGREGATOR; | ||
|
|
||
| // Sepolia for testing | ||
| const apiKit = new SafeApiKit({ | ||
| chainId: 137n, | ||
| }); | ||
|
|
||
| if ( | ||
| !RPC_URL || | ||
| !OWNER_1_PRIVATE_KEY || | ||
| !OWNER_1_ADDRESS || | ||
| !SAFE_ADDRESS || | ||
| !RETIREMENT_AGGREGATOR | ||
| ) { | ||
| throw new Error("Missing environment variables"); | ||
| } | ||
|
|
||
| const protocolKitOwner1 = await Safe.init({ | ||
| provider: RPC_URL, | ||
| signer: OWNER_1_PRIVATE_KEY, | ||
| safeAddress: SAFE_ADDRESS, | ||
| }); | ||
|
|
||
| // Create transaction | ||
| const safeTransactionData: MetaTransactionData = { | ||
| to: RETIREMENT_AGGREGATOR, | ||
| value: "0", | ||
| data: "0x1f931c1c0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000085f50d58d89d83a8a390379b4b07f060f85faeb100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000174deb0be000000000000000000000000000000000000000000000000000000000000000000000000000000007778bd8a404ffb91b2433552a9d02895d9eb1b46000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001dc3ca95c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", // txn call data generated by running upgrade script | ||
| operation: OperationType.Call, | ||
| }; | ||
|
|
||
| const nextNonce = await apiKit.getNextNonce(SAFE_ADDRESS); | ||
|
|
||
| const safeTransaction = await protocolKitOwner1.createTransaction({ | ||
| transactions: [safeTransactionData], | ||
| options: { | ||
| nonce: nextNonce, | ||
| }, | ||
| }); | ||
|
|
||
| const safeTxHash = await protocolKitOwner1.getTransactionHash(safeTransaction); | ||
| const signature = await protocolKitOwner1.signHash(safeTxHash); | ||
|
|
||
| // Propose transaction to the service | ||
| await apiKit.proposeTransaction({ | ||
| safeAddress: SAFE_ADDRESS, | ||
| safeTransactionData: safeTransaction.data, | ||
| safeTxHash, | ||
| senderAddress: OWNER_1_ADDRESS, | ||
| senderSignature: signature.data, | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| pragma solidity ^0.8.0; | ||
|
|
||
| import "forge-std/Script.sol"; | ||
| import {console2} from "forge-std/console2.sol"; | ||
|
|
||
| import "../src/infinity/interfaces/IDiamondCut.sol"; | ||
| import {Diamond} from "../src/infinity/Diamond.sol"; | ||
| import "../src/infinity/facets/DiamondCutFacet.sol"; | ||
| import "../src/infinity/facets/DiamondLoupeFacet.sol"; | ||
| import "../src/infinity/facets/OwnershipFacet.sol"; | ||
| import { RetireCarbonmarkFacet } from "../src/infinity/facets/Retire/RetireCarbonmarkFacet.sol"; | ||
| import { RetireCMARKFacet } from "../src/infinity/facets/Bridges/CMARK/RetireCMARKFacet.sol"; | ||
|
|
||
| import "../test/infinity/HelperContract.sol"; | ||
|
|
||
| contract UpgradeInfinityForCMARK is Script, HelperContract { | ||
| function run() external returns (bytes memory) { | ||
| //read env variables and choose EOA for transaction signing | ||
| uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); | ||
| address diamond = vm.envAddress("INFINITY_ADDRESS"); | ||
| bytes memory updateFacetsCalldata; | ||
|
|
||
| OwnershipFacet ownerF = OwnershipFacet(diamond); | ||
|
|
||
| vm.startBroadcast(deployerPrivateKey); | ||
|
|
||
| //deploy updated facets and init contract | ||
| RetireCarbonmarkFacet retireCarbonmarkF = new RetireCarbonmarkFacet(); | ||
| RetireCMARKFacet retireCMARKF = new RetireCMARKFacet(); | ||
|
|
||
| // FacetCut array which contains the three standard facets to be added | ||
| IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](2); | ||
|
|
||
| // Klima Infinity specific facets | ||
| cut[0] = ( | ||
| IDiamondCut.FacetCut({ | ||
| facetAddress: address(retireCarbonmarkF), | ||
| action: IDiamondCut.FacetCutAction.Replace, | ||
| functionSelectors: generateSelectors("RetireCarbonmarkFacet") | ||
| }) | ||
| ); | ||
|
|
||
| cut[1] = ( | ||
| IDiamondCut.FacetCut({ | ||
| facetAddress: address(retireCMARKF), | ||
| action: IDiamondCut.FacetCutAction.Add, | ||
| functionSelectors: generateSelectors("RetireCMARKFacet") | ||
| }) | ||
| ); | ||
|
|
||
| vm.stopBroadcast(); | ||
|
|
||
| // get calldata for the upgrade without init for interal library function view | ||
| updateFacetsCalldata = abi.encodeWithSelector( | ||
| IDiamondCut.diamondCut.selector, | ||
| cut, | ||
| address(0), | ||
| "" | ||
| ); | ||
|
|
||
| console2.log("New retireCarbonmarkF address"); | ||
| console2.logAddress(address(retireCarbonmarkF)); | ||
|
|
||
| console2.log("New retireCMARKF address"); | ||
| console2.logAddress(address(retireCMARKF)); | ||
|
|
||
| console2.log("Updated Retire Carbonmark Facet Calldata"); | ||
| console2.logBytes(updateFacetsCalldata); | ||
|
|
||
| return updateFacetsCalldata; | ||
|
|
||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| pragma solidity ^0.8.16; | ||
|
|
||
| import "../../../libraries/Bridges/LibCMARKCarbon.sol"; | ||
| import "../../../libraries/LibRetire.sol"; | ||
| import "../../../libraries/TokenSwap/LibSwap.sol"; | ||
| import "../../../ReentrancyGuard.sol"; | ||
|
|
||
| contract RetireCMARKFacet is ReentrancyGuard { | ||
| event CarbonRetired( | ||
| LibRetire.CarbonBridge carbonBridge, | ||
| address indexed retiringAddress, | ||
| string retiringEntityString, | ||
| address indexed beneficiaryAddress, | ||
| string beneficiaryString, | ||
| string retirementMessage, | ||
| address indexed carbonPool, | ||
| address carbonToken, | ||
| uint retiredAmount | ||
| ); | ||
|
|
||
| /** | ||
| * @notice This contract assumes that the token being provided is a raw CMARK credit token. | ||
| * @notice The transactions will revert otherwise. | ||
| */ | ||
|
|
||
| /** | ||
| * @notice Retires CMARK credits directly | ||
| * @param carbonToken Pool token to redeem | ||
| * @param amount Amounts of underlying tokens to redeem | ||
| * @param details Encoded struct of retirement details needed for the retirement | ||
| * @param fromMode From Mode for transfering tokens | ||
| * @return retirementIndex The latest retirement index for the beneficiary address | ||
| */ | ||
| function cmarkRetireExactCarbon( | ||
| address carbonToken, | ||
| uint amount, | ||
| LibRetire.RetireDetails memory details, | ||
| LibTransfer.From fromMode | ||
| ) external nonReentrant returns (uint retirementIndex) { | ||
| // Currently this is a simple wrapper for direct calls on specific CMARK tokens | ||
| // No fee is charged | ||
|
|
||
| LibTransfer.receiveToken(IERC20(carbonToken), amount, msg.sender, fromMode); | ||
|
|
||
| if (details.retiringAddress == address(0)) details.retiringAddress = msg.sender; | ||
|
|
||
| bytes memory tempEmptyStringTest = bytes(details.retiringEntityString); | ||
| if (tempEmptyStringTest.length == 0) { | ||
| details.retiringEntityString = "KlimaDAO Retirement Aggregator"; | ||
| } | ||
|
|
||
| // Retire the carbon | ||
| LibCMARKCarbon.retireCMARK( | ||
| carbonToken, | ||
| amount, | ||
| details | ||
| ); | ||
|
|
||
| return LibRetire.getTotalRetirements(details.beneficiaryAddress); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| interface ICMARKCreditToken { | ||
| function retire(uint256 amount, address beneficiary, string calldata beneficiaryName, string calldata message, string calldata consumptionCountryCode) external; | ||
| function retireFrom(uint256 amount, address beneficiary, string calldata beneficiaryName, string calldata message, string calldata consumptionCountryCode, address account) external; | ||
| } | ||
|
|
||
| interface ICMARKCreditTokenFactory { | ||
| function creditAddressToId(address) external view returns (string memory); | ||
| function creditIdToAddress(string calldata) external view returns (address); | ||
| function issueCredits(string calldata, uint256, address) external; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| pragma solidity ^0.8.16; | ||
|
|
||
| import "../LibRetire.sol"; | ||
| import "../Token/LibTransfer.sol"; | ||
| import "../../interfaces/ICMARKCredit.sol"; | ||
| import "../../C.sol"; | ||
|
|
||
| import "lib/forge-std/src/console.sol"; | ||
|
|
||
| /** | ||
| * @author MarcusAurelius | ||
| * @title LibCMARKCarbon | ||
| */ | ||
|
|
||
| library LibCMARKCarbon { | ||
| event CarbonRetired( | ||
|
0xAurelius marked this conversation as resolved.
|
||
| LibRetire.CarbonBridge carbonBridge, | ||
| address indexed retiringAddress, | ||
| string retiringEntityString, | ||
| address indexed beneficiaryAddress, | ||
| string beneficiaryString, | ||
| string retirementMessage, | ||
| address indexed carbonPool, | ||
| address carbonToken, | ||
| uint retiredAmount | ||
| ); | ||
|
|
||
| /** | ||
| * @notice Retire a CMARK project token | ||
|
0xAurelius marked this conversation as resolved.
|
||
| * @param projectToken Project token being retired | ||
| * @param amount Amount of tokens to retire | ||
| * @param details Encoded struct of retirement details needed for the retirement | ||
| */ | ||
| function retireCMARK( | ||
| address projectToken, | ||
| uint amount, | ||
| LibRetire.RetireDetails memory details | ||
| ) internal { | ||
| ICMARKCreditToken(projectToken).retire( | ||
| amount, | ||
| details.beneficiaryAddress, | ||
| details.beneficiaryString, | ||
| details.retirementMessage, | ||
| details.consumptionCountryCode | ||
| ); | ||
|
|
||
| LibRetire.saveRetirementDetails( | ||
| address(0), | ||
| projectToken, | ||
| amount, | ||
| details.beneficiaryAddress, | ||
| details.beneficiaryString, | ||
| details.retirementMessage | ||
| ); | ||
|
|
||
| emit CarbonRetired( | ||
| LibRetire.CarbonBridge.CMARK, | ||
| details.retiringAddress, | ||
| details.retiringEntityString, | ||
| details.beneficiaryAddress, | ||
| details.beneficiaryString, | ||
| details.retirementMessage, | ||
| address(0), | ||
| projectToken, | ||
| amount | ||
| ); | ||
| } | ||
|
|
||
| function isValid(address token) internal returns (bool) { | ||
| bytes memory tempEmptyStringTest = bytes(ICMARKCreditTokenFactory(C.cmarkCreditFactory()).creditAddressToId(token)); | ||
| return tempEmptyStringTest.length > 0; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious, how does this value actually get incremented? Is it a side effect of
retireCMARK() -> saveRetirementDetails()?