Skip to content

docs: describe B20's externally observable architecture - #233

Merged
rayyan224 merged 3 commits into
mainfrom
docs/b20-integration-architecture
Oct 1, 2026
Merged

rayyan224 merged 3 commits into
mainfrom
docs/b20-integration-architecture

Conversation

@rayyan224

Copy link
Copy Markdown
Collaborator

Summary

  • Add an integrator-facing architecture that describes the contract callers can build against: the system surface, token identity and the 0xef marker, state versus events, and what stays stable across hardforks.
  • Keep node routing and fork-resolution internals out of that document. Point the overview, docs index, and token-type notes at it, and leave execution details in the existing architecture doc.

Test plan

  • Read docs/integration-architecture.md and confirm it stays on observable behavior (addresses, code, views, events, reverts).
  • Follow the new links from docs/README.md, docs/overview.md, and docs/concepts/token-types.md.
  • Confirm docs/architecture.md is unchanged and still covers execution.

Made with Cursor

Give integrators a contract they can build against, separate from how the node executes B20.

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

Copy link
Copy Markdown

Interface Coverage

✅ All interface functions have test coverage.

@github-actions

github-actions Bot commented Sep 30, 2026 •

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% 99.68% 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.58% 97.78% 100.00%
🟢 MockPolicyRegistryStorage.sol 100.00% 100.00% 100.00% 100.00%
Total 97.12% 97.50% 98.21% 97.03%

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

@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

