Skip to content

fix(b20): make SEIZE_HOLDER_POLICY inclusive (authorized = seizable) - #206

Open
rayyan224 wants to merge 1 commit into
mainfrom
fix/seize-holder-inclusive-auth
Open

fix(b20): make SEIZE_HOLDER_POLICY inclusive (authorized = seizable)#206
rayyan224 wants to merge 1 commit into
mainfrom
fix/seize-holder-inclusive-auth

Conversation

@rayyan224

Copy link
Copy Markdown
Collaborator

Summary

  • Flip SEIZE_HOLDER_POLICY from inverted/blocklist semantics to inclusive allowlist semantics: an account is seizable when isAuthorized(...) is true.
  • Update the MockB20 gate, IB20 NatSpec, unit/revert-order tests, seize smoke journey, and Cobalt seize changelog/CHANGELOG guidance.
  • Unset holder policy remains ALWAYS_ALLOW, so every account is seizable until the issuer configures a restricted set.

Test plan

  • forge test --match-contract B20SeizeWithMemo -v
  • forge test -v
  • forge fmt --check
  • python3 script/check-coverage.py
  • base-forge test --match-contract B20SeizeWithMemo once the matching Rust precompile flip lands in base/base
  • make smoke-seize on a Cobalt-capable chain (optional)

Made with Cursor

Align seize-holder membership with the standard allowlist pattern used by
mint/seize receiver policies. An account is seizable when authorized under
SEIZE_HOLDER_POLICY; unset defaults to always-allow.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown

Interface Coverage

✅ All interface functions have test coverage.

@github-actions

Copy link
Copy Markdown

📊 Forge Coverage (src/lib/)

🟡 ≥95% across all metrics — some metrics below 99%.

File Lines Stmts Branches Funcs
🟡 B20FactoryLib.sol 97.70% 98.00% 100.00% 95.00%
🔴 test/lib/ForceFeeder.sol 0.00% 0.00% 100.00% 0.00%
🔴 test/lib/PrecompileProbe.sol 0.00% 0.00% 0.00% 0.00%
🟢 MockActivationRegistry.sol 100.00% 100.00% 100.00% 100.00%
🟢 MockActivationRegistryStorage.sol 100.00% 100.00% 100.00% 100.00%
🟢 MockB20.sol 100.00% 100.00% 100.00% 100.00%
🟢 MockB20Asset.sol 100.00% 100.00% 100.00% 100.00%
🟡 MockB20Factory.sol 98.96% 99.10% 100.00% 100.00%
🟢 MockB20Stablecoin.sol 100.00% 100.00% 100.00% 100.00%
🟢 MockB20Storage.sol 100.00% 100.00% 100.00% 100.00%
🟡 MockPolicyRegistry.sol 100.00% 99.54% 97.67% 100.00%
🟢 MockPolicyRegistryStorage.sol 100.00% 100.00% 100.00% 100.00%
Total 97.07% 97.52% 98.16% 97.00%

Full report: download artifact. To browse locally: make coverage (runs forge coverage + genhtml + opens the HTML report).

@github-actions

Copy link
Copy Markdown

⚠️ Fork tests: 26 failed, 709 passed

These failures indicate divergences where base/base needs to catch up to the base-std spec. This check is advisory and does not block merging.

