From 2d5368ee39e7c02d3072c24e786b7e1b4e02affb Mon Sep 17 00:00:00 2001 From: eukadish Date: Tue, 3 Sep 2024 18:02:57 -0400 Subject: [PATCH 1/7] add zero coupon bond --- test/LiquidTerm.t.sol | 260 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 test/LiquidTerm.t.sol diff --git a/test/LiquidTerm.t.sol b/test/LiquidTerm.t.sol new file mode 100644 index 0000000..05383d1 --- /dev/null +++ b/test/LiquidTerm.t.sol @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.24; + +import {IERC1155} from "openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol"; + +import {ERC20} from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; +import {ERC1155} from "openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol"; +import {ERC1155Supply} from "openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol"; + +import {Term} from "src/Term.sol"; + +import {Test} from "forge-std/Test.sol"; +import {console} from "forge-std/console.sol"; + +contract LiquidTerm is ERC20 { + IERC1155 public immutable registry; + uint256 public immutable tokenId; + + constructor( + IERC1155 _registry, + uint256 _tokenId + ) ERC20("Liquid Term", "ltrUSD") { + registry = _registry; + tokenId = _tokenId; + } + + function totalSupply() public view override returns (uint256) { + try ERC1155Supply(address(registry)).totalSupply(tokenId) returns ( + uint256 amount + ) { + return amount; + } catch { + return 0; + } + } + + function balanceOf(address account) public view override returns (uint256) { + return registry.balanceOf(account, tokenId); + } + + function _transfer( + address from, + address to, + uint256 amount + ) internal override { + registry.safeTransferFrom(from, to, tokenId, amount, ""); + } +} + +// TODO: Liquid Term => Fungible Term +// TODO: Get term contract address from the token + +contract LiquidTermTest is Test { + Term term; + + LiquidTerm lTerm00; + LiquidTerm lTerm01; + LiquidTerm lTerm02; + LiquidTerm lTerm03; + + address eoa1 = vm.addr(1); + address eoa2 = vm.addr(2); + address eoa3 = vm.addr(3); + address eoa4 = vm.addr(4); + + function setUp() external { + term = new Term(address(this), "https://reservoir.xyz"); + + vm.prank(eoa1); + term.setApprovalForAll(address(this), true); + + vm.prank(eoa2); + term.setApprovalForAll(address(this), true); + + lTerm00 = new LiquidTerm(IERC1155(address(term)), 0); + lTerm01 = new LiquidTerm(IERC1155(address(term)), 1); + lTerm02 = new LiquidTerm(IERC1155(address(term)), 2); + lTerm03 = new LiquidTerm(IERC1155(address(term)), 3); + } + + function testInitialState() external { + assertTrue(term.hasRole(0x00, address(this))); + } + + function testMint() external { + term.grantRole(term.MINTER(), address(this)); + + term.mint(eoa1, 0, 1_000e18); + term.mint(eoa2, 1, 1_000e18); + term.mint(eoa3, 2, 1_000e18); + term.mint(eoa4, 3, 1_000e18); + + assertEq(term.balanceOf(eoa1, 0), 1_000e18); + assertEq(term.balanceOf(eoa2, 1), 1_000e18); + assertEq(term.balanceOf(eoa3, 2), 1_000e18); + assertEq(term.balanceOf(eoa4, 3), 1_000e18); + + assertEq(term.totalSupply(0), 1_000e18); + assertEq(term.totalSupply(1), 1_000e18); + assertEq(term.totalSupply(2), 1_000e18); + assertEq(term.totalSupply(3), 1_000e18); + + assertEq(lTerm00.totalSupply(), 1_000e18); + assertEq(lTerm01.totalSupply(), 1_000e18); + assertEq(lTerm02.totalSupply(), 1_000e18); + assertEq(lTerm03.totalSupply(), 1_000e18); + + assertEq(lTerm00.balanceOf(eoa1), 1_000e18); + assertEq(lTerm00.balanceOf(eoa2), 0); + assertEq(lTerm00.balanceOf(eoa3), 0); + assertEq(lTerm00.balanceOf(eoa4), 0); + + assertEq(lTerm01.balanceOf(eoa1), 0); + assertEq(lTerm01.balanceOf(eoa2), 1_000e18); + assertEq(lTerm01.balanceOf(eoa3), 0); + assertEq(lTerm01.balanceOf(eoa4), 0); + + assertEq(lTerm02.balanceOf(eoa1), 0); + assertEq(lTerm02.balanceOf(eoa2), 0); + assertEq(lTerm02.balanceOf(eoa3), 1_000e18); + assertEq(lTerm02.balanceOf(eoa4), 0); + + assertEq(lTerm03.balanceOf(eoa1), 0); + assertEq(lTerm03.balanceOf(eoa2), 0); + assertEq(lTerm03.balanceOf(eoa3), 0); + assertEq(lTerm03.balanceOf(eoa4), 1_000e18); + } + + function testTransferSuccess01() external { + address receiver = vm.addr(uint256(keccak256("receiver"))); + + term.grantRole(term.MINTER(), address(this)); + + term.mint(eoa1, 0, 1_000e18); + term.mint(eoa2, 1, 1_000e18); + term.mint(eoa3, 2, 1_000e18); + term.mint(eoa4, 3, 1_000e18); + + // eoa1 + + assertEq(lTerm00.balanceOf(receiver), 0); + assertEq(lTerm00.balanceOf(eoa1), 1_000e18); + + vm.prank(eoa1); + term.setApprovalForAll(address(lTerm00), true); + + vm.prank(eoa1); + lTerm00.transfer(receiver, 1e18); + + assertEq(lTerm00.balanceOf(receiver), 1e18); + assertEq(lTerm00.balanceOf(eoa1), 999e18); + + // eoa2 + + assertEq(lTerm01.balanceOf(receiver), 0); + assertEq(lTerm01.balanceOf(eoa2), 1_000e18); + + vm.prank(eoa2); + term.setApprovalForAll(address(lTerm01), true); + + vm.prank(eoa2); + lTerm01.transfer(receiver, 1e18); + + assertEq(lTerm01.balanceOf(receiver), 1e18); + assertEq(lTerm01.balanceOf(eoa2), 999e18); + + // eoa3 + + assertEq(lTerm02.balanceOf(receiver), 0); + assertEq(lTerm02.balanceOf(eoa3), 1_000e18); + + vm.prank(eoa3); + term.setApprovalForAll(address(lTerm02), true); + + vm.prank(eoa3); + lTerm02.transfer(receiver, 1e18); + + assertEq(lTerm02.balanceOf(receiver), 1e18); + assertEq(lTerm02.balanceOf(eoa3), 999e18); + + // eoa4 + + assertEq(lTerm03.balanceOf(receiver), 0); + assertEq(lTerm03.balanceOf(eoa4), 1_000e18); + + vm.prank(eoa4); + term.setApprovalForAll(address(lTerm03), true); + + vm.prank(eoa4); + lTerm03.transfer(receiver, 1e18); + + assertEq(lTerm03.balanceOf(receiver), 1e18); + assertEq(lTerm03.balanceOf(eoa4), 999e18); + } + + function testTransferSuccess02() external { + assertTrue(true); + } + + function testTransferFailure() external { + assertTrue(true); + } + + // 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 2eeff8054e7261c7d866343dda6e34e69061674c Mon Sep 17 00:00:00 2001 From: eukadish Date: Tue, 3 Sep 2024 18:09:43 -0400 Subject: [PATCH 2/7] fix z coupon bond deps --- src/LquidTerm.sol | 43 +++++++++++++++++++++++++++++++++++++ src/governance/Governor.sol | 32 +++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 src/LquidTerm.sol create mode 100644 src/governance/Governor.sol diff --git a/src/LquidTerm.sol b/src/LquidTerm.sol new file mode 100644 index 0000000..d88b8c4 --- /dev/null +++ b/src/LquidTerm.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT + +import {IERC1155} from "openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol"; + +import {ERC20} from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; + +import {ERC1155Supply} from "openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol"; + +contract LiquidTerm is ERC20 { + uint256 public immutable tokenId; + + IERC1155 public immutable registry; + + constructor( + IERC1155 _registry, + uint256 _tokenId + ) ERC20("Liquid Term", "ltrUSD") { + registry = _registry; + tokenId = _tokenId; + } + + function totalSupply() public view override returns (uint256) { + try ERC1155Supply(address(registry)).totalSupply(tokenId) returns ( + uint256 amount + ) { + return amount; + } catch { + return 0; + } + } + + function balanceOf(address account) public view override returns (uint256) { + return registry.balanceOf(account, tokenId); + } + + function _transfer( + address from, + address to, + uint256 amount + ) internal override { + registry.safeTransferFrom(from, to, tokenId, amount, ""); + } +} diff --git a/src/governance/Governor.sol b/src/governance/Governor.sol new file mode 100644 index 0000000..379eb5e --- /dev/null +++ b/src/governance/Governor.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import {GovernorCountingSimple} from "openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sol"; +import {GovernorVotesComp} from "openzeppelin-contracts/contracts/governance/extensions/GovernorVotesComp.sol"; + +// contract Governor is GovernorVotesComp, GovernorCountingSimple { +// constructor(string memory name_, ERC20VotesComp token_) Governor(name_) GovernorVotesComp(token_) {} + +// 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); +// } +// } + From 3cea7e497534584bc2184337666ad2423b9b0f0b Mon Sep 17 00:00:00 2001 From: eukadish Date: Tue, 3 Sep 2024 18:10:53 -0400 Subject: [PATCH 3/7] fix source file name --- src/{LquidTerm.sol => LiquidTerm.sol} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{LquidTerm.sol => LiquidTerm.sol} (100%) diff --git a/src/LquidTerm.sol b/src/LiquidTerm.sol similarity index 100% rename from src/LquidTerm.sol rename to src/LiquidTerm.sol From 4e6532d47c5256697ba258cc33ca71cabdc58c93 Mon Sep 17 00:00:00 2001 From: eukadish Date: Mon, 16 Sep 2024 20:28:03 -0400 Subject: [PATCH 4/7] add dynamic name and symbol to constructor --- src/LiquidTerm.sol | 26 +++++++++++--------------- src/governance/Governor.sol | 32 -------------------------------- 2 files changed, 11 insertions(+), 47 deletions(-) delete mode 100644 src/governance/Governor.sol diff --git a/src/LiquidTerm.sol b/src/LiquidTerm.sol index d88b8c4..bbbd4a0 100644 --- a/src/LiquidTerm.sol +++ b/src/LiquidTerm.sol @@ -9,28 +9,24 @@ import {ERC1155Supply} from "openzeppelin-contracts/contracts/token/ERC1155/exte contract LiquidTerm is ERC20 { uint256 public immutable tokenId; - IERC1155 public immutable registry; + address public immutable registry; constructor( - IERC1155 _registry, - uint256 _tokenId - ) ERC20("Liquid Term", "ltrUSD") { - registry = _registry; - tokenId = _tokenId; + string memory name_, + string memory symbol_, + address registry_, + uint256 tokenId_ + ) ERC20(name_, symbol_) { + registry = registry_; + tokenId = tokenId_; } function totalSupply() public view override returns (uint256) { - try ERC1155Supply(address(registry)).totalSupply(tokenId) returns ( - uint256 amount - ) { - return amount; - } catch { - return 0; - } + return ERC1155Supply(registry).totalSupply(tokenId); } function balanceOf(address account) public view override returns (uint256) { - return registry.balanceOf(account, tokenId); + return IERC1155(registry).balanceOf(account, tokenId); } function _transfer( @@ -38,6 +34,6 @@ contract LiquidTerm is ERC20 { address to, uint256 amount ) internal override { - registry.safeTransferFrom(from, to, tokenId, amount, ""); + IERC1155(registry).safeTransferFrom(from, to, tokenId, amount, ""); } } diff --git a/src/governance/Governor.sol b/src/governance/Governor.sol deleted file mode 100644 index 379eb5e..0000000 --- a/src/governance/Governor.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import {GovernorCountingSimple} from "openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sol"; -import {GovernorVotesComp} from "openzeppelin-contracts/contracts/governance/extensions/GovernorVotesComp.sol"; - -// contract Governor is GovernorVotesComp, GovernorCountingSimple { -// constructor(string memory name_, ERC20VotesComp token_) Governor(name_) GovernorVotesComp(token_) {} - -// 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); -// } -// } - From ad42c17c0871912964c2f0a79151c536fbc8aa37 Mon Sep 17 00:00:00 2001 From: eukadish Date: Wed, 18 Sep 2024 12:46:36 -0400 Subject: [PATCH 5/7] test suite for liquid term token --- test/LiquidTerm.t.sol | 136 ++++++++++-------------------------------- 1 file changed, 30 insertions(+), 106 deletions(-) diff --git a/test/LiquidTerm.t.sol b/test/LiquidTerm.t.sol index 05383d1..f9daa07 100644 --- a/test/LiquidTerm.t.sol +++ b/test/LiquidTerm.t.sol @@ -9,45 +9,11 @@ import {ERC1155} from "openzeppelin-contracts/contracts/token/ERC1155/ERC1155.so import {ERC1155Supply} from "openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol"; import {Term} from "src/Term.sol"; +import {LiquidTerm} from "src/LiquidTerm.sol"; import {Test} from "forge-std/Test.sol"; import {console} from "forge-std/console.sol"; -contract LiquidTerm is ERC20 { - IERC1155 public immutable registry; - uint256 public immutable tokenId; - - constructor( - IERC1155 _registry, - uint256 _tokenId - ) ERC20("Liquid Term", "ltrUSD") { - registry = _registry; - tokenId = _tokenId; - } - - function totalSupply() public view override returns (uint256) { - try ERC1155Supply(address(registry)).totalSupply(tokenId) returns ( - uint256 amount - ) { - return amount; - } catch { - return 0; - } - } - - function balanceOf(address account) public view override returns (uint256) { - return registry.balanceOf(account, tokenId); - } - - function _transfer( - address from, - address to, - uint256 amount - ) internal override { - registry.safeTransferFrom(from, to, tokenId, amount, ""); - } -} - // TODO: Liquid Term => Fungible Term // TODO: Get term contract address from the token @@ -73,17 +39,39 @@ contract LiquidTermTest is Test { vm.prank(eoa2); term.setApprovalForAll(address(this), true); - lTerm00 = new LiquidTerm(IERC1155(address(term)), 0); - lTerm01 = new LiquidTerm(IERC1155(address(term)), 1); - lTerm02 = new LiquidTerm(IERC1155(address(term)), 2); - lTerm03 = new LiquidTerm(IERC1155(address(term)), 3); + lTerm00 = new LiquidTerm("Liquid Term", "ltrUSD-00", address(term), 0); + lTerm01 = new LiquidTerm("Liquid Term", "ltrUSD-01", address(term), 1); + lTerm02 = new LiquidTerm("Liquid Term", "ltrUSD-02", address(term), 2); + lTerm03 = new LiquidTerm("Liquid Term", "ltrUSD-03", address(term), 3); } function testInitialState() external { - assertTrue(term.hasRole(0x00, address(this))); + assertEq(lTerm00.tokenId(), 0); + assertEq(lTerm00.registry(), address(term)); + + assertEq(lTerm00.symbol(), "ltrUSD-00"); + assertEq(lTerm00.name(), "Liquid Term"); + + assertEq(lTerm01.tokenId(), 1); + assertEq(lTerm01.registry(), address(term)); + + assertEq(lTerm02.symbol(), "ltrUSD-02"); + assertEq(lTerm02.name(), "Liquid Term"); + + assertEq(lTerm02.tokenId(), 2); + assertEq(lTerm02.registry(), address(term)); + + assertEq(lTerm02.symbol(), "ltrUSD-02"); + assertEq(lTerm02.name(), "Liquid Term"); + + assertEq(lTerm03.tokenId(), 3); + assertEq(lTerm03.registry(), address(term)); + + assertEq(lTerm03.symbol(), "ltrUSD-03"); + assertEq(lTerm03.name(), "Liquid Term"); } - function testMint() external { + function testBalanceAndTotalSupply() external { term.grantRole(term.MINTER(), address(this)); term.mint(eoa1, 0, 1_000e18); @@ -127,7 +115,7 @@ contract LiquidTermTest is Test { assertEq(lTerm03.balanceOf(eoa4), 1_000e18); } - function testTransferSuccess01() external { + function testTransfer() external { address receiver = vm.addr(uint256(keccak256("receiver"))); term.grantRole(term.MINTER(), address(this)); @@ -193,68 +181,4 @@ contract LiquidTermTest is Test { assertEq(lTerm03.balanceOf(receiver), 1e18); assertEq(lTerm03.balanceOf(eoa4), 999e18); } - - function testTransferSuccess02() external { - assertTrue(true); - } - - function testTransferFailure() external { - assertTrue(true); - } - - // 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 2409b9baafdc907e235e0e917a9a8bd2961de74f Mon Sep 17 00:00:00 2001 From: eukadish Date: Wed, 18 Sep 2024 12:51:39 -0400 Subject: [PATCH 6/7] remove unused comments --- test/LiquidTerm.t.sol | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/test/LiquidTerm.t.sol b/test/LiquidTerm.t.sol index f9daa07..94c4d1f 100644 --- a/test/LiquidTerm.t.sol +++ b/test/LiquidTerm.t.sol @@ -2,21 +2,12 @@ pragma solidity ^0.8.24; -import {IERC1155} from "openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol"; - -import {ERC20} from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; -import {ERC1155} from "openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol"; -import {ERC1155Supply} from "openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol"; - import {Term} from "src/Term.sol"; import {LiquidTerm} from "src/LiquidTerm.sol"; import {Test} from "forge-std/Test.sol"; import {console} from "forge-std/console.sol"; -// TODO: Liquid Term => Fungible Term -// TODO: Get term contract address from the token - contract LiquidTermTest is Test { Term term; @@ -33,12 +24,6 @@ contract LiquidTermTest is Test { function setUp() external { term = new Term(address(this), "https://reservoir.xyz"); - vm.prank(eoa1); - term.setApprovalForAll(address(this), true); - - vm.prank(eoa2); - term.setApprovalForAll(address(this), true); - lTerm00 = new LiquidTerm("Liquid Term", "ltrUSD-00", address(term), 0); lTerm01 = new LiquidTerm("Liquid Term", "ltrUSD-01", address(term), 1); lTerm02 = new LiquidTerm("Liquid Term", "ltrUSD-02", address(term), 2); From 2238ac36457088d8a57842f9733146ed69f5bafe Mon Sep 17 00:00:00 2001 From: eukadish Date: Wed, 18 Sep 2024 16:50:06 -0400 Subject: [PATCH 7/7] add test for approval for liquid term token --- test/LiquidTerm.t.sol | 83 +++++++++++++++++++++++ test/morpho/MorphoUnderlyingAdapter.t.sol | 1 + 2 files changed, 84 insertions(+) diff --git a/test/LiquidTerm.t.sol b/test/LiquidTerm.t.sol index 94c4d1f..5aafb3a 100644 --- a/test/LiquidTerm.t.sol +++ b/test/LiquidTerm.t.sol @@ -166,4 +166,87 @@ contract LiquidTermTest is Test { assertEq(lTerm03.balanceOf(receiver), 1e18); assertEq(lTerm03.balanceOf(eoa4), 999e18); } + + function testTransferFrom() external { + address receiver = vm.addr(uint256(keccak256("receiver"))); + + term.grantRole(term.MINTER(), address(this)); + + term.mint(eoa1, 0, 1_000e18); + term.mint(eoa2, 1, 1_000e18); + term.mint(eoa3, 2, 1_000e18); + term.mint(eoa4, 3, 1_000e18); + + // eoa1 + + assertEq(lTerm00.balanceOf(receiver), 0); + assertEq(lTerm00.balanceOf(eoa1), 1_000e18); + + vm.prank(eoa1); + term.setApprovalForAll(address(lTerm00), true); + + vm.prank(eoa1); + lTerm00.approve(address(this), 1e18); + + lTerm00.transferFrom(eoa1, receiver, 1e18); + + assertEq(lTerm00.balanceOf(receiver), 1e18); + assertEq(lTerm00.balanceOf(eoa1), 999e18); + + assertEq(lTerm00.allowance(eoa1, receiver), 0); + + // eoa2 + + assertEq(lTerm01.balanceOf(receiver), 0); + assertEq(lTerm01.balanceOf(eoa2), 1_000e18); + + vm.prank(eoa2); + term.setApprovalForAll(address(lTerm01), true); + + vm.prank(eoa2); + lTerm01.approve(address(this), 1e18); + + lTerm01.transferFrom(eoa2, receiver, 1e18); + + assertEq(lTerm01.balanceOf(receiver), 1e18); + assertEq(lTerm01.balanceOf(eoa2), 999e18); + + assertEq(lTerm01.allowance(eoa2, receiver), 0); + + // eoa3 + + assertEq(lTerm02.balanceOf(receiver), 0); + assertEq(lTerm02.balanceOf(eoa3), 1_000e18); + + vm.prank(eoa3); + term.setApprovalForAll(address(lTerm02), true); + + vm.prank(eoa3); + lTerm02.approve(address(this), 1e18); + + lTerm02.transferFrom(eoa3, receiver, 1e18); + + assertEq(lTerm02.balanceOf(receiver), 1e18); + assertEq(lTerm02.balanceOf(eoa3), 999e18); + + assertEq(lTerm02.allowance(eoa3, receiver), 0); + + // eoa4 + + assertEq(lTerm03.balanceOf(receiver), 0); + assertEq(lTerm03.balanceOf(eoa4), 1_000e18); + + vm.prank(eoa4); + term.setApprovalForAll(address(lTerm03), true); + + vm.prank(eoa4); + lTerm03.approve(address(this), 1e18); + + lTerm03.transferFrom(eoa4, receiver, 1e18); + + assertEq(lTerm03.balanceOf(receiver), 1e18); + assertEq(lTerm03.balanceOf(eoa4), 999e18); + + assertEq(lTerm03.allowance(eoa2, receiver), 0); + } } 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);