Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
217 commits
Select commit Hold shift + click to select a range
dc7cab0
feat: override builder lib
ameeshaagrawal Oct 10, 2025
23161aa
feat: override params
ameeshaagrawal Oct 13, 2025
13204fd
fix: remove batch logic
ameeshaagrawal Oct 13, 2025
6356eb5
feat: refactor for single payload
ameeshaagrawal Oct 14, 2025
d636ca1
fix: build
ameeshaagrawal Oct 15, 2025
1de79fa
fix: remaining contract build
ameeshaagrawal Oct 15, 2025
387b0dd
fix: remove requests wip
ameeshaagrawal Oct 15, 2025
6638193
fix: counter tests
ameeshaagrawal Oct 17, 2025
328df25
feat: fix add payload
ameeshaagrawal Oct 24, 2025
27c6799
fix: override
ameeshaagrawal Oct 24, 2025
f15cee0
fix: fees settlement
ameeshaagrawal Oct 24, 2025
effec66
v1.1.49-test.0
ameeshaagrawal Oct 24, 2025
ced1c7c
fix: add signature
ameeshaagrawal Oct 24, 2025
5261307
feat: update deploy scripts
ameeshaagrawal Oct 24, 2025
7586700
fix: src
ameeshaagrawal Oct 24, 2025
5122d99
v1.1.49-test.1
ameeshaagrawal Oct 24, 2025
1ebf544
v1.1.49-test.2
ameeshaagrawal Oct 24, 2025
8734f15
v1.1.49-test.3
ameeshaagrawal Oct 24, 2025
ca1475a
feat: message switchboard
tHeMaskedMan981 Oct 24, 2025
91d5bc7
v1.1.49-test.4
ameeshaagrawal Oct 24, 2025
9aae799
v1.1.49-test.5
ameeshaagrawal Oct 24, 2025
b7b54e5
Merge branch 'phase-1' into feat/message-switchboard
tHeMaskedMan981 Oct 24, 2025
93b86a1
v1.1.49-test.6
ameeshaagrawal Oct 27, 2025
aecdd0f
v1.1.49-test.7
ameeshaagrawal Oct 28, 2025
2fb02d3
v1.1.49-test.8
ameeshaagrawal Oct 29, 2025
bde9aa2
feat: add watcher sig
ameeshaagrawal Oct 29, 2025
e4eacc5
feat: message switchboard tests complete
tHeMaskedMan981 Oct 29, 2025
12655a9
fix: scripts
ameeshaagrawal Oct 29, 2025
6e0adf4
v1.1.49-test.9
ameeshaagrawal Oct 30, 2025
ba5a850
Merge pull request #210 from SocketDotTech/fix/event
ameeshaagrawal Nov 3, 2025
2fba849
feat: updated payloadId implementation
tHeMaskedMan981 Nov 3, 2025
101fb60
Merge branch 'phase-1' of https://github.com/SocketDotTech/socket-pro…
tHeMaskedMan981 Nov 3, 2025
c41872d
Merge branch 'phase-1' of https://github.com/SocketDotTech/socket-pro…
tHeMaskedMan981 Nov 3, 2025
053fd3c
Merge pull request #207 from SocketDotTech/feat/message-switchboard
tHeMaskedMan981 Nov 3, 2025
0dac919
Merge branch 'phase-1' of https://github.com/SocketDotTech/socket-pro…
tHeMaskedMan981 Nov 3, 2025
337f8cf
wip
ameeshaagrawal Nov 4, 2025
554018a
Merge branch 'phase-1' into solana-phase1
ameeshaagrawal Nov 5, 2025
4c55c6a
feat: added payloadId tests, fixed old tests
tHeMaskedMan981 Nov 5, 2025
933900b
feat: updated deposit to trigger
tHeMaskedMan981 Nov 5, 2025
5e81fe7
feat: added pausable to watcher,socket
tHeMaskedMan981 Nov 6, 2025
ae5baa7
fix: deadline check
ameeshaagrawal Nov 6, 2025
35ee2b7
feat: solana libs
ameeshaagrawal Nov 6, 2025
ff6dfaf
fix: tests
ameeshaagrawal Nov 6, 2025
e1e990b
fix: lint
ameeshaagrawal Nov 7, 2025
e7970bf
fix: trigger
ameeshaagrawal Nov 7, 2025
0ccbc51
fix: watcher and transmitter fees
ameeshaagrawal Nov 7, 2025
8cbd5b7
fix: promise retryable with deadline
ameeshaagrawal Nov 7, 2025
5dd3770
feat: pausable tests, review fixes
tHeMaskedMan981 Nov 7, 2025
5b62e53
fix: tests
ameeshaagrawal Nov 7, 2025
8672361
fix: switchboardId, counter type change. idUtils optimize
tHeMaskedMan981 Nov 8, 2025
3c8f98f
Merge pull request #211 from SocketDotTech/feat/id
arthcp Nov 8, 2025
1334556
Merge pull request #212 from SocketDotTech/fix/fee-deposit-to-trigger
arthcp Nov 8, 2025
d5f20eb
Merge branch 'phase-1' into fix-watcher
ameeshaagrawal Nov 12, 2025
ab74592
Merge branch 'phase-1' into feat/pausable
ameeshaagrawal Nov 12, 2025
c07946b
Merge pull request #213 from SocketDotTech/feat/pausable
ameeshaagrawal Nov 12, 2025
73e6c78
fix: bugs
ameeshaagrawal Nov 12, 2025
bb20519
Merge pull request #214 from SocketDotTech/fix-watcher
ameeshaagrawal Nov 12, 2025
475ec42
Merge pull request #215 from SocketDotTech/solana-phase1
ameeshaagrawal Nov 12, 2025
e6786c6
fix: build
ameeshaagrawal Nov 12, 2025
dd96c9b
fix: renames
ameeshaagrawal Nov 12, 2025
f96282e
fix: vars and fn renames
ameeshaagrawal Nov 12, 2025
298783b
feat: add trasmitterSolana in Watcher contract; update test and deplo…
gwalen Nov 12, 2025
fe28064
Merge branch 'phase-1' into watcher-solana-add-trasmitter-solana
ameeshaagrawal Nov 12, 2025
dc9b920
fix: protocol fees contracts
ameeshaagrawal Nov 12, 2025
f5b18cf
feat: gas escrow
ameeshaagrawal Nov 12, 2025
853f90e
fix: interface
ameeshaagrawal Nov 12, 2025
9121631
Merge branch 'phase-1' of https://github.com/SocketDotTech/socket-pro…
tHeMaskedMan981 Nov 12, 2025
493e568
Merge branch 'phase-1' of https://github.com/SocketDotTech/socket-pro…
tHeMaskedMan981 Nov 12, 2025
c971705
fix: gas account manager
ameeshaagrawal Nov 12, 2025
5624e5e
fix: renames
ameeshaagrawal Nov 12, 2025
662a8ca
fix: build
ameeshaagrawal Nov 12, 2025
18e2d06
Remove declaration of susdcSolanaProgramId in FeesManager; fix path t…
gwalen Nov 13, 2025
379275c
Merge pull request #216 from SocketDotTech/watcher-solana-add-trasmit…
gwalen Nov 13, 2025
1b6a25f
fix: add missing comments
gwalen Nov 13, 2025
f868907
Merge pull request #217 from SocketDotTech/feat/pausable
tHeMaskedMan981 Nov 13, 2025
cfe8264
fix: rename credit
ameeshaagrawal Nov 13, 2025
5ad30ed
fix: tests
ameeshaagrawal Nov 13, 2025
a12b0d1
Merge branch 'phase-1' into gas-account
ameeshaagrawal Nov 13, 2025
db1a6e0
fix: remove susdc
ameeshaagrawal Nov 13, 2025
6a41577
Merge pull request #219 from SocketDotTech/watcher-solana-add-trasmit…
gwalen Nov 13, 2025
a632474
chore: review
arthcp Nov 13, 2025
ebee8b1
merge
arthcp Nov 13, 2025
c5bd655
Merge pull request #218 from SocketDotTech/gas-account
arthcp Nov 13, 2025
b15f143
fix: sb sign
ameeshaagrawal Nov 14, 2025
3f204c7
fix: review fixes
ameeshaagrawal Nov 14, 2025
2595862
fix: remove extra functions
ameeshaagrawal Nov 14, 2025
cbd73f7
fix: socket tests
tHeMaskedMan981 Nov 14, 2025
755766a
Merge branch 'phase-1' of https://github.com/SocketDotTech/socket-pro…
tHeMaskedMan981 Nov 14, 2025
c3d5101
Merge pull request #221 from SocketDotTech/tests-socket
tHeMaskedMan981 Nov 14, 2025
3d37ef4
Merge branch 'phase-1' into fix/review
ameeshaagrawal Nov 14, 2025
b59b03f
fix: review comments and bugs
ameeshaagrawal Nov 14, 2025
42ec35e
fix: sb sign
ameeshaagrawal Nov 14, 2025
e189752
fix: review fixes
ameeshaagrawal Nov 14, 2025
ec4fff4
fix: contract bugs
ameeshaagrawal Nov 14, 2025
27f7d70
doc: internal audit docs
ameeshaagrawal Nov 14, 2025
b2dd857
fix: tests
ameeshaagrawal Nov 14, 2025
061c792
feat: audit fixes
ameeshaagrawal Nov 14, 2025
bc9c88c
fix: socket tests
ameeshaagrawal Nov 14, 2025
119ab07
doc: audit md
ameeshaagrawal Nov 17, 2025
02d9556
Merge pull request #220 from SocketDotTech/fix/review
ameeshaagrawal Nov 17, 2025
ed0fd06
fix: lint
ameeshaagrawal Nov 17, 2025
e52278b
fix: send payload fallback
ameeshaagrawal Nov 17, 2025
b6ee980
fix: remove onChainAddress from ForwarderSolana initiazlier
gwalen Nov 17, 2025
d58159f
feat: fixed stack too deep
tHeMaskedMan981 Nov 17, 2025
5da9afe
Merge branch 'fix-bugs' of https://github.com/SocketDotTech/socket-pr…
tHeMaskedMan981 Nov 17, 2025
a7eb6f7
fix: trigger
ameeshaagrawal Nov 17, 2025
a421602
Merge branch 'fix-bugs' of https://github.com/SocketDotTech/socket-pr…
tHeMaskedMan981 Nov 17, 2025
bf52ce1
Merge pull request #223 from SocketDotTech/phase-1-forwarder-solana
tHeMaskedMan981 Nov 17, 2025
0dc857f
fix: set is valid plug
ameeshaagrawal Nov 17, 2025
85762ee
fix: fallback encoding
tHeMaskedMan981 Nov 17, 2025
77cf9f0
doc: todo
ameeshaagrawal Nov 17, 2025
94f9a2f
fix: tests
ameeshaagrawal Nov 17, 2025
f321472
Merge pull request #224 from SocketDotTech/fix/test
ameeshaagrawal Nov 17, 2025
c401b0b
chore: docs
ameeshaagrawal Nov 17, 2025
ffe5d62
fix: remove callerAppGateway from callSolana() function on ForwarderS…
gwalen Nov 18, 2025
1e785dc
chore: docs
ameeshaagrawal Nov 18, 2025
9f6c81b
fix: hash collision
tHeMaskedMan981 Nov 18, 2025
f0e5563
fix: tests
ameeshaagrawal Nov 18, 2025
7f519e1
chore: coverage report
ameeshaagrawal Nov 18, 2025
0538482
chore: comments
ameeshaagrawal Nov 18, 2025
ec62942
rename: execution status
ameeshaagrawal Nov 18, 2025
179c401
rename: execution params
ameeshaagrawal Nov 18, 2025
8ac924b
rename: callData_
ameeshaagrawal Nov 18, 2025
1982776
fix: event
ameeshaagrawal Nov 18, 2025
6f3c65b
rename: switchboardStatus
ameeshaagrawal Nov 18, 2025
e706724
fix: config renames
ameeshaagrawal Nov 18, 2025
12c5a81
fix: rename trigger
ameeshaagrawal Nov 18, 2025
bdc24da
chore: audit doc
ameeshaagrawal Nov 18, 2025
f5bcf07
chore: audit docs
ameeshaagrawal Nov 18, 2025
814ab61
fix: remove unused vars
ameeshaagrawal Nov 18, 2025
6fa5ee8
fix: latest solidity version
ameeshaagrawal Nov 18, 2025
7036814
fix: added feesIncreased event
tHeMaskedMan981 Nov 18, 2025
71d33e9
Merge branch 'fix-bugs' of https://github.com/SocketDotTech/socket-pr…
tHeMaskedMan981 Nov 18, 2025
d6b68ca
chore: comment
ameeshaagrawal Nov 18, 2025
05d3324
fix: tests
ameeshaagrawal Nov 18, 2025
6e9eb50
fix: fees increase
ameeshaagrawal Nov 18, 2025
3d58710
chore: docs
ameeshaagrawal Nov 18, 2025
c677a67
feat: added slither output
tHeMaskedMan981 Nov 19, 2025
d73b94f
Merge pull request #225 from SocketDotTech/phase-1-fix-forwarder-sola…
ameeshaagrawal Nov 19, 2025
d6e83e9
fix: renames, clean code
ameeshaagrawal Nov 19, 2025
313df96
fix: lint
ameeshaagrawal Nov 19, 2025
f0f2e82
doc: comments
ameeshaagrawal Nov 19, 2025
084ef6e
fix: style guide
ameeshaagrawal Nov 19, 2025
63a8b16
fix: move errors
ameeshaagrawal Nov 19, 2025
85e6f78
fix: source updated to encodePacked
tHeMaskedMan981 Nov 19, 2025
0f894b0
Merge branch 'fix-bugs' of https://github.com/SocketDotTech/socket-pr…
tHeMaskedMan981 Nov 19, 2025
22ddd86
Merge branch 'fix-bugs' into doc
ameeshaagrawal Nov 19, 2025
f3d6e03
fix: tests
tHeMaskedMan981 Nov 19, 2025
4bb073b
fix: comments
ameeshaagrawal Nov 19, 2025
d197ae5
fix: tests
tHeMaskedMan981 Nov 20, 2025
19abff9
Merge branch 'fix-bugs' into doc
ameeshaagrawal Nov 20, 2025
9196ddb
Merge pull request #226 from SocketDotTech/doc
ameeshaagrawal Nov 20, 2025
5f11f5e
chore: renames, comments
ameeshaagrawal Nov 20, 2025
d13219c
chore: update doc
ameeshaagrawal Nov 20, 2025
9fcd6aa
feat: update compiler version
ameeshaagrawal Nov 20, 2025
b643558
fix: add validation in constructor
ameeshaagrawal Nov 21, 2025
fd24c5a
Merge pull request #227 from SocketDotTech/fix/constructor
ameeshaagrawal Nov 21, 2025
97189b7
Merge pull request #228 from SocketDotTech/fix-version
ameeshaagrawal Nov 21, 2025
5a46089
fix: arrange structs
ameeshaagrawal Nov 21, 2025
35ae0f1
Merge pull request #229 from SocketDotTech/fix/constructor
ameeshaagrawal Nov 21, 2025
09fe7bd
fix: tests, audit comments
tHeMaskedMan981 Nov 21, 2025
c9bad04
Merge branch 'fix-bugs' of https://github.com/SocketDotTech/socket-pr…
tHeMaskedMan981 Nov 21, 2025
ce04c40
fix: cleanup
tHeMaskedMan981 Nov 21, 2025
23148ec
Merge pull request #222 from SocketDotTech/fix-bugs
ameeshaagrawal Nov 21, 2025
8b7ac09
fix: rerun audit
ameeshaagrawal Nov 21, 2025
5d7253e
fix: clean docs
ameeshaagrawal Nov 21, 2025
05271d0
feat: added audit docs
tHeMaskedMan981 Nov 21, 2025
1899bd1
fix: added default deadline setter, deadline bug in createDigest, nam…
tHeMaskedMan981 Nov 21, 2025
4fc2627
chore: cleanup comments
tHeMaskedMan981 Nov 21, 2025
2631eda
chore: docs update
tHeMaskedMan981 Nov 21, 2025
eac68a0
fix: remove audit tags
ameeshaagrawal Nov 22, 2025
778abdc
fix: socket contracts
ameeshaagrawal Nov 22, 2025
df6c3fd
fix: remove inline comments
ameeshaagrawal Nov 22, 2025
bad2800
feat: encode tests
tHeMaskedMan981 Nov 22, 2025
dee69ba
Merge branch 'phase-1' into fix-bugs
tHeMaskedMan981 Nov 22, 2025
cfc5781
fix: build
tHeMaskedMan981 Nov 22, 2025
f85269b
Merge pull request #230 from SocketDotTech/fix-bugs
tHeMaskedMan981 Nov 22, 2025
9e8caec
fix: review
tHeMaskedMan981 Nov 22, 2025
7075cb3
feat: gasBuffer, maxCopyBytes immutable, deadline update
tHeMaskedMan981 Nov 24, 2025
8d5d6f4
feat: n/n watcher
ameeshaagrawal Nov 24, 2025
c7c5ff5
fix: tests
ameeshaagrawal Nov 24, 2025
fc13704
Merge branch 'phase-1' into feat/multi-watcher
ameeshaagrawal Nov 24, 2025
426f352
fix: tests
ameeshaagrawal Nov 24, 2025
8554de9
fix: lint
ameeshaagrawal Nov 24, 2025
abace8f
fix: evmx sb
ameeshaagrawal Nov 24, 2025
95952c0
fix: rename
ameeshaagrawal Nov 24, 2025
dc293f2
fix: move payload id to digest map
ameeshaagrawal Nov 24, 2025
1f3dacc
fix: check used nonce
ameeshaagrawal Nov 24, 2025
a7911af
Merge pull request #232 from SocketDotTech/feat/multi-watcher
ameeshaagrawal Nov 24, 2025
d938896
feat: remove obosolete check from ForwarderSolana; add test for Solan…
gwalen Nov 24, 2025
53dc756
chore: coverage script
ameeshaagrawal Nov 25, 2025
c9757c0
test: sb full coverage
ameeshaagrawal Nov 25, 2025
4ff6be6
Merge pull request #233 from SocketDotTech/test-sb
ameeshaagrawal Nov 25, 2025
85e4fa3
fix: digest in evmx sb
ameeshaagrawal Nov 25, 2025
07118e6
feat: sibling slug
ameeshaagrawal Nov 26, 2025
eefc1d8
fix: rename
ameeshaagrawal Nov 26, 2025
5286612
fix: attest
ameeshaagrawal Nov 26, 2025
2d82ed0
chore: audit ref doc
ameeshaagrawal Nov 26, 2025
a6c596a
feat: added auditor doc
tHeMaskedMan981 Nov 26, 2025
0de7a83
Merge branch 'fix/sb-tests' of https://github.com/SocketDotTech/socke…
tHeMaskedMan981 Nov 26, 2025
7eb9683
fix: remove path specific watchers
ameeshaagrawal Nov 27, 2025
f2c2251
fix: digest and payload id map for sb
ameeshaagrawal Nov 27, 2025
aefae78
fix: assignTransmitter
tHeMaskedMan981 Nov 28, 2025
aa04465
fix: assign Transmitter test
tHeMaskedMan981 Nov 28, 2025
ff1ad26
fix: tests
ameeshaagrawal Nov 28, 2025
9d4c993
fix: added audit report for utils
tHeMaskedMan981 Nov 28, 2025
933cb8c
Merge branch 'fix/sb-tests' of https://github.com/SocketDotTech/socke…
tHeMaskedMan981 Nov 28, 2025
02685f4
fix: tests
ameeshaagrawal Nov 28, 2025
ed5263f
fix: increase coverage
ameeshaagrawal Nov 28, 2025
b0e4968
fix: added assignTransmitter in messageSwitchboard
tHeMaskedMan981 Nov 29, 2025
59b8b1b
Merge pull request #234 from SocketDotTech/feat/assign-transmitter
arthcp Nov 30, 2025
11dfe1a
feat: rename watcher set id
arthcp Dec 1, 2025
8beac92
feat: remove docs
arthcp Dec 1, 2025
9e5b61f
Merge pull request #235 from SocketDotTech/fix/sb-tests
arthcp Dec 1, 2025
f137b61
fix: assign transmitter tests
tHeMaskedMan981 Dec 1, 2025
b4b186b
Merge branch 'phase-1' of https://github.com/SocketDotTech/socket-pro…
tHeMaskedMan981 Dec 1, 2025
9f2bccf
Merge pull request #236 from SocketDotTech/feat/assign-transmitter
arthcp Dec 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion FunctionSignatures.md
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@
| `setRequestPayloadCountLimit` | `0x8526582b` |
| `submitRequest` | `0xf91ba7cc` |
| `transferOwnership` | `0xf2fde38b` |
| `updateRequestAndProcessBatch` | `0x46464471` |
| `updateRequest` | `0x46464471` |
| `watcher__` | `0x300bb063` |

