diff --git a/.gitmodules b/.gitmodules index c73698ab..553c5da7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "lib/prb-math"] path = lib/prb-math url = https://github.com/PaulRBerg/prb-math +[submodule "lib/fvm-solidity"] + path = lib/fvm-solidity + url = https://github.com/filecoin-project/fvm-solidity diff --git a/CHANGELOG.md b/CHANGELOG.md index dfcf0be6..0612cc13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,15 +4,33 @@ All notable changes to this project will be documented in this file. The format ## [Unreleased] +### Added + +### Changed + +### Fixed + +## [0.6.0-rc1] - Filecoin-Pay M3 rc1 + +### Deployed +- **Calibration**: [0xc77336Af9853817729F52fE5C3d465C18e87b9E0](https://calibration.filfox.info/en/address/0xc77336Af9853817729F52fE5C3d465C18e87b9E0) +- **Mainnet**: [0xCe03746C078d99C38C4993f6d7322f6fcd3F5C45](https://filfox.info/en/address/0xCe03746C078d99C38C4993f6d7322f6fcd3F5C45) + ### Added - Support for ERC-3009 (Transfer with authorization) ([#214](https://github.com/FilOzone/filecoin-pay/pull/214)) - Support for relayers to submit deposit transactions ([#217](https://github.com/FilOzone/filecoin-pay/pull/217)) - Network fee charging in settlement operations ([#224](https://github.com/FilOzone/filecoin-pay/pull/224)) - IERC20 type improvements and label mapping keys ([#225](https://github.com/FilOzone/filecoin-pay/pull/225)) +- Fee auction functionality ([#229](https://github.com/FilOzone/filecoin-pay/pull/229)) +- Pagination support for `_getRailsForAddressAndToken` ([#237](https://github.com/FilOzone/filecoin-pay/pull/237)) ### Changed +- Restored settlement permissions allowing any participant to settle rails ([#221](https://github.com/FilOzone/filecoin-pay/pull/221)) ### Fixed +- Network fee handling in `settleTerminatedRailWithoutValidation` ([#223](https://github.com/FilOzone/filecoin-pay/pull/223)) +- CI workflow issue with npm dependencies in publish-abis workflow ([#236](https://github.com/FilOzone/filecoin-pay/pull/236)) +- Add completed security audit report to readme ([#231](https://github.com/FilOzone/filecoin-pay/pull/231)) ## [0.5.0] - Filecoin-Pay Developer Preview @@ -34,7 +52,6 @@ upcoming breaking changes. - Settlement operations now accessible by any participant (payer, payee, or operator) ([#219](https://github.com/FilOzone/filecoin-pay/pull/219), [#220](https://github.com/FilOzone/filecoin-pay/pull/220)) ### Fixed -- Network fee handling in `settleTerminatedRailWithoutValidation` ([#223](https://github.com/FilOzone/filecoin-pay/pull/223)) - Settlement permission logic corrections ([#220](https://github.com/FilOzone/filecoin-pay/pull/220)) ## [0.2.0] - Mainnet Alpha diff --git a/lib/fvm-solidity b/lib/fvm-solidity new file mode 160000 index 00000000..346eccf2 --- /dev/null +++ b/lib/fvm-solidity @@ -0,0 +1 @@ +Subproject commit 346eccf2f4daf5ad2aaab3d576f5c5d8955199f7 diff --git a/src/Payments.sol b/src/Payments.sol index 34302b35..5daed6cc 100644 --- a/src/Payments.sol +++ b/src/Payments.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 OR MIT pragma solidity ^0.8.27; +import {BURN_ADDRESS} from "fvm-solidity/FVMActors.sol"; +import {FVMPay} from "fvm-solidity/FVMPay.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; @@ -15,7 +17,7 @@ uint88 constant UINT88_MAX = 0xffffffffffffffffffffff; // FIL max supply cap is 2 billion uint88 constant MAX_AUCTION_START_PRICE = UINT88_MAX; // 309,485,009.821345068724781055 FIL -uint88 constant FIRST_AUCTION_START_PRICE = 31.32 ether; // 31.32 FIL +uint88 constant FIRST_AUCTION_START_PRICE = 0.5 ether; // 0.5 FIL interface IValidator { struct ValidationResult { @@ -52,7 +54,6 @@ contract Payments is ReentrancyGuard { uint256 public constant NETWORK_FEE_NUMERATOR = 1; // 0.5% uint256 public constant NETWORK_FEE_DENOMINATOR = 200; - address payable private constant BURN_ADDRESS = payable(0xff00000000000000000000000000000000000063); IERC20 private constant NATIVE_TOKEN = IERC20(address(0)); // Events @@ -774,8 +775,7 @@ contract Payments is ReentrancyGuard { uint256 available = account.funds - account.lockupCurrent; require(amount <= available, Errors.InsufficientUnlockedFunds(available, amount)); if (token == NATIVE_TOKEN) { - (bool success,) = payable(to).call{value: amount}(""); - require(success, Errors.NativeTransferFailed(to, amount)); + require(FVMPay.pay(to, amount), Errors.NativeTransferFailed(to, amount)); } else { uint256 actual = transferOut(token, to, amount); if (amount != actual) { @@ -1086,8 +1086,7 @@ contract Payments is ReentrancyGuard { // ceil() fee = (amount * NETWORK_FEE_NUMERATOR + (NETWORK_FEE_DENOMINATOR - 1)) / NETWORK_FEE_DENOMINATOR; if (token == NATIVE_TOKEN) { - (bool success,) = BURN_ADDRESS.call{value: fee}(""); - require(success, Errors.NativeTransferFailed(BURN_ADDRESS, msg.value)); + require(FVMPay.burn(fee), Errors.NativeTransferFailed(BURN_ADDRESS, fee)); } else { accounts[token][address(this)].funds += fee; // start fee auction if necessary @@ -1821,8 +1820,7 @@ contract Payments is ReentrancyGuard { auction.startPrice = uint88(auctionPrice); auction.startTime = uint168(block.timestamp); - (bool success,) = BURN_ADDRESS.call{value: msg.value}(""); - require(success, Errors.NativeTransferFailed(BURN_ADDRESS, msg.value)); + require(FVMPay.burn(msg.value), Errors.NativeTransferFailed(BURN_ADDRESS, msg.value)); uint256 actual = transferOut(token, recipient, requested); fees.funds = available - actual; diff --git a/test/AccountManagement.t.sol b/test/AccountManagement.t.sol index ca901aa2..6863bd8f 100644 --- a/test/AccountManagement.t.sol +++ b/test/AccountManagement.t.sol @@ -1,14 +1,15 @@ // SPDX-License-Identifier: Apache-2.0 OR MIT pragma solidity ^0.8.27; -import {Test} from "forge-std/Test.sol"; +import {MockFVMTest} from "fvm-solidity/mocks/MockFVMTest.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + import {Payments} from "../src/Payments.sol"; import {PaymentsTestHelpers} from "./helpers/PaymentsTestHelpers.sol"; import {BaseTestHelper} from "./helpers/BaseTestHelper.sol"; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {Errors} from "../src/Errors.sol"; -contract AccountManagementTest is Test, BaseTestHelper { +contract AccountManagementTest is MockFVMTest, BaseTestHelper { PaymentsTestHelpers helper; Payments payments; @@ -18,7 +19,8 @@ contract AccountManagementTest is Test, BaseTestHelper { IERC20 private constant NATIVE_TOKEN = IERC20(address(0)); - function setUp() public { + function setUp() public override { + super.setUp(); // Create test helpers and setup environment helper = new PaymentsTestHelpers(); helper.setupStandardTestEnvironment(); diff --git a/test/Burn.t.sol b/test/Burn.t.sol index ee7fac7b..5ca158cf 100644 --- a/test/Burn.t.sol +++ b/test/Burn.t.sol @@ -2,14 +2,15 @@ pragma solidity ^0.8.27; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {Test} from "forge-std/Test.sol"; +import {MockFVMTest} from "fvm-solidity/mocks/MockFVMTest.sol"; +import {BURN_ADDRESS} from "fvm-solidity/FVMActors.sol"; import {Dutch} from "../src/Dutch.sol"; import {Errors} from "../src/Errors.sol"; import {FIRST_AUCTION_START_PRICE, MAX_AUCTION_START_PRICE, Payments} from "../src/Payments.sol"; import {PaymentsTestHelpers} from "./helpers/PaymentsTestHelpers.sol"; -contract BurnTest is Test { +contract BurnTest is MockFVMTest { using Dutch for uint256; PaymentsTestHelpers helper = new PaymentsTestHelpers(); @@ -17,8 +18,6 @@ contract BurnTest is Test { uint256 testTokenRailId; uint256 nativeTokenRailId; - address payable private constant BURN_ADDRESS = payable(0xff00000000000000000000000000000000000063); - IERC20 private testToken; IERC20 private constant NATIVE_TOKEN = IERC20(address(0)); address private payer; @@ -26,7 +25,10 @@ contract BurnTest is Test { address private operator; address private recipient; - function setUp() public { + function setUp() public override { + // Mock the FVM precompiles + super.setUp(); + helper.setupStandardTestEnvironment(); payments = helper.payments(); diff --git a/test/BurnExtraFeeToken.t.sol b/test/BurnExtraFeeToken.t.sol index 6249f0cd..7525b834 100644 --- a/test/BurnExtraFeeToken.t.sol +++ b/test/BurnExtraFeeToken.t.sol @@ -1,25 +1,29 @@ // SPDX-License-Identifier: Apache-2.0 OR MIT pragma solidity ^0.8.27; +import {MockFVMTest} from "fvm-solidity/mocks/MockFVMTest.sol"; +import {BURN_ADDRESS} from "fvm-solidity/FVMActors.sol"; + import {PaymentsTestHelpers} from "./helpers/PaymentsTestHelpers.sol"; import {ExtraFeeToken} from "./mocks/ExtraFeeToken.sol"; import {FIRST_AUCTION_START_PRICE, Payments} from "../src/Payments.sol"; -import {Test} from "forge-std/Test.sol"; -contract BurnFeeOnTransferTokenTest is Test { +contract BurnFeeOnTransferTokenTest is MockFVMTest { PaymentsTestHelpers helper = new PaymentsTestHelpers(); Payments payments; ExtraFeeToken feeToken; uint256 railId; - address payable private constant BURN_ADDRESS = payable(0xff00000000000000000000000000000000000063); address operator; address payer; address payee; address recipient; - function setUp() public { + function setUp() public override { + // Mock the FVM precompiles + super.setUp(); + helper.setupStandardTestEnvironment(); payments = helper.payments(); operator = helper.OPERATOR(); diff --git a/test/BurnFeeOnTransferToken.t.sol b/test/BurnFeeOnTransferToken.t.sol index 5618423c..3674c4f1 100644 --- a/test/BurnFeeOnTransferToken.t.sol +++ b/test/BurnFeeOnTransferToken.t.sol @@ -1,25 +1,29 @@ // SPDX-License-Identifier: Apache-2.0 OR MIT pragma solidity ^0.8.27; +import {MockFVMTest} from "fvm-solidity/mocks/MockFVMTest.sol"; +import {BURN_ADDRESS} from "fvm-solidity/FVMActors.sol"; + import {PaymentsTestHelpers} from "./helpers/PaymentsTestHelpers.sol"; import {MockFeeOnTransferTokenWithPermit} from "./mocks/MockFeeOnTransferTokenWithPermit.sol"; import {FIRST_AUCTION_START_PRICE, Payments} from "../src/Payments.sol"; -import {Test} from "forge-std/Test.sol"; -contract BurnFeeOnTransferTokenTest is Test { +contract BurnFeeOnTransferTokenTest is MockFVMTest { PaymentsTestHelpers helper = new PaymentsTestHelpers(); Payments payments; MockFeeOnTransferTokenWithPermit feeToken; uint256 railId; - address payable private constant BURN_ADDRESS = payable(0xff00000000000000000000000000000000000063); address operator; address payer; address payee; address recipient; - function setUp() public { + function setUp() public override { + // Mock the FVM precompiles + super.setUp(); + helper.setupStandardTestEnvironment(); payments = helper.payments(); operator = helper.OPERATOR();