⚠️ Fork tests: 80 failed, 742 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_batchMint_revert_tokenRecipient(address,uint256,uint256): next call did not revert as expected; counterexample: calldata=0x0e04a6a6000000000000000000000000f81792ff0c69758e2e59effd1b9daf0e0997e786000000000000000000000000000000000000000000000000002a4fc29fdb18b00000000000000000000000000000000000000450868874843448f417ec329bf1 args=[0xf81792fF0c69758e2e59eFfD1B9Daf0E0997E786, 11909646346033328 [1.19e16], 87509527371208606292129787059185 [8.75e31]]
  • test_invertedPolicyId_success_negatesAuthorization(address): custom error 0x6b468933; counterexample: calldata=0x4268079e000000000000000000000000124b5aa583a8363a99e86e774151e415a935c3b7 args=[0x124b5aa583a8363a99e86e774151E415A935C3B7]
  • test_invertedPolicyId_success_togglesAndRoundTrips(uint64): custom error 0x6b468933; counterexample: calldata=0x123f60c000000000000000000000000000000000000000000000000000000000e9bd34bf args=[3921491135 [3.921e9]]
  • test_isAuthorized_success_intersectAllowAndNotX(address): PolicyNotFound(); counterexample: calldata=0x55848b8e000000000000000000000000df466c501f70a0f54110a81f5c5dec2bb93c6a3c args=[0xdf466c501f70A0f54110a81F5C5DEC2Bb93c6a3c]
  • test_isAuthorized_success_invertAllowlistNonMemberAuthorized(address): assertion failed; counterexample: calldata=0xb07c21cd000000000000000000000000a00430851d9f1657c2cba97e68d6c9fe60d51e49 args=[0xa00430851D9F1657C2CBA97E68D6C9fe60D51e49]
  • test_isAuthorized_success_invertAlwaysBlockAuthorizes(address): assertion failed; counterexample: calldata=0xca9d71610000000000000000000000000000000000000000000000000000000000003353 args=[0x0000000000000000000000000000000000003353]
  • test_isAuthorized_success_invertBlocklistMemberAuthorized(address): assertion failed; counterexample: calldata=0x072617790000000000000000000000004c8d661ce590c27e3d8d7cf0695e8d75259bc3b0 args=[0x4C8d661ce590C27E3d8D7cf0695e8d75259bC3b0]
  • test_mintWithMemo_revert_tokenRecipient(uint256,bytes32): next call did not revert as expected; counterexample: calldata=0x4ca8134a000000000000000000000000000000000000000000000000000000000000000177f8b619941cc30e05606f3295bd4d598adf2728d8ecc0dd13301e82707e08f7 args=[1, 0x77f8b619941cc30e05606f3295bd4d598adf2728d8ecc0dd13301e82707e08f7]
  • test_mint_revertOrder_tokenRecipient_beats_cap(uint256): Error != expected error: SupplyCapExceeded(0, 12094 [1.209e4]) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf); counterexample: calldata=0xc475cac10000000000000000000000000000000000000000000000000000000000002f3e args=[12094 [1.209e4]]
  • test_mint_revertOrder_tokenRecipient_beats_policy(uint256): Error != expected error: PolicyForbids(0xa0d5ae037e66a09119acf080a1d807abb9b6d03b6b9130eb19f7c1e6bdb8ffc8, 72057594037927937 [7.205e16]) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf); counterexample: calldata=0x6ea9803100000000000000000000000000000000000000000000000022b1c8c1227a0000 args=[2500000000000000000 [2.5e18]]
  • test_mint_revert_tokenRecipient(uint256): next call did not revert as expected; counterexample: calldata=0x03224e1a000000000000000000000000000000000000000000000000000000000208039d args=[34079645 [3.407e7]]
  • test_policyAdmin_success_invertResolvesBaseAdmin(address): assertion failed: 0x0000000000000000000000000000000000000000 != 0x8453000000000000000000000000000000000001; counterexample: calldata=0xee7ff5a60000000000000000000000008453000000000000000000000000000000000001 args=[0x8453000000000000000000000000000000000001]
  • test_policyExists_success_invertMirrorsBase(uint56): assertion failed; counterexample: calldata=0xf4aec5dc000000000000000000000000000000000000000000000000000000000000e62e args=[58926 [5.892e4]]
  • test_seizeWithMemo_revertOrder_tokenRecipient_beats_blocked(address): Error != expected error: AccountNotSeizable(0x6a7F2d95Cdb13999e113385C2604a5CA2a035841) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf); counterexample: calldata=0x4ce156d20000000000000000000000006a7f2d95cdb13999e113385c2604a5ca2a035841 args=[0x6a7F2d95Cdb13999e113385C2604a5CA2a035841]
  • test_seizeWithMemo_revert_tokenRecipient(address,uint256): Error != expected error: InsufficientBalance(0x00000000000000000000000000000000000044AC, 0, 82099942313829880515582171778066873600068812804006977395700351106844409766975 [8.209e76]) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf); counterexample: calldata=0x220d05f300000000000000000000000000000000000000000000000000000000000044acb582ebae03f16fee49a6763f78df482fb11ae73f103ed0d330bbe556aa90a43f args=[0x00000000000000000000000000000000000044AC, 82099942313829880515582171778066873600068812804006977395700351106844409766975 [8.209e76]]
  • test_transferFromWithMemo_revert_tokenRecipient(address,address,uint256,bytes32): Error != expected error: InsufficientAllowance(0xe0EaDAFaD4Dc0F21c349D6C065de23569B0085ff, 0, 10246741160497453283154845 [1.024e25]) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf); counterexample: calldata=0xac063dd0000000000000000000000000e0eadafad4dc0f21c349d6c065de23569b0085ff0000000000000000000000008b23671da2630dd89674e776cac51559348801450000000000000000000000000000000000000000000879d4f38c070516801b9d7e665203fc6ae467e6bc75586e91224a5812448bccb355d499222ba695514474 args=[0xe0EaDAFaD4Dc0F21c349D6C065de23569B0085ff, 0x8b23671da2630Dd89674E776Cac5155934880145, 10246741160497453283154845 [1.024e25], 0x7e665203fc6ae467e6bc75586e91224a5812448bccb355d499222ba695514474]
  • test_transferFrom_revertOrder_tokenRecipient_beats_allowance(address,address,uint256): Error != expected error: InsufficientAllowance(0x43DE74a30439528F6528AA2fD5e6C69f257f30a0, 0, 15539788467250665312641834142 [1.553e28]) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf); counterexample: calldata=0x98d9a95e00000000000000000000000043de74a30439528f6528aa2fd5e6c69f257f30a0000000000000000000000000143b7c54bb90180b1026a6918cf33d4c5801bacd000000000000000000000000000000000000000032363634ced3b57548735c9e args=[0x43DE74a30439528F6528AA2fD5e6C69f257f30a0, 0x143b7c54Bb90180B1026a6918cF33d4c5801BAcd, 15539788467250665312641834142 [1.553e28]]
  • test_transferFrom_revertOrder_tokenRecipient_beats_executorPolicy(address,address,uint256): Error != expected error: InsufficientAllowance(0x00000000000000000000000000000000000013C2, 0, 3000000 [3e6]) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf); counterexample: calldata=0x0fbad03100000000000000000000000000000000000000000000000000000000000013c2000000000000000000000000000000000000000000000000000000000000018300000000000000000000000000000000000000000000000000000000002dc6c0 args=[0x00000000000000000000000000000000000013C2, 0x0000000000000000000000000000000000000183, 3000000 [3e6]]
  • test_transferFrom_revert_selfCaller_executorPolicyForbids(address,address,uint256): next call did not revert as expected; counterexample: calldata=0x641b204b000000000000000000000000f711f4f8ad59b0e16faf4490e5515bfe34c5d749000000000000000000000000f5251c437a5421d95860a94bb04bb3b2ce35059f0008f515a6c271344c65cfba3f42f31c3bb1032b5ecf88c4679bd7d49bb39dcf args=[0xF711F4f8AD59B0E16FaF4490e5515bfe34c5d749, 0xF5251c437a5421D95860a94Bb04bB3b2cE35059f, 15826288093900073220152749996828812370779803288797735240594721052782992847 [1.582e73]]
  • test_transferFrom_revert_tokenRecipient(address,address,uint256): Error != expected error: InsufficientAllowance(0xc9e7A22A12E097315047D7E9191dDAFAB1b51Fb0, 0, 622190590190994396358256122063339792357956709964336997706000 [6.221e59]) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf); counterexample: calldata=0xb9f54792000000000000000000000000c9e7a22a12e097315047d7e9191ddafab1b51fb0000000000000000000000000e4c361f3c0fa2f8616b0a0477e0288f30ed0fba500000000000000631ee4dc69f701420a5a236c47d0a4595796559edd2c81a910 args=[0xc9e7A22A12E097315047D7E9191dDAFAB1b51Fb0, 0xe4C361f3C0fA2f8616B0A0477E0288f30Ed0FBA5, 622190590190994396358256122063339792357956709964336997706000 [6.221e59]]
  • test_transferWithMemo_revertOrder(address,address,uint256,bytes32): Error != expected error: PolicyForbids(0xb81736c875ab819dd97f59f2a6542cfb731ad52b4ae15a6f24df2fb02b0327f5, 72057594037927937 [7.205e16]) != PolicyForbids(0x10be5173aff2a44e748bd9acd8b19fe34689581398a9db7ba2fb671e786ff7d8, 72057594037927937 [7.205e16]); counterexample: calldata=0xf5e3112500000000000000000000000000000000000000000000000000000000000028030000000000000000000000000000000000000000000000000000000000003c2a0000000000000000000000000000000000000000000000000000000000002be5423230466163746f727900000000000000000000000000000000000000000000 args=[0x0000000000000000000000000000000000002803, 0x0000000000000000000000000000000000003c2A, 11237 [1.123e4], 0x423230466163746f727900000000000000000000000000000000000000000000]
  • test_transferWithMemo_revert_executorPolicyForbids(address,address,uint256,bytes32): Error != expected error: InsufficientBalance(0x860799c8a5b6374B7a3A2E0D14dE98A7DD4936C6, 0, 171777444339317336993336253588941075102 [1.717e38]) != PolicyForbids(0x10be5173aff2a44e748bd9acd8b19fe34689581398a9db7ba2fb671e786ff7d8, 72057594037927937 [7.205e16]); counterexample: calldata=0xa3802c17000000000000000000000000860799c8a5b6374b7a3a2e0d14de98a7dd4936c60000000000000000000000004351ad508ff6bab7cb90fe08de27b17887ac874c00000000000000000000000000000000813b21e3cf1e2190bb5e25a49d2c729eb06d07aac999a39ff93ffb8ba07df2124dad43afdbcea3da851e15dc3ffb34d9 args=[0x860799c8a5b6374B7a3A2E0D14dE98A7DD4936C6, 0x4351Ad508Ff6BAB7cB90Fe08DE27B17887ac874c, 171777444339317336993336253588941075102 [1.717e38], 0xb06d07aac999a39ff93ffb8ba07df2124dad43afdbcea3da851e15dc3ffb34d9]
  • test_transferWithMemo_revert_tokenRecipient(address,uint256,bytes32): Error != expected error: InsufficientBalance(0x259e7255B46c5125Cf964ffA4fE52f34cE6FC985, 0, 11882419493319490574919177474669352313419870820036400228841423365549906 [1.188e70]) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf); counterexample: calldata=0xe48d5155000000000000000000000000259e7255b46c5125cf964ffa4fe52f34ce6fc985000001b8be51bc7cfc394ab8990752f28879c7dfca5d06ab76a262dda4592f5268430c2760d364555474e8646f28da5948f8f0fe7af8acd1c9930435badd8a27 args=[0x259e7255B46c5125Cf964ffA4fE52f34cE6FC985, 11882419493319490574919177474669352313419870820036400228841423365549906 [1.188e70], 0x68430c2760d364555474e8646f28da5948f8f0fe7af8acd1c9930435badd8a27]
  • test_transfer_revertOrder_executorPolicy_beats_balance(address,address,uint256): Error != expected error: InsufficientBalance(0xB04Fe06Db9Fcaa7AB7865304D8aF1C19e991283d, 0, 149055122838847175266921890675586560921 [1.49e38]) != PolicyForbids(0x10be5173aff2a44e748bd9acd8b19fe34689581398a9db7ba2fb671e786ff7d8, 72057594037927937 [7.205e16]); counterexample: calldata=0x76b31f6e000000000000000000000000b04fe06db9fcaa7ab7865304d8af1c19e991283d0000000000000000000000008f32824b00e05bb6b047a1425fb3117894209db50000000000000000000000000643b6c57022f8f21674644e832a2a4e16193cd4 args=[0xB04Fe06Db9Fcaa7AB7865304D8aF1C19e991283d, 0x8f32824B00e05Bb6b047A1425Fb3117894209Db5, 35764016173965575524495919492484339172413881556 [3.576e46]]
  • test_transfer_revertOrder_executorPolicy_beats_receiverPolicy(address,address,uint256): Error != expected error: PolicyForbids(0x8a4b3fa2d8b921852bc0089c6ef0958aa6961897be36fd731330fe2cd23f8363, 72057594037927937 [7.205e16]) != PolicyForbids(0x10be5173aff2a44e748bd9acd8b19fe34689581398a9db7ba2fb671e786ff7d8, 72057594037927937 [7.205e16]); counterexample: calldata=0x67f822c5000000000000000000000000cd394397fc26e836694c16f59bbc141d1f80804d000000000000000000000000d5d1f6c2a4e9271e82abf59ded6953b31dd388fa0000000000000064a5450cfb04654456e1ce2221d7e81a00ea3bb2da5f4da87a args=[0xCD394397FC26e836694c16F59bBC141D1f80804d, 0xd5d1F6C2a4E9271e82aBF59DEd6953b31dd388Fa, 631762575510169042257485266505262190194606455720778736183418 [6.317e59]]
  • test_transfer_revertOrder_executorPolicy_beats_senderPolicy(address,address,uint256): Error != expected error: PolicyForbids(0xb81736c875ab819dd97f59f2a6542cfb731ad52b4ae15a6f24df2fb02b0327f5, 72057594037927937 [7.205e16]) != PolicyForbids(0x10be5173aff2a44e748bd9acd8b19fe34689581398a9db7ba2fb671e786ff7d8, 72057594037927937 [7.205e16]); counterexample: calldata=0xe9945cbb0000000000000000000000002d37a28bdfb8fab908e28773d6b4a31f5e375d4400000000000000000000000023099cbfbf61c68d53302ffc93955974f173ffad00000000000000000000000000000000000000000296f0205c1da3408ef37e93 args=[0x2D37a28bdfB8fab908e28773D6B4a31F5E375D44, 0x23099CBfbf61c68D53302fFc93955974F173ffAd, 801442857474224510697963155 [8.014e26]]
  • test_transfer_revertOrder_tokenRecipient_beats_balance(address,uint256): Error != expected error: InsufficientBalance(0x1DE28c05fCE10108F879e44a4BA541Ace224Be29, 0, 340282366920938463463374607431768211455 [3.402e38]) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf); counterexample: calldata=0x71022c5e0000000000000000000000001de28c05fce10108f879e44a4ba541ace224be29ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff args=[0x1DE28c05fCE10108F879e44a4BA541Ace224Be29, 115792089237316195423570985008687907853269984665640564039457584007913129639935 [1.157e77]]
  • test_transfer_revertOrder_tokenRecipient_beats_executorPolicy(address,uint256): Error != expected error: InsufficientBalance(0xCB00000000000000000000000000000000000000, 0, 56) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf); counterexample: calldata=0x5de2a22f000000000000000000000000cb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038 args=[0xCB00000000000000000000000000000000000000, 56]
  • test_transfer_revertOrder_tokenRecipient_beats_receiverPolicy(address,uint256): Error != expected error: PolicyForbids(0x8a4b3fa2d8b921852bc0089c6ef0958aa6961897be36fd731330fe2cd23f8363, 72057594037927937 [7.205e16]) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf); counterexample: calldata=0x85d001e4000000000000000000000000355223c4a2c32de3f11497f5fc04d06481369e42000007c6e95127a4dd72823aedee611ae2e7f5e9ff05114e7268c8dec41a2718 args=[0x355223C4a2c32De3f11497f5fc04d06481369e42, 53674865016761291053002495337798893696823951958883056925150511980226328 [5.367e70]]
  • test_transfer_revertOrder_tokenRecipient_beats_senderPolicy(address,uint256): Error != expected error: PolicyForbids(0xb81736c875ab819dd97f59f2a6542cfb731ad52b4ae15a6f24df2fb02b0327f5, 72057594037927937 [7.205e16]) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf); counterexample: calldata=0x82b0eb1a0000000000000000000000006fbb1c6fc7ecdf91bffd0664d33732462ab85319000000000000000001d3d777852458f105224db325f425b10095238e950e74ef args=[0x6fbb1C6fC7ECdf91bfFD0664D33732462AB85319, 44810329327943013570153886921856901925215945723158099183 [4.481e55]]
  • test_transfer_revertOrder_tokenRecipient_beats_zeroSender(uint256): Error != expected error: InvalidSender(0x0000000000000000000000000000000000000000) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf); counterexample: calldata=0x842ce6140000000000000000000000000000000000251ddbfb5611f6d47063585b21b329 args=[192720602396675063669421460626191145 [1.927e35]]
  • test_transfer_revert_executorPolicyForbids(address,address,uint256): Error != expected error: InsufficientBalance(0xD64538C043ab8e28c9eF6F0c9A16908f5BcDF233, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932 [1.157e77]) != PolicyForbids(0x10be5173aff2a44e748bd9acd8b19fe34689581398a9db7ba2fb671e786ff7d8, 72057594037927937 [7.205e16]); counterexample: calldata=0xe8de369d000000000000000000000000d64538c043ab8e28c9ef6f0c9a16908f5bcdf233000000000000000000000000c0c75bb51e37527705f0973058f7160b122b4bbcfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc args=[0xD64538C043ab8e28c9eF6F0c9A16908f5BcDF233, 0xc0C75bB51e37527705f0973058f7160b122b4BBc, 115792089237316195423570985008687907853269984665640564039457584007913129639932 [1.157e77]]
  • test_transfer_revert_externalExecutorPolicyDenies(address,address,uint256): Error != expected error: InsufficientBalance(0x48Ad3DE69f43d5e6D2B1C8559fa587971714f656, 0, 56) != PolicyForbids(0x10be5173aff2a44e748bd9acd8b19fe34689581398a9db7ba2fb671e786ff7d8, 72057594037927938 [7.205e16]); counterexample: calldata=0x66ef867100000000000000000000000048ad3de69f43d5e6d2b1c8559fa587971714f65600000000000000000000000083113c0bce7ee7c85fc37938bb756b20ec1f71a40000000000000000000000000000000000000000000000000000000000000038 args=[0x48Ad3DE69f43d5e6D2B1C8559fa587971714f656, 0x83113c0BCE7ee7C85fC37938bb756B20eC1f71A4, 56]
  • test_transfer_revert_tokenRecipient(address,uint256): Error != expected error: InsufficientBalance(0x9a6c6c4d3cD9fd15b1c54AA77AA9d11c4DbfED5b, 0, 350946927333282 [3.509e14]) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf); counterexample: calldata=0x0221ddf60000000000000000000000009a6c6c4d3cd9fd15b1c54aa77aa9d11c4dbfed5b00000000000000000000000000000000000000000000000000013f2f32f04fa2 args=[0x9a6c6c4d3cD9fd15b1c54AA77AA9d11c4DbfED5b, 350946927333282 [3.509e14]]
    [FAIL: Error != expected error: InvalidSender(0x0000000000000000000000000000000000000000) != InvalidReceiver(0xB2000000000000000000009E871a2184B5aFaCCf)] test_seizeWithMemo_revertOrder_tokenRecipient_beats_zeroSender() (gas: 47044)
    [FAIL: Error != expected error: PolicyNotFound() != InvalidChildPolicy(9367487224930631684 [9.367e18])] test_createCompositePolicy_revert_invertedCompositeChild() (gas: 234691)
    [FAIL: PolicyNotFound()] test_compositePolicyChildIds_success_invertedCompositeIdReturnsSameSet() (gas: 130069)
    [FAIL: PolicyNotFound()] test_compositePolicyChildIds_success_returnsChildrenVerbatim() (gas: 130113)
    [FAIL: PolicyNotFound()] test_compositePolicyChildIds_success_returnsInvertedChildVerbatimAfterUpdate() (gas: 234463)
    [FAIL: PolicyNotFound()] test_createCompositePolicy_success_invertedSimpleChild() (gas: 130123)

rayyan224 and others added 2 commits September 30, 2026 14:49
Add an integrator-facing page on precompiles, token routing, and hardfork upgrades, and drop the state and transition sections from the integration architecture doc.

Co-authored-by: Cursor <cursoragent@cursor.com>
@rayyan224
rayyan224 merged commit 0207138 into main Oct 1, 2026
10 checks passed
@rayyan224
rayyan224 deleted the docs/b20-integration-architecture branch October 1, 2026 14:17

@stephancill stephancill left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is great!

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.

2 participants