Failing tests
  • test_seizeWithMemo_revertOrder_holder_beats_balance(address,address): Error != expected error: InsufficientBalance(0x14f3Dcd0d1e32270fE876511813A4461C0618a35, 0, 1) != AccountNotSeizable(0x14f3Dcd0d1e32270fE876511813A4461C0618a35); counterexample: calldata=0x239099f700000000000000000000000014f3dcd0d1e32270fe876511813a4461c0618a3500000000000000000000000037b59163ee31b1c3b3db2a4d4bc7b8439f8f8ba5 args=[0x14f3Dcd0d1e32270fE876511813A4461C0618a35, 0x37B59163EE31b1c3B3dB2a4d4BC7B8439f8f8Ba5]
  • test_seizeWithMemo_revertOrder_holder_beats_receiver(address,address): Error != expected error: PolicyForbids(0xbf15b19caf5c77422c038bc25f26b8b815c3a14f6d04c6616076b81bcfe07b3d, 72057594037927937 [7.205e16]) != AccountNotSeizable(0x5aA6fa23104d1e45D820b7542a7775d63f076D9A); counterexample: calldata=0xa570c5880000000000000000000000005aa6fa23104d1e45d820b7542a7775d63f076d9a000000000000000000000000ea890fdb8e384943c2b1e620af296373457aca8f args=[0x5aA6fa23104d1e45D820b7542a7775d63f076D9A, 0xEA890fdb8E384943c2b1E620aF296373457ACa8F]
  • test_seizeWithMemo_revertOrder_receiver_beats_balance(address,address): Error != expected error: AccountNotSeizable(0xB695F4268d379E7601221B6BF0C25213067a44fB) != PolicyForbids(0xbf15b19caf5c77422c038bc25f26b8b815c3a14f6d04c6616076b81bcfe07b3d, 72057594037927937 [7.205e16]); counterexample: calldata=0xc375ac63000000000000000000000000b695f4268d379e7601221b6bf0c25213067a44fb000000000000000000000000a04a899f2a6a0b3a634461c47e4d38a038aa1434 args=[0xB695F4268d379E7601221B6BF0C25213067a44fB, 0xa04A899f2a6a0B3A634461c47E4d38a038aA1434]
  • test_seizeWithMemo_revert_accountNotSeizable(address,address,uint256): Error != expected error: InsufficientBalance(0x0dc57040B0B3f86E4b7eEE104A702D34e2564778, 0, 9211737475 [9.211e9]) != AccountNotSeizable(0x0dc57040B0B3f86E4b7eEE104A702D34e2564778); counterexample: calldata=0xd8381c0c0000000000000000000000000dc57040b0b3f86e4b7eee104a702d34e25647780000000000000000000000008cc36a524dd7b24dac9579fe3efe3b917b34923600000000000000000000000000000000000000000000000000000002250ff583 args=[0x0dc57040B0B3f86E4b7eEE104A702D34e2564778, 0x8CC36A524dd7b24DAc9579FE3EFe3B917b349236, 9211737475 [9.211e9]]
  • test_seizeWithMemo_revert_insufficientBalance(address,address,uint256): Error != expected error: AccountNotSeizable(0xead48f9a8377efd333fd4754B2CDA9E6239b6593) != InsufficientBalance(0xead48f9a8377efd333fd4754B2CDA9E6239b6593, 0, 76605409514530667519101271899697465240832406532 [7.66e46]); counterexample: calldata=0x033c5005000000000000000000000000ead48f9a8377efd333fd4754b2cda9e6239b65930000000000000000000000006196c01b58e63e126796d81c42dfb9263926ec0b0000000000000000000000000d6b1af9512025ce3f6bb21cb08388300f8b7404 args=[0xead48f9a8377efd333fd4754B2CDA9E6239b6593, 0x6196C01B58E63E126796d81C42dfB9263926eC0B, 76605409514530667519101271899697465240832406532 [7.66e46]]
  • test_seizeWithMemo_revert_receiverPolicyForbids(address,address,uint256): Error != expected error: AccountNotSeizable(0x5D10811583Ae5B7172c9A491eB4f1c2a9f809Eb3) != PolicyForbids(0xbf15b19caf5c77422c038bc25f26b8b815c3a14f6d04c6616076b81bcfe07b3d, 72057594037927937 [7.205e16]); counterexample: calldata=0x05a3631f0000000000000000000000005d10811583ae5b7172c9a491eb4f1c2a9f809eb300000000000000000000000008b4e1c57f91cc32f04dc88568f069bf9caa8e950000e7ce8dafa1d7ed78db1ce53ad16011784f80e03f836f77d106e64ddac076 args=[0x5D10811583Ae5B7172c9A491eB4f1c2a9f809Eb3, 0x08B4E1C57f91cC32f04Dc88568f069Bf9Caa8E95, 1599872076406075340858811709198655886732898121620871075970011782790692982 [1.599e72]]
  • test_seizeWithMemo_success_configuredReceiverPolicyAllows(address,address,uint256): AccountNotSeizable(0x9A78F461AB2beB360A4e91D277Bd57F9666D54e4); counterexample: calldata=0xd1038b0d0000000000000000000000009a78f461ab2beb360a4e91d277bd57f9666d54e4000000000000000000000000651d68e12a450b72c60845bcd9ba70c355f96e46000000000000000000000000000000000006bb1869d2f9e57db54044f68e7042 args=[0x9A78F461AB2beB360A4e91D277Bd57F9666D54e4, 0x651d68e12A450b72c60845bCd9bA70c355F96E46, 34948525973972726461712013420556354 [3.494e34]]
  • test_seizeWithMemo_success_emitsEvents(address,address,uint256,bytes32): log != expected log; counterexample: calldata=0x984936cb000000000000000000000000cb2ab65d841084b4bfb7bf3ea10cbf4534ea82d3000000000000000000000000a90a09e6946fa5f5d2a1a91f4f5bf75bf88028f900001a4a48c0461ce10110d5231e59673a9a404b64b9837851e3ad7adf268a96e8da7a44e014085929c6bd1d2b7c2763eaa4c55a524886957313d02ca691c11a args=[0xcB2AB65D841084B4bfB7bF3eA10CbF4534Ea82D3, 0xa90A09e6946Fa5f5d2A1a91f4f5bF75BF88028F9, 181448102651809632386187330972235309614657566930696327210147616123161238 [1.814e71], 0xe8da7a44e014085929c6bd1d2b7c2763eaa4c55a524886957313d02ca691c11a]
  • test_seizeWithMemo_success_ignoresReceiverPolicy(address,address,uint256): AccountNotSeizable(0x17A1670Db394b06C30c71ea1A406edE90774eE7D); counterexample: calldata=0x6358be6c00000000000000000000000017a1670db394b06c30c71ea1a406ede90774ee7d000000000000000000000000ac2ef2bd0f42125df02d2b3ca068c64c36ec0ce200000029a9e760f9b83a450db3c789155eb9c411f8bb009744cfd809004cd552 args=[0x17A1670Db394b06C30c71ea1A406edE90774eE7D, 0xAc2Ef2bd0f42125DF02d2b3cA068c64c36EC0ce2, 1123250774366915524761215794822526675754073590367425349216885569017170 [1.123e69]]
  • test_seizeWithMemo_success_movesBalance(address,address,uint256): AccountNotSeizable(0x499853378eE65c4302f830265Aea59fBCBc0B57d); counterexample: calldata=0xc4ab022a000000000000000000000000499853378ee65c4302f830265aea59fbcbc0b57d000000000000000000000000de49821ad69076290dfae31f5d86a072aaf90c4700000000000000000000000000000000000000000000000000000000000002f7 args=[0x499853378eE65c4302f830265Aea59fBCBc0B57d, 0xDe49821aD69076290DFaE31F5d86A072AAF90c47, 759]
  • test_seizeWithMemo_success_noAllowanceRequired(address,address,uint256): AccountNotSeizable(0x000000000000000000000000000000000000144f); counterexample: calldata=0xdc26e1f5000000000000000000000000000000000000000000000000000000000000144f000000000000000000000000000000000000000000000000000000000000463f00000000000000000000000000000000000000000000000000000000000020b3 args=[0x000000000000000000000000000000000000144f, 0x000000000000000000000000000000000000463f, 8371]
  • test_seizeWithMemo_success_unsetHolderPolicyAllowsAnySource(address,address,uint256): AccountNotSeizable(0x09c5d2f32192d9513E8e6e6873a26a52c9a72BE5); counterexample: calldata=0xe599413a00000000000000000000000009c5d2f32192d9513e8e6e6873a26a52c9a72be500000000000000000000000017e6706778a50f60b3bdd4bd082d5f16b916cd080000000000000000000000000000000000000000000000000000000000000001 args=[0x09c5d2f32192d9513E8e6e6873a26a52c9a72BE5, 0x17E6706778A50F60B3bDd4bD082D5f16B916cD08, 1]
  • test_seizeWithMemo_success_unsetReceiverPolicyAllowsAnyDestination(address,address,uint256): AccountNotSeizable(0x00000000000000000000000000000000000030de); counterexample: calldata=0x47ad42e200000000000000000000000000000000000000000000000000000000000030de0000000000000000000000000000000000000000000000000000000000000999000000000000000000000000000000000000000000000000000000000000000e args=[0x00000000000000000000000000000000000030de, 0x0000000000000000000000000000000000000999, 14]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant