# User can bypass staking restrictions through composer and deposit on another chain

Restricted staker bypasses SOFT_RESTRICTED_STAKER_ROLE by depositing via wiTryVaultComposer cross-chain path, receiving wiTRY on a spoke chain.

- Payout: Contest reward
- Severity: medium
- Program: Brix Money
- Credited: harry
- Disclosed: 2026-02-10
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2025-11-brix-money#m-01
- Library page: https://bugbountylibrary.com/r/c4%3A2025-11-brix-money%3AM-01
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:chained technique:source-review vuln:access-control vuln:business-logic

**Target:** wiTryOFTAdapter / wiTryVaultComposer cross-chain staking flow
**Root cause:** VaultComposerSync._deposit() calls VAULT.deposit() as address(this) without checking the _depositor's SOFT/FULL_RESTRICTED_STAKER_ROLE, so restriction roles on StakediTry are never propagated into the LayerZero compose path.
**Steps:**
1. Admin blacklists user via addToBlacklist() with SOFT_RESTRICTED_STAKER_ROLE on StakediTry hub vault.
2. User calls `wiTryOFTAdapter.send()` with 100e18 iTRY, routing through LayerZero endpoint.
3. Endpoint invokes `lzCompose()` -> `handleCompose()` -> `_depositAndSend()` -> `_deposit()`.
4. `_deposit()` calls `VAULT.deposit(_assetAmount, address(this))` as the composer, bypassing the user's restriction.
5. Shares are sent via SHARE_OFT to the spoke chain; user receives wiTRY on OP Sepolia.
**How found:** Code review of the cross-chain deposit path: noticed _deposit() uses address(this) as the vault depositor and that _depositor parameter is unused, so StakediTry's restriction roles are never consulted.
**Exploitation:** Restricted user deposits iTRY through the OFT adapter's cross-chain compose flow; the composer contract (not the user) is the vault depositor, so restriction checks never fire, and wiTRY shares are minted to the user on the destination chain.
**Insight:** When a vault enforces role-based restrictions on msg.sender, any peripheral contract (composer, adapter, router) that deposits on behalf of users becomes a restriction bypass unless it re-checks the original depositor's roles; grep for unused _depositor-style params in cross-chain compose handlers.
