diff --git a/contracts/account/CMAccount.sol b/contracts/account/CMAccount.sol index 6e507db..9222c98 100644 --- a/contracts/account/CMAccount.sol +++ b/contracts/account/CMAccount.sol @@ -10,7 +10,9 @@ import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; // Access +// Size Impact: +0.411 (Enumerable) import "@openzeppelin/contracts-upgradeable/access/extensions/AccessControlEnumerableUpgradeable.sol"; +//import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; // ERC721 import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; @@ -42,7 +44,6 @@ contract CMAccount is UUPSUpgradeable, IERC721Receiver, ChequeManager, - BookingTokenOperator, PartnerConfiguration, GasMoneyManager { @@ -331,16 +332,23 @@ contract CMAccount is uint256 expirationTimestamp, uint256 price, IERC20 paymentToken - ) external override onlyRole(BOOKING_OPERATOR_ROLE) { + ) external onlyRole(BOOKING_OPERATOR_ROLE) { // Mint the token - _mintBookingToken(getBookingTokenAddress(), reservedFor, uri, expirationTimestamp, price, paymentToken); + BookingTokenOperator._mintBookingToken( + getBookingTokenAddress(), + reservedFor, + uri, + expirationTimestamp, + price, + paymentToken + ); } /** * @dev Buy booking token */ - function buyBookingToken(uint256 tokenId) external override onlyRole(BOOKING_OPERATOR_ROLE) { - _buyBookingToken(getBookingTokenAddress(), tokenId); + function buyBookingToken(uint256 tokenId) external onlyRole(BOOKING_OPERATOR_ROLE) { + BookingTokenOperator._buyBookingToken(getBookingTokenAddress(), tokenId); } /** @@ -587,21 +595,25 @@ contract CMAccount is /** * @dev Add messenger bot */ - function addMessengerBot(address bot) public onlyRole(BOT_ADMIN_ROLE) { - // Grant roles to bot - _grantRole(CHEQUE_OPERATOR_ROLE, bot); - _grantRole(BOOKING_OPERATOR_ROLE, bot); - _grantRole(GAS_WITHDRAWER_ROLE, bot); + // function addMessengerBot(address bot) public onlyRole(BOT_ADMIN_ROLE) { + // // Grant roles to bot + // _grantRole(CHEQUE_OPERATOR_ROLE, bot); + // _grantRole(BOOKING_OPERATOR_ROLE, bot); + // _grantRole(GAS_WITHDRAWER_ROLE, bot); - emit MessengerBotAdded(bot); - } + // emit MessengerBotAdded(bot); + // } function addMessengerBot(address bot, uint256 gasMoney) public onlyRole(BOT_ADMIN_ROLE) { // Check if we can spend the gasMoney to send it to the bot _checkPrefundSpent(gasMoney); // Grant roles to bot - addMessengerBot(bot); + _grantRole(CHEQUE_OPERATOR_ROLE, bot); + _grantRole(BOOKING_OPERATOR_ROLE, bot); + _grantRole(GAS_WITHDRAWER_ROLE, bot); + + emit MessengerBotAdded(bot); // Send gasMoney to bot payable(bot).sendValue(gasMoney); diff --git a/contracts/booking-token/BookingTokenOperator.sol b/contracts/booking-token/BookingTokenOperator.sol index 6da978c..ee82c29 100644 --- a/contracts/booking-token/BookingTokenOperator.sol +++ b/contracts/booking-token/BookingTokenOperator.sol @@ -6,7 +6,7 @@ import "./IBookingToken.sol"; // ERC-20 Utils import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -abstract contract BookingTokenOperator { +library BookingTokenOperator { using SafeERC20 for IERC20; function _mintBookingToken( @@ -16,14 +16,14 @@ abstract contract BookingTokenOperator { uint256 expirationTimestamp, uint256 price, IERC20 paymentToken - ) internal virtual { + ) public { IBookingToken(bookingToken).safeMintWithReservation(reservedFor, uri, expirationTimestamp, price, paymentToken); } /** * @dev Buy a booking token with the specified price */ - function _buyBookingToken(address bookingToken, uint256 tokenId) internal virtual { + function _buyBookingToken(address bookingToken, uint256 tokenId) public { // Get the price from the booking token contract (uint256 price, IERC20 paymentToken) = IBookingToken(bookingToken).getReservationPrice(tokenId); @@ -48,18 +48,18 @@ abstract contract BookingTokenOperator { * * This function should be overridden by the implementation */ - function mintBookingToken( - address reservedFor, - string memory uri, - uint256 expirationTimestamp, - uint256 price, - IERC20 paymentToken - ) external virtual; + // function mintBookingToken( + // address reservedFor, + // string memory uri, + // uint256 expirationTimestamp, + // uint256 price, + // IERC20 paymentToken + // ) external; /** * @dev Buy a booking token * * This function should be overridden by the implementation */ - function buyBookingToken(uint256 tokenId) external virtual; + //function buyBookingToken(uint256 tokenId) external virtual; } diff --git a/test/CMAccount.test.js b/test/CMAccount.test.js index 551f3a6..ea6f504 100644 --- a/test/CMAccount.test.js +++ b/test/CMAccount.test.js @@ -26,7 +26,11 @@ describe("CMAccount", function () { const oldImplementationAddress = await cmAccountManager.getAccountImplementation(); // Create a new implementation for CMAccount - const CMAccountImplV2 = await ethers.getContractFactory("CMAccount"); + const BookingTokenOperator = await ethers.getContractFactory("BookingTokenOperator"); + const bookingTokenOperator = await BookingTokenOperator.deploy(); + const CMAccountImplV2 = await ethers.getContractFactory("CMAccount", { + libraries: { BookingTokenOperator: await bookingTokenOperator.getAddress() }, + }); const cmAccountImplV2 = await CMAccountImplV2.deploy(); await cmAccountImplV2.waitForDeployment(); const newImplementationAddress = await cmAccountImplV2.getAddress(); @@ -48,7 +52,11 @@ describe("CMAccount", function () { const oldImplementationAddress = await cmAccountManager.getAccountImplementation(); // Create a new implementation for CMAccount - const CMAccountImplV2 = await ethers.getContractFactory("CMAccount"); + const BookingTokenOperator = await ethers.getContractFactory("BookingTokenOperator"); + const bookingTokenOperator = await BookingTokenOperator.deploy(); + const CMAccountImplV2 = await ethers.getContractFactory("CMAccount", { + libraries: { BookingTokenOperator: await bookingTokenOperator.getAddress() }, + }); const cmAccountImplV2 = await CMAccountImplV2.deploy(); await cmAccountImplV2.waitForDeployment(); const newImplementationAddress = await cmAccountImplV2.getAddress(); @@ -235,7 +243,7 @@ describe("CMAccount", function () { const bot = signers.otherAccount1; // Register bot - await expect(cmAccount.connect(signers.cmAccountAdmin).addMessengerBot(bot.address)) + await expect(cmAccount.connect(signers.cmAccountAdmin).addMessengerBot(bot.address, 0n)) .to.emit(cmAccount, "MessengerBotAdded") .withArgs(bot.address); @@ -254,7 +262,7 @@ describe("CMAccount", function () { const bot = signers.otherAccount1; // Register bot - await expect(cmAccount.connect(signers.cmAccountAdmin).addMessengerBot(bot.address)) + await expect(cmAccount.connect(signers.cmAccountAdmin).addMessengerBot(bot.address, 0n)) .to.emit(cmAccount, "MessengerBotAdded") .withArgs(bot.address); diff --git a/test/GasMoneyManager.test.js b/test/GasMoneyManager.test.js index 43b9b1d..95ae1b7 100644 --- a/test/GasMoneyManager.test.js +++ b/test/GasMoneyManager.test.js @@ -58,7 +58,7 @@ describe("GasMoneyManager", function () { const withdrawer = signers.withdrawer; // Register withdrawer as a bot - await expect(cmAccount.connect(signers.cmAccountAdmin).addMessengerBot(withdrawer.address)) + await expect(cmAccount.connect(signers.cmAccountAdmin).addMessengerBot(withdrawer.address, 0n)) .to.emit(cmAccount, "MessengerBotAdded") .withArgs(withdrawer.address); @@ -94,7 +94,7 @@ describe("GasMoneyManager", function () { const expectedLimit = ethers.parseEther("10"); // 10 CAM // Register withdrawer as a bot - await expect(cmAccount.connect(signers.cmAccountAdmin).addMessengerBot(withdrawer.address)) + await expect(cmAccount.connect(signers.cmAccountAdmin).addMessengerBot(withdrawer.address, 0n)) .to.emit(cmAccount, "MessengerBotAdded") .withArgs(withdrawer.address); @@ -113,7 +113,7 @@ describe("GasMoneyManager", function () { const expectedLimit = ethers.parseEther("10"); // 10 CAM // Register withdrawer as a bot - await expect(cmAccount.connect(signers.cmAccountAdmin).addMessengerBot(withdrawer.address)) + await expect(cmAccount.connect(signers.cmAccountAdmin).addMessengerBot(withdrawer.address, 0n)) .to.emit(cmAccount, "MessengerBotAdded") .withArgs(withdrawer.address); @@ -154,7 +154,7 @@ describe("GasMoneyManager", function () { const expectedLimit = ethers.parseEther("10"); // 10 CAM // Register withdrawer as a bot - await expect(cmAccount.connect(signers.cmAccountAdmin).addMessengerBot(withdrawer.address)) + await expect(cmAccount.connect(signers.cmAccountAdmin).addMessengerBot(withdrawer.address, 0n)) .to.emit(cmAccount, "MessengerBotAdded") .withArgs(withdrawer.address); diff --git a/test/utils/fixtures.js b/test/utils/fixtures.js index 0d4f646..d8f4cf2 100644 --- a/test/utils/fixtures.js +++ b/test/utils/fixtures.js @@ -73,7 +73,11 @@ async function deployCMAccountManagerFixture() { } async function deployCMAccountImplFixture() { - const CMAccount = await ethers.getContractFactory("CMAccount"); + const BookingTokenOperator = await ethers.getContractFactory("BookingTokenOperator"); + const bookingTokenOperator = await BookingTokenOperator.deploy(); + const CMAccount = await ethers.getContractFactory("CMAccount", { + libraries: { BookingTokenOperator: await bookingTokenOperator.getAddress() }, + }); const cmAccountImpl = await CMAccount.deploy(); await cmAccountImpl.waitForDeployment(); @@ -110,6 +114,7 @@ async function deployAndConfigureAllFixture() { await cmAccountManager.grantRole(await cmAccountManager.FEE_ADMIN_ROLE(), signers.feeAdmin.address); // Deploy BookingToken + const BookingToken = await ethers.getContractFactory("BookingToken"); const bookingToken = await upgrades.deployProxy( BookingToken,