## Watcher
Expand Down
278 changes: 56 additions & 222 deletions contracts/evmx/base/AppGatewayBase.sol

Large diffs are not rendered by default.

37 changes: 15 additions & 22 deletions contracts/evmx/fees/Credit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ import "solady/tokens/ERC20.sol";
import "../interfaces/IFeesManager.sol";
import "../interfaces/IFeesPlug.sol";
import "../interfaces/IFeesPool.sol";
import "../interfaces/IReceiver.sol";

import {AddressResolverUtil} from "../helpers/AddressResolverUtil.sol";
import {NonceUsed, InvalidAmount, InsufficientCreditsAvailable, InsufficientBalance, InvalidChainSlug, NotRequestHandler, InvalidReceiver} from "../../utils/common/Errors.sol";
import {WRITE} from "../../utils/common/Constants.sol";
import {WRITE, FAST} from "../../utils/common/Constants.sol";
import "../../utils/RescueFundsLib.sol";
import "../base/AppGatewayBase.sol";
import {toBytes32Format} from "../../utils/common/Converters.sol";
Expand All @@ -34,9 +33,9 @@ abstract contract FeesManagerStorage is IFeesManager {
mapping(address => uint256) public userBlockedCredits;

// slot 52
/// @notice Mapping to track request credits details for each request count
/// @dev requestCount => RequestFee
mapping(uint40 => uint256) public requestBlockedCredits;
/// @notice Mapping to track request credits details for each payload id
/// @dev payloadId => RequestFee
mapping(bytes32 => uint256) public requestBlockedCredits;

// slot 53
// token pool balances
Expand Down Expand Up @@ -136,7 +135,6 @@ abstract contract Credit is FeesManagerStorage, Initializable, Ownable, AppGatew

// Mint tokens to the user
_mint(depositTo_, creditAmount_);

if (nativeAmount_ > 0) {
// if native transfer fails, add to credit
bool success = feesPool.withdraw(depositTo_, nativeAmount_);
Expand Down Expand Up @@ -201,7 +199,7 @@ abstract contract Credit is FeesManagerStorage, Initializable, Ownable, AppGatew
uint256 amount_
) public view override returns (bool) {
// If consumeFrom_ is not same as spender_ or spender_ is not watcher, check if it is approved
if (!_isWatcher(spender_) && consumeFrom_ != spender_) {
if (spender_ != address(watcher__()) && consumeFrom_ != spender_) {
if (allowance(consumeFrom_, spender_) == 0) return false;
}

Expand All @@ -224,7 +222,7 @@ abstract contract Credit is FeesManagerStorage, Initializable, Ownable, AppGatew
) public override returns (bool) {
if (!isCreditSpendable(from_, msg.sender, amount_)) revert InsufficientCreditsAvailable();

if (_isWatcher(msg.sender)) _approve(from_, msg.sender, amount_);
if (msg.sender == address(watcher__())) _approve(from_, msg.sender, amount_);
return super.transferFrom(from_, to_, amount_);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Don’t clobber user approvals when caller is watcher

Setting allowance to amount_ for watcher overwrites any existing allowance (including infinite). This should bypass allowance entirely for watcher and perform a direct transfer.

-        if (msg.sender == address(watcher__())) _approve(from_, msg.sender, amount_);
-        return super.transferFrom(from_, to_, amount_);
+        if (msg.sender == address(watcher__())) {
+            _transfer(from_, to_, amount_);
+            return true;
+        }
+        return super.transferFrom(from_, to_, amount_);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!isCreditSpendable(from_, msg.sender, amount_)) revert InsufficientCreditsAvailable();
if (_isWatcher(msg.sender)) _approve(from_, msg.sender, amount_);
if (msg.sender == address(watcher__())) _approve(from_, msg.sender, amount_);
return super.transferFrom(from_, to_, amount_);
}
if (!isCreditSpendable(from_, msg.sender, amount_)) revert InsufficientCreditsAvailable();
if (msg.sender == address(watcher__())) {
_transfer(from_, to_, amount_);
return true;
}
return super.transferFrom(from_, to_, amount_);
}
🤖 Prompt for AI Agents
In contracts/evmx/fees/Credit.sol around lines 223 to 227, the current logic
sets the watcher's allowance to amount_ (clobbering any existing approval)
before calling super.transferFrom; instead, detect when msg.sender ==
address(watcher__()) and bypass allowance handling entirely by performing a
direct internal transfer (call the contract's internal _transfer(from_, to_,
amount_) and return true) so existing user allowances (including infinite
approvals) are not overwritten; otherwise, keep the existing path that uses
super.transferFrom.


