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/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", diff --git a/test/11_LastPoolOwner.ts b/test/11_LastPoolOwner.ts new file mode 100644 index 0000000..4237fef --- /dev/null +++ b/test/11_LastPoolOwner.ts @@ -0,0 +1,29 @@ +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 () => { + const IBeforeTransferInterfaceId = '0x1ffb811f'; + expect(await lastPoolOwner.supportsInterface(IBeforeTransferInterfaceId)).to.equal(true); + }); + + it('should support IERC165 interface', async () => { + const IERC165InterfaceId = '0x01ffc9a7'; + expect(await lastPoolOwner.supportsInterface(IERC165InterfaceId)).to.equal(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); + }); +});