From d78fa15ffe8bd5016e079a24a9ef9a0b731f7121 Mon Sep 17 00:00:00 2001 From: eukadish Date: Tue, 3 Sep 2024 14:00:40 -0400 Subject: [PATCH 1/9] add DAM governance token --- src/governance/DAM.sol | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/governance/DAM.sol diff --git a/src/governance/DAM.sol b/src/governance/DAM.sol new file mode 100644 index 0000000..0d152e0 --- /dev/null +++ b/src/governance/DAM.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.24; + +import {AccessControl} from "openzeppelin-contracts/contracts/access/AccessControl.sol"; + +import {SafeCast} from "openzeppelin-contracts/contracts/utils/math/SafeCast.sol"; +import {ERC20Votes, ERC20, ERC20Permit} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sol"; + +contract DAM is ERC20Votes { + uint256 private constant supply = 1_000_000_000e18; + + constructor() ERC20("DAM", "DAM") { + _mint(msg.sender, supply); + } + + // function clock() public view virtual override returns (uint48) { + // return SafeCast.toUint48(block.timestamp); + // } + + // // solhint-disable-next-line func-name-mixedcase + // function CLOCK_MODE() public view virtual override returns (string memory) { + // return "mode=timestamp"; + // } +} From 1a2c1981dc2293ab0b99641e534f40625916345d Mon Sep 17 00:00:00 2001 From: eukadish Date: Wed, 4 Sep 2024 21:10:54 -0400 Subject: [PATCH 2/9] add governance dependencies --- src/governance/DAM.sol | 11 ++++- src/governance/Governor.sol | 93 +++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 src/governance/Governor.sol diff --git a/src/governance/DAM.sol b/src/governance/DAM.sol index 0d152e0..68c72fa 100644 --- a/src/governance/DAM.sol +++ b/src/governance/DAM.sol @@ -7,13 +7,22 @@ import {AccessControl} from "openzeppelin-contracts/contracts/access/AccessContr import {SafeCast} from "openzeppelin-contracts/contracts/utils/math/SafeCast.sol"; import {ERC20Votes, ERC20, ERC20Permit} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sol"; +import {ERC20} from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; +import {Context} from "openzeppelin-contracts/contracts/utils/Context.sol"; + +// burnable, mintable + contract DAM is ERC20Votes { uint256 private constant supply = 1_000_000_000e18; - constructor() ERC20("DAM", "DAM") { + constructor(/* admin */) ERC20("DAM", "DAM") ERC20Permit("DAM") { _mint(msg.sender, supply); } + // mint - - owner + + // burn - - + // function clock() public view virtual override returns (uint48) { // return SafeCast.toUint48(block.timestamp); // } diff --git a/src/governance/Governor.sol b/src/governance/Governor.sol new file mode 100644 index 0000000..c45a7c8 --- /dev/null +++ b/src/governance/Governor.sol @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import {IERC165} from "openzeppelin-contracts/contracts/interfaces/IERC165.sol"; + +import {IVotes} from "openzeppelin-contracts/contracts/governance/utils/IVotes.sol"; + +import {TimelockController} from "openzeppelin-contracts/contracts/governance/TimelockController.sol"; + +import {IGovernor} from "openzeppelin-contracts/contracts/governance/IGovernor.sol"; + +import {Governor} from "openzeppelin-contracts/contracts/governance/Governor.sol"; +import {GovernorVotes} from "openzeppelin-contracts/contracts/governance/extensions/GovernorVotes.sol"; +import {GovernorTimelockControl} from "openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockControl.sol"; + +contract ReservoirGovernor is GovernorVotes, GovernorTimelockControl { + constructor( + string memory name_, + IVotes token_, + TimelockController timelock_ + ) + GovernorVotes(token_) + GovernorTimelockControl(timelock_) + Governor(name_) + {} + + // function quorum(uint256) public pure override returns (uint256) { + // return 0; + // } + + // function votingDelay() public pure override returns (uint256) { + // return 4; + // } + + // function votingPeriod() public pure override returns (uint256) { + // return 16; + // } + + // function cancel( + // address[] memory targets, + // uint256[] memory values, + // bytes[] memory calldatas, + // bytes32 salt + // ) public returns (uint256 proposalId) { + // return _cancel(targets, values, calldatas, salt); + // } + + function state( + uint256 proposalId + ) + public + view + override(Governor, GovernorTimelockControl) + returns (ProposalState) + { + return super.state(proposalId); + } + + function _execute( + uint256 proposalId, + address[] memory targets, + uint256[] memory values, + bytes[] memory calldatas, + bytes32 descriptionHash + ) internal override(Governor, GovernorTimelockControl) { + super._execute(proposalId, targets, values, calldatas, descriptionHash); + } + + function _cancel( + address[] memory targets, + uint256[] memory values, + bytes[] memory calldatas, + bytes32 descriptionHash + ) internal override(Governor, GovernorTimelockControl) returns (uint256) { + return super._cancel(targets, values, calldatas, descriptionHash); + } + + function _executor() + internal + view + override(Governor, GovernorTimelockControl) + returns (address) + { + return super._executor(); + } + + function supportsInterface( + bytes4 interfaceId + ) public view override(Governor, GovernorTimelockControl) returns (bool) { + return super.supportsInterface(interfaceId); + } +} From 651e382be9590a40e183825b68003e6f03d50bdf Mon Sep 17 00:00:00 2001 From: eukadish Date: Thu, 5 Sep 2024 08:12:29 -0400 Subject: [PATCH 3/9] cleanup dependencies --- src/governance/Governor.sol | 58 +++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/src/governance/Governor.sol b/src/governance/Governor.sol index c45a7c8..19abdf3 100644 --- a/src/governance/Governor.sol +++ b/src/governance/Governor.sol @@ -2,49 +2,51 @@ pragma solidity ^0.8.0; -import {IERC165} from "openzeppelin-contracts/contracts/interfaces/IERC165.sol"; - import {IVotes} from "openzeppelin-contracts/contracts/governance/utils/IVotes.sol"; +import {IGovernor} from "openzeppelin-contracts/contracts/governance/IGovernor.sol"; import {TimelockController} from "openzeppelin-contracts/contracts/governance/TimelockController.sol"; -import {IGovernor} from "openzeppelin-contracts/contracts/governance/IGovernor.sol"; - import {Governor} from "openzeppelin-contracts/contracts/governance/Governor.sol"; import {GovernorVotes} from "openzeppelin-contracts/contracts/governance/extensions/GovernorVotes.sol"; -import {GovernorTimelockControl} from "openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockControl.sol"; +import {GovernorSettings} from "openzeppelin-contracts/contracts/governance/extensions/GovernorSettings.sol"; -contract ReservoirGovernor is GovernorVotes, GovernorTimelockControl { +import {GovernorCountingSimple} from "openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sol"; +import {GovernorTimelockControl} from "openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockControl.sol"; +import {GovernorVotesQuorumFraction} from "openzeppelin-contracts/contracts/governance/extensions/GovernorVotesQuorumFraction.sol"; + +contract ReservoirGovernor is + Governor, + GovernorVotes, + GovernorSettings, + GovernorCountingSimple, + GovernorTimelockControl, + GovernorVotesQuorumFraction +{ constructor( string memory name_, IVotes token_, - TimelockController timelock_ + TimelockController timelock_, + uint256 votingDelay_, + uint256 votingPeriod_, + uint256 proposalThreshold_, + uint256 quorumNumeratorValue_ ) + Governor(name_) GovernorVotes(token_) + GovernorSettings(votingDelay_, votingPeriod_, proposalThreshold_) GovernorTimelockControl(timelock_) - Governor(name_) + GovernorVotesQuorumFraction(quorumNumeratorValue_) {} - // function quorum(uint256) public pure override returns (uint256) { - // return 0; - // } - - // function votingDelay() public pure override returns (uint256) { - // return 4; - // } - - // function votingPeriod() public pure override returns (uint256) { - // return 16; - // } - - // function cancel( - // address[] memory targets, - // uint256[] memory values, - // bytes[] memory calldatas, - // bytes32 salt - // ) public returns (uint256 proposalId) { - // return _cancel(targets, values, calldatas, salt); - // } + function proposalThreshold() + public + view + override(Governor, GovernorSettings) + returns (uint256) + { + return super.proposalThreshold(); + } function state( uint256 proposalId From c337fc0562f7908a9c0e1d0dd51dd5cceb92ca25 Mon Sep 17 00:00:00 2001 From: eukadish Date: Mon, 16 Sep 2024 20:58:18 -0400 Subject: [PATCH 4/9] add mint and burn to DAM --- src/governance/DAM.sol | 52 ++++++++++++++------ src/governance/Governor.sol | 95 ------------------------------------- 2 files changed, 38 insertions(+), 109 deletions(-) delete mode 100644 src/governance/Governor.sol diff --git a/src/governance/DAM.sol b/src/governance/DAM.sol index 68c72fa..c86a0ce 100644 --- a/src/governance/DAM.sol +++ b/src/governance/DAM.sol @@ -5,30 +5,54 @@ pragma solidity ^0.8.24; import {AccessControl} from "openzeppelin-contracts/contracts/access/AccessControl.sol"; import {SafeCast} from "openzeppelin-contracts/contracts/utils/math/SafeCast.sol"; + +import {ERC20Burnable} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol"; import {ERC20Votes, ERC20, ERC20Permit} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sol"; import {ERC20} from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; import {Context} from "openzeppelin-contracts/contracts/utils/Context.sol"; -// burnable, mintable - -contract DAM is ERC20Votes { +contract DAM is AccessControl, ERC20Burnable, ERC20Votes { uint256 private constant supply = 1_000_000_000e18; - constructor(/* admin */) ERC20("DAM", "DAM") ERC20Permit("DAM") { - _mint(msg.sender, supply); + bytes32 public constant MINTER = keccak256(abi.encode("dam.minter")); + + constructor( + address admin_, + string memory name_, + string memory symbol_ + ) ERC20(name_, symbol_) ERC20Permit(name_) { + _grantRole(DEFAULT_ADMIN_ROLE, admin_); + + _mint(admin_, supply); } - // mint - - owner + /// @notice Increase token total supply + /// @param account Address to increment the token balance + /// @param amount Quantity of token added + function mint(address account, uint256 amount) external onlyRole(MINTER) { + _mint(account, amount); + } - // burn - - + function _afterTokenTransfer( + address from, + address to, + uint256 amount + ) internal override(ERC20, ERC20Votes) { + ERC20Votes._afterTokenTransfer(from, to, amount); + } - // function clock() public view virtual override returns (uint48) { - // return SafeCast.toUint48(block.timestamp); - // } + function _mint( + address account, + uint256 amount + ) internal override(ERC20, ERC20Votes) { + super._mint(account, amount); + } - // // solhint-disable-next-line func-name-mixedcase - // function CLOCK_MODE() public view virtual override returns (string memory) { - // return "mode=timestamp"; - // } + function _burn( + address account, + uint256 amount + ) internal override(ERC20, ERC20Votes) { + super._burn(account, amount); + } } diff --git a/src/governance/Governor.sol b/src/governance/Governor.sol deleted file mode 100644 index 19abdf3..0000000 --- a/src/governance/Governor.sol +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import {IVotes} from "openzeppelin-contracts/contracts/governance/utils/IVotes.sol"; -import {IGovernor} from "openzeppelin-contracts/contracts/governance/IGovernor.sol"; - -import {TimelockController} from "openzeppelin-contracts/contracts/governance/TimelockController.sol"; - -import {Governor} from "openzeppelin-contracts/contracts/governance/Governor.sol"; -import {GovernorVotes} from "openzeppelin-contracts/contracts/governance/extensions/GovernorVotes.sol"; -import {GovernorSettings} from "openzeppelin-contracts/contracts/governance/extensions/GovernorSettings.sol"; - -import {GovernorCountingSimple} from "openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sol"; -import {GovernorTimelockControl} from "openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockControl.sol"; -import {GovernorVotesQuorumFraction} from "openzeppelin-contracts/contracts/governance/extensions/GovernorVotesQuorumFraction.sol"; - -contract ReservoirGovernor is - Governor, - GovernorVotes, - GovernorSettings, - GovernorCountingSimple, - GovernorTimelockControl, - GovernorVotesQuorumFraction -{ - constructor( - string memory name_, - IVotes token_, - TimelockController timelock_, - uint256 votingDelay_, - uint256 votingPeriod_, - uint256 proposalThreshold_, - uint256 quorumNumeratorValue_ - ) - Governor(name_) - GovernorVotes(token_) - GovernorSettings(votingDelay_, votingPeriod_, proposalThreshold_) - GovernorTimelockControl(timelock_) - GovernorVotesQuorumFraction(quorumNumeratorValue_) - {} - - function proposalThreshold() - public - view - override(Governor, GovernorSettings) - returns (uint256) - { - return super.proposalThreshold(); - } - - function state( - uint256 proposalId - ) - public - view - override(Governor, GovernorTimelockControl) - returns (ProposalState) - { - return super.state(proposalId); - } - - function _execute( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockControl) { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockControl) returns (uint256) { - return super._cancel(targets, values, calldatas, descriptionHash); - } - - function _executor() - internal - view - override(Governor, GovernorTimelockControl) - returns (address) - { - return super._executor(); - } - - function supportsInterface( - bytes4 interfaceId - ) public view override(Governor, GovernorTimelockControl) returns (bool) { - return super.supportsInterface(interfaceId); - } -} From ae208d98929f5ee2327672151a63fd72079e416c Mon Sep 17 00:00:00 2001 From: eukadish Date: Tue, 17 Sep 2024 08:02:12 -0400 Subject: [PATCH 5/9] remove burn functionality --- src/governance/DAM.sol | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/src/governance/DAM.sol b/src/governance/DAM.sol index c86a0ce..054771f 100644 --- a/src/governance/DAM.sol +++ b/src/governance/DAM.sol @@ -4,15 +4,11 @@ pragma solidity ^0.8.24; import {AccessControl} from "openzeppelin-contracts/contracts/access/AccessControl.sol"; -import {SafeCast} from "openzeppelin-contracts/contracts/utils/math/SafeCast.sol"; - -import {ERC20Burnable} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol"; import {ERC20Votes, ERC20, ERC20Permit} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sol"; import {ERC20} from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; -import {Context} from "openzeppelin-contracts/contracts/utils/Context.sol"; -contract DAM is AccessControl, ERC20Burnable, ERC20Votes { +contract DAM is AccessControl, ERC20Votes { uint256 private constant supply = 1_000_000_000e18; bytes32 public constant MINTER = keccak256(abi.encode("dam.minter")); @@ -33,26 +29,4 @@ contract DAM is AccessControl, ERC20Burnable, ERC20Votes { function mint(address account, uint256 amount) external onlyRole(MINTER) { _mint(account, amount); } - - function _afterTokenTransfer( - address from, - address to, - uint256 amount - ) internal override(ERC20, ERC20Votes) { - ERC20Votes._afterTokenTransfer(from, to, amount); - } - - function _mint( - address account, - uint256 amount - ) internal override(ERC20, ERC20Votes) { - super._mint(account, amount); - } - - function _burn( - address account, - uint256 amount - ) internal override(ERC20, ERC20Votes) { - super._burn(account, amount); - } } From 1df4f3dfbadacd3856e03c2b9ae7e6ad1a805dd0 Mon Sep 17 00:00:00 2001 From: eukadish Date: Tue, 17 Sep 2024 13:26:52 -0400 Subject: [PATCH 6/9] add mainnet environment variable --- .env.template | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.env.template b/.env.template index c802988..5de79f3 100644 --- a/.env.template +++ b/.env.template @@ -5,6 +5,8 @@ PRIVATE_KEY= # RPC_URL=http://127.0.0.1:8545 RPC_URL=https://gateway.tenderly.co/public/polygon +MAINNET_RPC_URL=https://eth-mainnet.nodereal.io/v1/1659dfb40aa24bbb8153a677b98064d7 + ETHERSCAN_API_KEY= OWNER= From 540e2b6f37a7ffac44131663623e5fa44cebc678 Mon Sep 17 00:00:00 2001 From: eukadish Date: Tue, 17 Sep 2024 13:37:21 -0400 Subject: [PATCH 7/9] fix fuzzing restriction --- test/Dam.t..sol | 91 +++++++++++++++++++++++ test/morpho/MorphoUnderlyingAdapter.t.sol | 1 + 2 files changed, 92 insertions(+) create mode 100644 test/Dam.t..sol diff --git a/test/Dam.t..sol b/test/Dam.t..sol new file mode 100644 index 0000000..8d951ee --- /dev/null +++ b/test/Dam.t..sol @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.24; + +import {DAM} from "src/governance/DAM.sol"; + +import {Test} from "forge-std/Test.sol"; +import {console} from "forge-std/console.sol"; + +contract DamTest is Test { + DAM dam; + + address eoa1 = vm.addr(1); + address eoa2 = vm.addr(2); + + function setUp() external { + dam = new DAM(address(this), "DAM", "Reservoir Protocol Token"); + } + + function testInitialState() external { + assertTrue(dam.hasRole(0x00, address(this))); + } + + function testMint() external { + dam.grantRole(dam.MINTER(), address(this)); + + dam.mint(eoa1, 100e18); + dam.mint(eoa2, 100e18); + + assertEq(dam.balanceOf(eoa1), 100e18); + assertEq(dam.balanceOf(eoa2), 100e18); + + // mint same term again + } + + // function testBurn() external { + // term.grantRole(term.MINTER(), address(this)); + + // term.mint(eoa1, 0, 12); + // term.mint(eoa2, 1, 26); + // term.mint(eoa2, 2, 1042); + + // term.burn(eoa1, 0, 8); + + // term.burn(eoa2, 1, 1); + // term.burn(eoa2, 1, 12); + // term.burn(eoa2, 2, 18); + + // assertEq(term.balanceOf(eoa1, 0), 4); + // assertEq(term.balanceOf(eoa1, 1), 0); + // assertEq(term.balanceOf(eoa1, 2), 0); + + // assertEq(term.balanceOf(eoa2, 0), 0); + // assertEq(term.balanceOf(eoa2, 1), 13); + // assertEq(term.balanceOf(eoa2, 2), 1024); + + // assertEq(term.totalSupply(0), 4); + // assertEq(term.totalSupply(1), 13); + // assertEq(term.totalSupply(2), 1024); + // } + + // function testTransfer() external { + // term.grantRole(term.MINTER(), address(this)); + + // term.mint(eoa1, 0, 12); + // term.mint(eoa2, 1, 26); + // term.mint(eoa2, 2, 1042); + + // term.safeTransferFrom(eoa1, eoa2, 0, 8, ""); + + // assertEq(term.balanceOf(eoa1, 0), 4); + // assertEq(term.balanceOf(eoa2, 0), 8); + + // uint256[] memory ids = new uint256[](2); + // uint256[] memory amounts = new uint256[](2); + + // ids[0] = 1; + // ids[1] = 2; + + // amounts[0] = 26; + // amounts[1] = 34; + + // term.safeBatchTransferFrom(eoa2, eoa1, ids, amounts, ""); + + // assertEq(term.balanceOf(eoa1, 1), 26); + // assertEq(term.balanceOf(eoa1, 2), 34); + + // assertEq(term.balanceOf(eoa2, 1), 0); + // assertEq(term.balanceOf(eoa2, 2), 1008); + // } +} diff --git a/test/morpho/MorphoUnderlyingAdapter.t.sol b/test/morpho/MorphoUnderlyingAdapter.t.sol index cac67d4..d66b3a2 100644 --- a/test/morpho/MorphoUnderlyingAdapter.t.sol +++ b/test/morpho/MorphoUnderlyingAdapter.t.sol @@ -498,6 +498,7 @@ contract MorphoUnderlyingAdapterTest is Test { function testRecover(uint256 _amount, address _reciever) external { vm.assume(_reciever != address(0)); + vm.assume(_reciever != address(adapter)); ERC20 testToken = new ERC20("Test Token", "TTT"); deal(address(testToken), address(adapter), _amount); From 19c9985018e1e5c0ff793b3b65c3aec614899c53 Mon Sep 17 00:00:00 2001 From: eukadish Date: Tue, 17 Sep 2024 14:47:06 -0400 Subject: [PATCH 8/9] remove unneeded test --- test/Dam.t..sol | 91 ------------------------------------------------- 1 file changed, 91 deletions(-) delete mode 100644 test/Dam.t..sol diff --git a/test/Dam.t..sol b/test/Dam.t..sol deleted file mode 100644 index 8d951ee..0000000 --- a/test/Dam.t..sol +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {DAM} from "src/governance/DAM.sol"; - -import {Test} from "forge-std/Test.sol"; -import {console} from "forge-std/console.sol"; - -contract DamTest is Test { - DAM dam; - - address eoa1 = vm.addr(1); - address eoa2 = vm.addr(2); - - function setUp() external { - dam = new DAM(address(this), "DAM", "Reservoir Protocol Token"); - } - - function testInitialState() external { - assertTrue(dam.hasRole(0x00, address(this))); - } - - function testMint() external { - dam.grantRole(dam.MINTER(), address(this)); - - dam.mint(eoa1, 100e18); - dam.mint(eoa2, 100e18); - - assertEq(dam.balanceOf(eoa1), 100e18); - assertEq(dam.balanceOf(eoa2), 100e18); - - // mint same term again - } - - // function testBurn() external { - // term.grantRole(term.MINTER(), address(this)); - - // term.mint(eoa1, 0, 12); - // term.mint(eoa2, 1, 26); - // term.mint(eoa2, 2, 1042); - - // term.burn(eoa1, 0, 8); - - // term.burn(eoa2, 1, 1); - // term.burn(eoa2, 1, 12); - // term.burn(eoa2, 2, 18); - - // assertEq(term.balanceOf(eoa1, 0), 4); - // assertEq(term.balanceOf(eoa1, 1), 0); - // assertEq(term.balanceOf(eoa1, 2), 0); - - // assertEq(term.balanceOf(eoa2, 0), 0); - // assertEq(term.balanceOf(eoa2, 1), 13); - // assertEq(term.balanceOf(eoa2, 2), 1024); - - // assertEq(term.totalSupply(0), 4); - // assertEq(term.totalSupply(1), 13); - // assertEq(term.totalSupply(2), 1024); - // } - - // function testTransfer() external { - // term.grantRole(term.MINTER(), address(this)); - - // term.mint(eoa1, 0, 12); - // term.mint(eoa2, 1, 26); - // term.mint(eoa2, 2, 1042); - - // term.safeTransferFrom(eoa1, eoa2, 0, 8, ""); - - // assertEq(term.balanceOf(eoa1, 0), 4); - // assertEq(term.balanceOf(eoa2, 0), 8); - - // uint256[] memory ids = new uint256[](2); - // uint256[] memory amounts = new uint256[](2); - - // ids[0] = 1; - // ids[1] = 2; - - // amounts[0] = 26; - // amounts[1] = 34; - - // term.safeBatchTransferFrom(eoa2, eoa1, ids, amounts, ""); - - // assertEq(term.balanceOf(eoa1, 1), 26); - // assertEq(term.balanceOf(eoa1, 2), 34); - - // assertEq(term.balanceOf(eoa2, 1), 0); - // assertEq(term.balanceOf(eoa2, 2), 1008); - // } -} From e12e4afe3309a48190bb44e1d359fc7185a76458 Mon Sep 17 00:00:00 2001 From: eukadish Date: Wed, 18 Sep 2024 17:56:20 -0400 Subject: [PATCH 9/9] add burn for governance token --- src/governance/DAM.sol | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/governance/DAM.sol b/src/governance/DAM.sol index 054771f..255e6c7 100644 --- a/src/governance/DAM.sol +++ b/src/governance/DAM.sol @@ -29,4 +29,18 @@ contract DAM is AccessControl, ERC20Votes { function mint(address account, uint256 amount) external onlyRole(MINTER) { _mint(account, amount); } + + /// @notice Decrease token total supply + /// @param amount Quantity of token deducted + function burn(uint256 amount) public virtual { + _burn(_msgSender(), amount); + } + + /// @notice Decrease token total supply + /// @param account Address to decrement the token balance + /// @param amount Quantity of token deducted + function burnFrom(address account, uint256 amount) public virtual { + _spendAllowance(account, _msgSender(), amount); + _burn(account, amount); + } }