Expand Down Expand Up @@ -268,33 +266,28 @@ abstract contract Credit is FeesManagerStorage, Initializable, Ownable, AppGatew
uint256 maxFees_,
bytes memory payload_
) internal async {
_setMaxFees(getMaxFees(chainSlug_));
_setOverrides(consumeFrom_);

QueueParams memory queueParams;
queueParams.overrideParams = overrideParams;
queueParams.transaction = Transaction({
// applyOverride(
// OverrideParamsLib.setMaxFees(overrideParams, getMaxFees(chainSlug_)).setConsumeFrom(consumeFrom_)
// );
RawPayload memory rawPayload;
rawPayload.overrideParams = overrideParams;
rawPayload.transaction = Transaction({
chainSlug: chainSlug_,
target: _getFeesPlugAddress(chainSlug_),
payload: payload_
});
queueParams.switchboardType = sbType;
watcher__().queue(queueParams, address(this));
watcher__().executePayload(rawPayload, address(this));
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Construct and apply override params before executing payload

overrideParams is used but never constructed; applyOverride(...) is commented out. This leaves consumeFrom/maxFees unset, likely breaking fee accounting/execution.

This should set overrideParams locally with consumeFrom_ and maxFees_ (and any defaults), assign it to rawPayload.overrideParams, then call executePayload.

-        // applyOverride(
-        //     OverrideParamsLib.setMaxFees(overrideParams, getMaxFees(chainSlug_)).setConsumeFrom(consumeFrom_)
-        // );
-        RawPayload memory rawPayload;
-        rawPayload.overrideParams = overrideParams;
+        RawPayload memory rawPayload;
+        OverrideParams memory params;
+        // Populate override params locally to avoid stale/global state
+        params = OverrideParamsLib
+            .setMaxFees(params, getMaxFees(chainSlug_))
+            .setConsumeFrom(consumeFrom_);
+        rawPayload.overrideParams = params;
         rawPayload.transaction = Transaction({
             chainSlug: chainSlug_,
             target: _getFeesPlugAddress(chainSlug_),
             payload: payload_
         });
         watcher__().executePayload(rawPayload, address(this));

Add missing import at the top of the file:

+import {OverrideParams} from "../../utils/common/Structs.sol";
+import "../../utils/OverrideParamsLib.sol";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// applyOverride(
// OverrideParamsLib.setMaxFees(overrideParams, getMaxFees(chainSlug_)).setConsumeFrom(consumeFrom_)
// );
RawPayload memory rawPayload;
rawPayload.overrideParams = overrideParams;
rawPayload.transaction = Transaction({
chainSlug: chainSlug_,
target: _getFeesPlugAddress(chainSlug_),
payload: payload_
});
queueParams.switchboardType = sbType;
watcher__().queue(queueParams, address(this));
watcher__().executePayload(rawPayload, address(this));
}
// Add these at the top of the file:
import {OverrideParams} from "../../utils/common/Structs.sol";
import "../../utils/OverrideParamsLib.sol";
RawPayload memory rawPayload;
OverrideParams memory params;
// Populate override params locally to avoid stale/global state
params = OverrideParamsLib
.setMaxFees(params, getMaxFees(chainSlug_))
.setConsumeFrom(consumeFrom_);
rawPayload.overrideParams = params;
rawPayload.transaction = Transaction({
chainSlug: chainSlug_,
target: _getFeesPlugAddress(chainSlug_),
payload: payload_
});
watcher__().executePayload(rawPayload, address(this));
}


function increaseFees(uint40 requestCount_, uint256 newMaxFees_) public {
_increaseFees(requestCount_, newMaxFees_);
function increaseFees(bytes32 payloadId_, uint256 newMaxFees_) public {
_increaseFees(payloadId_, newMaxFees_);
}

function _getFeesPlugAddress(uint32 chainSlug_) internal view returns (bytes32) {
if (feesPlugs[chainSlug_] == bytes32(0)) revert InvalidChainSlug();
return feesPlugs[chainSlug_];
}

function _getRequestParams(uint40 requestCount_) internal view returns (RequestParams memory) {
return watcher__().getRequestParams(requestCount_);
}

function _recoverSigner(
bytes32 digest_,
bytes memory signature_
Expand Down
62 changes: 30 additions & 32 deletions contracts/evmx/fees/FeesManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@ import "./Credit.sol";
/// @title FeesManager
/// @notice Contract for managing fees
contract FeesManager is Credit {
using OverrideParamsLib for OverrideParams;

/// @notice Emitted when fees are blocked for a batch
/// @param requestCount The batch identifier
/// @param payloadId The payload id
/// @param consumeFrom The consume from address
/// @param amount The blocked amount
event CreditsBlocked(uint40 indexed requestCount, address indexed consumeFrom, uint256 amount);
event CreditsBlocked(bytes32 indexed payloadId, address indexed consumeFrom, uint256 amount);

/// @notice Emitted when fees are unblocked and assigned to a transmitter
/// @param requestCount The batch identifier
/// @param payloadId The payload id
/// @param consumeFrom The consume from address
/// @param transmitter The transmitter address
/// @param amount The unblocked amount
event CreditsUnblockedAndAssigned(
uint40 indexed requestCount,
bytes32 indexed payloadId,
address indexed consumeFrom,
address indexed transmitter,
uint256 amount
Expand All @@ -30,14 +32,9 @@ contract FeesManager is Credit {
event MaxFeesPerChainSlugSet(uint32 indexed chainSlug, uint256 fees);

/// @notice Emitted when fees are unblocked
/// @param requestCount The batch identifier
/// @param payloadId The payload id
/// @param consumeFrom The consume from address
event CreditsUnblocked(uint40 indexed requestCount, address indexed consumeFrom);

modifier onlyRequestHandler() {
if (msg.sender != address(watcher__().requestHandler__())) revert NotRequestHandler();
_;
}
event CreditsUnblocked(bytes32 indexed payloadId, address indexed consumeFrom);

constructor() {
_disableInitializers(); // disable for implementation
Expand All @@ -56,11 +53,10 @@ contract FeesManager is Credit {
bytes32 sbType_
) public reinitializer(2) {
evmxSlug = evmxSlug_;
sbType = sbType_;
feesPool = IFeesPool(feesPool_);
maxFeesPerChainSlug[evmxSlug_] = fees_;

_setMaxFees(fees_);
overrideParams = overrideParams.setSwitchboardType(sbType_).setMaxFees(fees_);

_initializeOwner(owner_);
_initializeAppGateway(addressResolver_);
}
Expand Down Expand Up @@ -88,39 +84,40 @@ contract FeesManager is Credit {
}

function setMaxFees(uint256 fees_) external onlyOwner {
_setMaxFees(fees_);
overrideParams = overrideParams.setMaxFees(fees_);
}

/////////////////////// FEES MANAGEMENT ///////////////////////

/// @notice Blocks fees for a request count
/// @param requestCount_ The batch identifier
/// @param payloadId_ The payload id
/// @param consumeFrom_ The fees payer address
/// @param credits_ The total fees to block
/// @dev Only callable by delivery helper
function blockCredits(
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Docstring drift.

“This should” say “Blocks fees for a payload” not “request count”. Update the NatSpec to match the payloadId flow.

-    /// @notice Blocks fees for a request count
+    /// @notice Blocks fees for a payload
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// @notice Blocks fees for a request count
/// @param requestCount_ The batch identifier
/// @param payloadId_ The payload id
/// @param consumeFrom_ The fees payer address
/// @param credits_ The total fees to block
/// @dev Only callable by delivery helper
function blockCredits(
/// @notice Blocks fees for a payload
/// @param payloadId_ The payload id
/// @param consumeFrom_ The fees payer address
/// @param credits_ The total fees to block
/// @dev Only callable by delivery helper
function blockCredits(
🤖 Prompt for AI Agents
In contracts/evmx/fees/FeesManager.sol around lines 92 to 97, the NatSpec
title/description is incorrect: it currently says "Blocks fees for a request
count" but the function operates on a payloadId; update the docstring to say
"Blocks fees for a payload" (and adjust any other mentions of "request count" to
"payload" or "payloadId" so the documentation matches the function parameters
and behavior).

uint40 requestCount_,
bytes32 payloadId_,
address consumeFrom_,
uint256 credits_
) external override onlyRequestHandler {
) external override onlyWatcher {
if (balanceOf(consumeFrom_) < credits_) revert InsufficientCreditsAvailable();

userBlockedCredits[consumeFrom_] += credits_;
requestBlockedCredits[requestCount_] = credits_;
emit CreditsBlocked(requestCount_, consumeFrom_, credits_);
requestBlockedCredits[payloadId_] = credits_;
emit CreditsBlocked(payloadId_, consumeFrom_, credits_);
}

/// @notice Unblocks fees after successful execution and assigns them to the transmitter
/// @param requestCount_ The request count of the executed batch
/// @param payloadId_ The payload id
/// @param assignTo_ The address of the transmitter
function unblockAndAssignCredits(
uint40 requestCount_,
bytes32 payloadId_,
address assignTo_
) external override onlyRequestHandler {
uint256 blockedCredits = requestBlockedCredits[requestCount_];
) external override onlyWatcher {
uint256 blockedCredits = requestBlockedCredits[payloadId_];
if (blockedCredits == 0) return;

address consumeFrom = _getRequestParams(requestCount_).requestFeesDetails.consumeFrom;
// address consumeFrom = _getRequestParams(requestCount_).requestFeesDetails.consumeFrom;
address consumeFrom = overrideParams.consumeFrom;

// Unblock credits from the original user
userBlockedCredits[consumeFrom] -= blockedCredits;
Expand All @@ -132,20 +129,21 @@ contract FeesManager is Credit {
_mint(assignTo_, blockedCredits);

// Clean up storage
delete requestBlockedCredits[requestCount_];
emit CreditsUnblockedAndAssigned(requestCount_, consumeFrom, assignTo_, blockedCredits);
delete requestBlockedCredits[payloadId_];
emit CreditsUnblockedAndAssigned(payloadId_, consumeFrom, assignTo_, blockedCredits);
}

function unblockCredits(uint40 requestCount_) external override onlyRequestHandler {
uint256 blockedCredits = requestBlockedCredits[requestCount_];
function unblockCredits(bytes32 payloadId_) external override onlyWatcher {
uint256 blockedCredits = requestBlockedCredits[payloadId_];
if (blockedCredits == 0) return;

// Unblock credits from the original user
address consumeFrom = _getRequestParams(requestCount_).requestFeesDetails.consumeFrom;
// address consumeFrom = _getRequestParams(requestCount_).requestFeesDetails.consumeFrom;
address consumeFrom = overrideParams.consumeFrom;
userBlockedCredits[consumeFrom] -= blockedCredits;

delete requestBlockedCredits[requestCount_];
emit CreditsUnblocked(requestCount_, consumeFrom);
delete requestBlockedCredits[payloadId_];
emit CreditsUnblocked(payloadId_, consumeFrom);
}

/**
Expand Down
19 changes: 0 additions & 19 deletions contracts/evmx/helpers/AddressResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ abstract contract AddressResolverStorage is IAddressResolver {
// slot 52
IAsyncDeployer public override asyncDeployer__;

// slot 53
IDeployForwarder public override deployForwarder__;

// slot 54
address public override defaultAuctionManager;

// slot 55
mapping(bytes32 => address) public override contractAddresses;
Comment on lines 32 to 33
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Incorrect storage slot comment.

The comment claims contractAddresses is at slot 55, but gasAccountToken__ already occupies slot 55. This mapping is actually at slot 56.

Apply this diff:

-    // slot 55
+    // slot 56
     mapping(bytes32 => address) public override contractAddresses;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// slot 55
mapping(bytes32 => address) public override contractAddresses;
// slot 56
mapping(bytes32 => address) public override contractAddresses;
🤖 Prompt for AI Agents
In contracts/evmx/helpers/AddressResolver.sol around lines 32 to 33, the inline
comment incorrectly states the storage slot for contractAddresses as slot 55;
update the comment to reflect the correct storage slot 56 by changing the
comment from "// slot 55" to "// slot 56" so it matches the existing
gasAccountToken__ allocation.

Expand Down Expand Up @@ -75,20 +70,6 @@ contract AddressResolver is AddressResolverStorage, Initializable, Ownable {
emit AsyncDeployerUpdated(asyncDeployer_);
}

/// @notice Updates the address of the default auction manager
/// @param defaultAuctionManager_ The address of the default auction manager
function setDefaultAuctionManager(address defaultAuctionManager_) external override onlyOwner {
defaultAuctionManager = defaultAuctionManager_;
emit DefaultAuctionManagerUpdated(defaultAuctionManager_);
}

/// @notice Updates the address of the deploy forwarder
/// @param deployForwarder_ The address of the deploy forwarder
function setDeployForwarder(address deployForwarder_) external override onlyOwner {
deployForwarder__ = IDeployForwarder(deployForwarder_);
emit DeployForwarderUpdated(deployForwarder_);
}

/// @notice Updates the address of a contract
/// @param contractId_ The id of the contract
/// @param contractAddress_ The address of the contract
Expand Down
14 changes: 4 additions & 10 deletions contracts/evmx/helpers/AddressResolverUtil.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ abstract contract AddressResolverUtil {
/// @notice Restricts function access to the watcher precompile contract
/// @dev Validates that msg.sender matches the registered watcher precompile address
modifier onlyWatcher() {
if (!_isWatcher(msg.sender)) revert OnlyWatcherAllowed();
if (!isWatcher()) revert OnlyWatcherAllowed();
_;
}

function _isWatcher(address account_) internal view returns (bool) {
return (watcher__().isWatcher(account_) || account_ == address(watcher__()));
/// @notice Restricts function access to the watcher owner
function isWatcher() internal view returns (bool) {
return msg.sender == address(watcher__()) || msg.sender == watcher__().owner();
}

/// @notice Gets the watcher precompile contract interface
Expand All @@ -51,13 +52,6 @@ abstract contract AddressResolverUtil {
return addressResolver__.asyncDeployer__();
}

/// @notice Gets the deploy forwarder contract interface
/// @return IDeployForwarder interface of the registered deploy forwarder
/// @dev Resolves and returns the deploy forwarder contract for interaction
function deployForwarder__() public view returns (IDeployForwarder) {
return addressResolver__.deployForwarder__();
}

/// @notice Internal function to set the address resolver
/// @param _addressResolver The address of the resolver contract
/// @dev Should be called in the initialization of inheriting contracts
Expand Down
14 changes: 7 additions & 7 deletions contracts/evmx/helpers/AsyncDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ contract AsyncDeployer is AsyncDeployerStorage, Initializable, AddressResolverUt
/// @return newAsyncPromise The address of the deployed AsyncPromise proxy contract
function deployAsyncPromiseContract(
address invoker_,
uint40 requestCount_
bytes32 payloadId_
) external override onlyWatcher returns (address newAsyncPromise) {
// creates init data and salt
(bytes32 salt, bytes memory initData) = _createAsyncPromiseParams(invoker_, requestCount_);
(bytes32 salt, bytes memory initData) = _createAsyncPromiseParams(invoker_, payloadId_);
asyncPromiseCounter++;

// deploys the proxy
Expand Down Expand Up @@ -131,18 +131,18 @@ contract AsyncDeployer is AsyncDeployerStorage, Initializable, AddressResolverUt

function _createAsyncPromiseParams(
address invoker_,
uint40 requestCount_
bytes32 payloadId_
) internal view returns (bytes32 salt, bytes memory initData) {
bytes memory constructorArgs = abi.encode(
requestCount_,
payloadId_,
invoker_,
address(addressResolver__)
);

// creates init data
initData = abi.encodeWithSelector(
AsyncPromise.initialize.selector,
requestCount_,
payloadId_,
invoker_,
address(addressResolver__)
);
Expand Down Expand Up @@ -183,9 +183,9 @@ contract AsyncDeployer is AsyncDeployerStorage, Initializable, AddressResolverUt
/// @return The predicted address of the AsyncPromise proxy contract
function getAsyncPromiseAddress(
address invoker_,
uint40 requestCount_
bytes32 payloadId_
) public view override returns (address) {
(bytes32 salt, ) = _createAsyncPromiseParams(invoker_, requestCount_);
(bytes32 salt, ) = _createAsyncPromiseParams(invoker_, payloadId_);
return _predictProxyAddress(salt, address(asyncPromiseBeacon));
}

Expand Down
Loading