diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 762a296..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: CI - -on: - push: - pull_request: - workflow_dispatch: - -env: - FOUNDRY_PROFILE: ci - -jobs: - check: - strategy: - fail-fast: true - - name: Foundry project - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - - name: Show Forge version - run: | - forge --version - - - name: Run Forge fmt - run: | - forge fmt --check - id: fmt - - - name: Run Forge build - run: | - forge build --sizes - id: build - - - name: Run Forge tests - run: | - forge test -vvv - id: test diff --git a/addresses.json b/addresses.json index 2020e28..754f8e1 100644 --- a/addresses.json +++ b/addresses.json @@ -1,3 +1,6 @@ { - "BNBTestnet": "0x35a8483444947B2166Aa85837F97FaEf122f5ebb" + "BNBTestnet": { + "AccessTokenFactory": "0x35a8483444947B2166Aa85837F97FaEf122f5ebb", + "Marketplace": "0x647d77324E241709BaF63D7f96F0C19ecA06E2e0" + } } \ No newline at end of file diff --git a/script/AccessControl.s.sol b/script/AccessControl.s.sol new file mode 100644 index 0000000..588a054 --- /dev/null +++ b/script/AccessControl.s.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {AccessTokenFactory} from "../contracts/AccessTokenFactory.sol"; +import {AccessToken} from "../contracts/AccessToken.sol"; +import {Marketplace} from "../contracts/Marketplace.sol"; +import {IMarketplaceStructs} from "../contracts/interfaces/IMarketplaceStructs.sol"; +import "forge-std/src/Script.sol"; + +contract Rent is Script { + uint256 deployerPrivateKey; + Marketplace marketplace; + IProductFactory productFactory; + AccessTokenFactory accessTokenFactory; + address device; + IProductFactory.DeviceBinding deviceBinding; + AccessToken accessToken; + address user; + + function setUp() public { + deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + marketplace = Marketplace(0x647d77324E241709BaF63D7f96F0C19ecA06E2e0); + productFactory = IProductFactory(0x8E360F40c7875e096e0DbFe0cC01d1db5aFB78B6); + accessTokenFactory = AccessTokenFactory(0x35a8483444947B2166Aa85837F97FaEf122f5ebb); + device = 0xA7fE098F2D4D2cD6bA158E5470d9231AC223bA06; // set device here + user = 0xD0167B1cc6CAb1e4e7C6f38d09EA35171d00b68e; // set user device here + deviceBinding = productFactory.getDeviceBinding(device); + accessToken = AccessToken(accessTokenFactory.getAccessToken(deviceBinding.product)); + } + + function run() public view { + bool accessible = accessToken.isUserOwned(vm.addr(deployerPrivateKey), deviceBinding.tokenId); + console.log("accessible:", accessible); + } +} + +interface IProductFactory { + struct DeviceBinding { + address product; + uint256 tokenId; + } + + /** + * @notice Returns the product address and token ID for a device. + * @param device Address of the device. + * @return DevieInfo Product address and Token ID associated with the device. + */ + function getDeviceBinding( + address device + ) external view returns (DeviceBinding memory); +} diff --git a/script/CreateAccessToken.s.sol b/script/CreateAccessToken.s.sol new file mode 100644 index 0000000..11d52e8 --- /dev/null +++ b/script/CreateAccessToken.s.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {AccessTokenFactory} from "../contracts/AccessTokenFactory.sol"; +import "forge-std/src/Script.sol"; + +contract CreateAccessToken is Script { + uint256 deployerPrivateKey; + AccessTokenFactory accessTokenFactory; + IProductFactory productFactory; + address device; + + function setUp() public { + deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + accessTokenFactory = AccessTokenFactory(0x35a8483444947B2166Aa85837F97FaEf122f5ebb); + productFactory = IProductFactory(0x8E360F40c7875e096e0DbFe0cC01d1db5aFB78B6); + device = 0xA7fE098F2D4D2cD6bA158E5470d9231AC223bA06; // set your device here + } + + function run() public returns (address) { + IProductFactory.DeviceBinding memory deviceBinding = productFactory.getDeviceBinding(device); + vm.startBroadcast(deployerPrivateKey); + address accessToken = accessTokenFactory.createAccessToken(deviceBinding.product); + console.log("AccessToken:", accessToken); + vm.stopBroadcast(); + return address(accessTokenFactory); + } +} + +interface IProductFactory { + struct DeviceBinding { + address product; + uint256 tokenId; + } + + /** + * @notice Returns the product address and token ID for a device. + * @param device Address of the device. + * @return DevieInfo Product address and Token ID associated with the device. + */ + function getDeviceBinding( + address device + ) external view returns (DeviceBinding memory); +} diff --git a/script/DeployMarketplace.s.sol b/script/DeployMarketplace.s.sol new file mode 100644 index 0000000..87b0d92 --- /dev/null +++ b/script/DeployMarketplace.s.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {Marketplace} from "../contracts/Marketplace.sol"; +import "forge-std/src/Script.sol"; + +contract DeployMarketplace is Script { + uint256 deployerPrivateKey; + address accessTokenFactory; + address[] rentCurrencies; + address treasury; + uint256 feePoints; + + function setUp() public { + deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + accessTokenFactory = 0x35a8483444947B2166Aa85837F97FaEf122f5ebb; + treasury = 0x3F3786B67DC1874C3Bd8e8CD61F5eea87604470F; + feePoints = 100; // 100/10000 = 10% + } + + function run() public returns (address) { + vm.startBroadcast(deployerPrivateKey); + Marketplace martketplace = new Marketplace( + vm.addr(deployerPrivateKey), + accessTokenFactory, + rentCurrencies, + payable(treasury), + feePoints + ); + vm.stopBroadcast(); + return address(martketplace); + } +} diff --git a/script/List.s.sol b/script/List.s.sol new file mode 100644 index 0000000..67a516d --- /dev/null +++ b/script/List.s.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {Marketplace} from "../contracts/Marketplace.sol"; +import {IMarketplaceStructs} from "../contracts/interfaces/IMarketplaceStructs.sol"; +import {IProduct} from "../contracts/interfaces/IProduct.sol"; +import "forge-std/src/Script.sol"; + +contract List is Script { + uint256 deployerPrivateKey; + Marketplace marketplace; + IProductFactory productFactory; + address device; + IProductFactory.DeviceBinding deviceBinding; + IMarketplaceStructs.ListArgs listArgs; + + function setUp() public { + deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + marketplace = Marketplace(0x647d77324E241709BaF63D7f96F0C19ecA06E2e0); + productFactory = IProductFactory(0x8E360F40c7875e096e0DbFe0cC01d1db5aFB78B6); + device = 0xA7fE098F2D4D2cD6bA158E5470d9231AC223bA06; // set your device here + deviceBinding = productFactory.getDeviceBinding(device); + listArgs = IMarketplaceStructs.ListArgs({ + product: deviceBinding.product, + tokenId: deviceBinding.tokenId, + minRentalDays: 5, // set min rental days + maxRentalDays: 10, // set max rental days + rentCurrency: address(0), // only whitelisted currency, zero-address means bnb(native token) + dailyRent: 1e14, // set daily rent, here is 0.0001 BNB per day + rentRecipient: vm.addr(deployerPrivateKey) // set rent receiver + }); + } + + function run() public { + vm.startBroadcast(deployerPrivateKey); + IProduct(deviceBinding.product).approve(address(marketplace), deviceBinding.tokenId); + marketplace.list(listArgs); + vm.stopBroadcast(); + } +} + +interface IProductFactory { + struct DeviceBinding { + address product; + uint256 tokenId; + } + + /** + * @notice Returns the product address and token ID for a device. + * @param device Address of the device. + * @return DevieInfo Product address and Token ID associated with the device. + */ + function getDeviceBinding( + address device + ) external view returns (DeviceBinding memory); +} diff --git a/script/Rent.s.sol b/script/Rent.s.sol new file mode 100644 index 0000000..9fa6753 --- /dev/null +++ b/script/Rent.s.sol @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {AccessTokenFactory} from "../contracts/AccessTokenFactory.sol"; +import {AccessToken} from "../contracts/AccessToken.sol"; +import {Marketplace} from "../contracts/Marketplace.sol"; +import {IMarketplaceStructs} from "../contracts/interfaces/IMarketplaceStructs.sol"; +import "forge-std/src/Script.sol"; + +contract Rent is Script { + uint256 deployerPrivateKey; + Marketplace marketplace; + IProductFactory productFactory; + AccessTokenFactory accessTokenFactory; + address device; + IProductFactory.DeviceBinding deviceBinding; + AccessToken accessToken; + IMarketplaceStructs.ListingInfo listingInfo; + IMarketplaceStructs.RentArgs rentArgs; + + function setUp() public { + deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + marketplace = Marketplace(0x647d77324E241709BaF63D7f96F0C19ecA06E2e0); + productFactory = IProductFactory(0x8E360F40c7875e096e0DbFe0cC01d1db5aFB78B6); + accessTokenFactory = AccessTokenFactory(0x35a8483444947B2166Aa85837F97FaEf122f5ebb); + device = 0xA7fE098F2D4D2cD6bA158E5470d9231AC223bA06; // set your device here + deviceBinding = productFactory.getDeviceBinding(device); + accessToken = AccessToken(accessTokenFactory.getAccessToken(deviceBinding.product)); + listingInfo = marketplace.getListingInfo(address(accessToken), deviceBinding.tokenId); + rentArgs = IMarketplaceStructs.RentArgs({ + accessToken: address(accessToken), + tokenId: deviceBinding.tokenId, + tenant: vm.addr(deployerPrivateKey), // set tenant address, default is caller + rentalDays: 5, // set rental days, min value is min rental days set by device owner + prepaidRent: 5 * listingInfo.dailyRent // set prepaid rent, min value is rentalDays * dailyRent set by device owner + }); + } + + function run() public { + vm.startBroadcast(deployerPrivateKey); + if(listingInfo.rentCurrency == marketplace.NATIVE_TOKEN()) { + marketplace.rent{value: rentArgs.prepaidRent}(rentArgs); + } else { + marketplace.rent(rentArgs); + } + require(accessToken.isUserOwned(vm.addr(deployerPrivateKey), deviceBinding.tokenId)); + vm.stopBroadcast(); + } +} + +interface IProductFactory { + struct DeviceBinding { + address product; + uint256 tokenId; + } + + /** + * @notice Returns the product address and token ID for a device. + * @param device Address of the device. + * @return DevieInfo Product address and Token ID associated with the device. + */ + function getDeviceBinding( + address device + ) external view returns (DeviceBinding memory); +}