From 856ad925d10aa70d9e1e3708badcfee68d3d5546 Mon Sep 17 00:00:00 2001 From: Andrew Dmytrenko Date: Fri, 7 Mar 2025 16:08:55 +0200 Subject: [PATCH 1/4] add LastPoolOwnerState abstract contract --- contracts/LastPoolOwnerState.sol | 31 +++++++++++++++++++++++++++ contracts/mocks/MockLastPoolOwner.sol | 28 ++++++++++++++++++++++++ test/11_LastPoolOwner.ts | 27 +++++++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 contracts/LastPoolOwnerState.sol create mode 100644 contracts/mocks/MockLastPoolOwner.sol create mode 100644 test/11_LastPoolOwner.ts diff --git a/contracts/LastPoolOwnerState.sol b/contracts/LastPoolOwnerState.sol new file mode 100644 index 0000000..ebe21a5 --- /dev/null +++ b/contracts/LastPoolOwnerState.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "./interfaces/IBeforeTransfer.sol"; +import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; + +/** + * @title LastPoolOwnerState + * @dev Contract to keep track of the last owner of a Provider pool before a transfer. + */ +abstract contract LastPoolOwnerState is IBeforeTransfer, IERC165 { + // Mapping to store the last owner of each Provider pool before a transfer + mapping(uint256 => address) internal lastPoolOwner; + + /** + * @dev Function to be called before a transfer. + * @param from Address from which the transfer is initiated. + * @param to Address to which the transfer is directed. + * @param poolId Identifier of the Provider pool. + */ + function beforeTransfer(address from, address to, uint256 poolId) external virtual override; + + /** + * @dev Checks whether a contract supports the specified interface. + * @param interfaceId Interface identifier. + * @return A boolean indicating whether the contract supports the specified interface. + */ + function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { + return interfaceId == type(IERC165).interfaceId || interfaceId == type(IBeforeTransfer).interfaceId; + } +} \ No newline at end of file diff --git a/contracts/mocks/MockLastPoolOwner.sol b/contracts/mocks/MockLastPoolOwner.sol new file mode 100644 index 0000000..f41eaa2 --- /dev/null +++ b/contracts/mocks/MockLastPoolOwner.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "../LastPoolOwnerState.sol"; + +/** + * @title MockLastPoolOwner + * @dev Mock contract to keep track of the last owner of a Provider pool before a transfer. + */ +contract MockLastPoolOwner is LastPoolOwnerState { + /** + * @dev Function to be called before a transfer. + * @param from Address from which the transfer is initiated. + * @param poolId Identifier of the Provider pool. + */ + function beforeTransfer(address from, address, uint256 poolId) external override { + lastPoolOwner[poolId] = from; + } + + /** + * @dev Function to get the last owner of a Provider pool. + * @param poolId Identifier of the Provider pool. + * @return Address of the last owner of the Provider pool. + */ + function getLastPoolOwner(uint256 poolId) external view returns (address) { + return lastPoolOwner[poolId]; + } +} diff --git a/test/11_LastPoolOwner.ts b/test/11_LastPoolOwner.ts new file mode 100644 index 0000000..db886fc --- /dev/null +++ b/test/11_LastPoolOwner.ts @@ -0,0 +1,27 @@ +import { ethers } from 'hardhat'; +import { deployed } from '../scripts/deploy'; +import { MockLastPoolOwner } from '../typechain-types'; +import { expect } from 'chai'; + +describe('LastPoolOwner abstract contract', function () { + let lastPoolOwner: MockLastPoolOwner; + const poolId = ethers.parseUnits('100', 18); + + before(async () => { + lastPoolOwner = await deployed('MockLastPoolOwner'); + }); + + it('should support IBeforeTransfer interface', async () => { + expect(await lastPoolOwner.supportsInterface('0x1ffb811f')).to.be.true; + }); + + it('should support IERC165 interface', async () => { + expect(await lastPoolOwner.supportsInterface('0x01ffc9a7')).to.be.true; + }); + + it('should return lastPoolOwner', async () => { + const [addr0] = await ethers.getSigners(); + await lastPoolOwner.beforeTransfer(addr0.address, addr0.address, poolId); + expect(await lastPoolOwner.getLastPoolOwner(poolId)).to.equal(addr0.address); + }); +}); From 6e3e66cbe9ca30d3f6b1ebd7450c5977ea41d77f Mon Sep 17 00:00:00 2001 From: Andrew Dmytrenko Date: Fri, 7 Mar 2025 16:09:52 +0200 Subject: [PATCH 2/4] 3.0.4 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index de265a6..1f8f6ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@poolzfinance/poolz-helper-v2", - "version": "3.0.3", + "version": "3.0.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@poolzfinance/poolz-helper-v2", - "version": "3.0.3", + "version": "3.0.4", "license": "MIT", "dependencies": { "@ironblocks/firewall-consumer": "^1.0.17", diff --git a/package.json b/package.json index 76a1424..b691c77 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@poolzfinance/poolz-helper-v2", - "version": "3.0.3", + "version": "3.0.4", "description": "A single source of truth of helper contracts used by Poolz.", "main": "dist/index.js", "types": "dist/index.d.ts", From 158ab26cf802fe4dfca066f065468cd771dcf6d3 Mon Sep 17 00:00:00 2001 From: Andrew Dmytrenko Date: Fri, 7 Mar 2025 16:13:32 +0200 Subject: [PATCH 3/4] update IERC165 tests --- test/11_LastPoolOwner.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/11_LastPoolOwner.ts b/test/11_LastPoolOwner.ts index db886fc..9cf62e4 100644 --- a/test/11_LastPoolOwner.ts +++ b/test/11_LastPoolOwner.ts @@ -12,11 +12,13 @@ describe('LastPoolOwner abstract contract', function () { }); it('should support IBeforeTransfer interface', async () => { - expect(await lastPoolOwner.supportsInterface('0x1ffb811f')).to.be.true; + const IBeforeTransferInterfaceId = '0x1ffb811f'; + expect(await lastPoolOwner.supportsInterface(IBeforeTransferInterfaceId)).to.be.true; }); it('should support IERC165 interface', async () => { - expect(await lastPoolOwner.supportsInterface('0x01ffc9a7')).to.be.true; + const IERC165InterfaceId = '0x01ffc9a7'; + expect(await lastPoolOwner.supportsInterface(IERC165InterfaceId)).to.be.true; }); it('should return lastPoolOwner', async () => { From 5f591463b21b74e045e581dca7da94f2da4e85ef Mon Sep 17 00:00:00 2001 From: Andrew Dmytrenko Date: Fri, 7 Mar 2025 16:15:27 +0200 Subject: [PATCH 4/4] codefactor fix --- test/11_LastPoolOwner.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/11_LastPoolOwner.ts b/test/11_LastPoolOwner.ts index 9cf62e4..4237fef 100644 --- a/test/11_LastPoolOwner.ts +++ b/test/11_LastPoolOwner.ts @@ -13,12 +13,12 @@ describe('LastPoolOwner abstract contract', function () { it('should support IBeforeTransfer interface', async () => { const IBeforeTransferInterfaceId = '0x1ffb811f'; - expect(await lastPoolOwner.supportsInterface(IBeforeTransferInterfaceId)).to.be.true; + expect(await lastPoolOwner.supportsInterface(IBeforeTransferInterfaceId)).to.equal(true); }); it('should support IERC165 interface', async () => { const IERC165InterfaceId = '0x01ffc9a7'; - expect(await lastPoolOwner.supportsInterface(IERC165InterfaceId)).to.be.true; + expect(await lastPoolOwner.supportsInterface(IERC165InterfaceId)).to.equal(true); }); it('should return lastPoolOwner', async () => {