# Contract state: authorization, callbacks and accounting

Turn protocol promises into explicit invariants and test realistic local operation sequences with independent accounting.

## Investigation sequence

1. Resolve implementation
2. Write unit-aware invariants
3. Build actor baseline
4. Exercise sequences
5. Minimize state trace

## Used in these playbooks

[Web3 & protocols](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/web3.html) · [OSS & self-hosted](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/oss.html)

## Setup and security invariant

Prepare a reviewed local checkout with dependencies and compiler already available. Use a private local EVM test harness; keep wallet secrets absent and review configuration for FFI, RPC endpoints and fork creation before execution. Record commit, compiler settings, proxy family, implementation, initialized roles and supported token behavior. A local reproduction against a simplified model explains an idea; an eligible report must establish that the same path exists in the relevant deployed implementation.

Write properties using explicit units: assets, shares, debt, fees and time. For example, **redeeming a claim cannot pay more assets than its defined entitlement**, and **an ordinary actor cannot change the implementation or initialize an already initialized proxy**. Do not equate token balance and share supply. Reuse the [authorization matrix](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/modules/authz-matrix.html) for actors and protected transitions. OpenZeppelin documents proxy-specific initialization and upgrade behavior, so inspect the actual family and version. [OpenZeppelin proxies](https://docs.openzeppelin.com/contracts/5.x/api/proxy)

## Controlled procedure

1. **Build realistic actors.** Separate setup administrator, ordinary depositor A, depositor B and callback receiver. Setup may allocate synthetic tokens, but record each privilege and stop using administrator impersonation before the candidate sequence. Verify a normal deposit/redemption round trip and expected privileged-operation rejection.
2. **Trace callbacks.** Mark every external call and the state visible at that instant. Give an owned callback contract one bounded reentry attempt into the original or a related function. Compare with a receiver that accepts the callback without reentry. Solidity warns that reentrancy concerns external contract calls and interacting contracts, not only Ether transfers. [Solidity security considerations](https://docs.soliditylang.org/en/latest/security-considerations.html)
3. **Track independent accounting.** Record user assets, shares, protocol holdings, debts and fees before and after every action. Calculate the expected relationship independently of the implementation under test. For rounding, test zero supply, minimal amounts, mixed decimals, partial redemption and a direct donation, using only supported tokens. Quantify attacker cost as well as victim loss. ERC-4626 conversions and donations can expose rounding-sensitive states. [OpenZeppelin ERC-4626](https://docs.openzeppelin.com/contracts/5.x/erc4626)
4. **Exercise ordering.** Try short valid sequences: deposit → transfer shares → redeem; deposit → donate → second deposit; callback → related read/write; initialize → initialize again. Change one amount, role or order at a time. Count successful state-changing calls so an all-revert fuzz run cannot be mistaken for coverage.
5. **Minimize the failure.** Reduce the sequence and amounts while preserving the violated property. Run the identical sequence with the benign callback or corrected authorization as a control. Preserve the earliest inconsistent state as well as the final balance difference.

## Harness and command cheat sheet

Create target-specific test functions; the names below are a suggested harness contract, not built-in Foundry scans.

| Function | Required assertion |
|---|---|
| `test_BaselineRoundTrip` | Expected fees and rounding explain final balances |
| `test_UnauthorizedUpgradeDenied` | Ordinary actor cannot alter implementation |
| `test_CallbackInvariant` | Bounded callback preserves the chosen property |
| `test_MinimizedSequence` | Replays exact candidate and checks measured effect |

```bash
git rev-parse HEAD
forge --version
rg -n 'ffi|rpc_endpoints|createFork|createSelectFork' foundry.toml test
forge test --match-test '^test_BaselineRoundTrip$' -vvvv
forge test --match-test '^test_CallbackInvariant$' -vvvv
forge test --match-test '^test_MinimizedSequence$' -vvvv
```

Run only after the named local tests exist and their setup has been reviewed. `--match-test` selects your tests; verbosity exposes local traces. These commands do not broadcast transactions, but test code can explicitly access external resources, which is why harness review matters. [Foundry test reference](https://www.getfoundry.sh/reference/forge/test)

## Evidence, false positives and completion

Provide the implementation identity, exact harness, trace, initial capital, privileges, unit-aware balance sheet and bounded impact. Exclude unsupported malicious-token assumptions, fabricated oracle authority, admin-only behavior working as designed, and a callback that cannot occur in the real path.

- [ ] Baseline exercises the same implementation and setup.
- [ ] Actor powers match the claimed attack model.
- [ ] Successful transitions and reverts are counted.
- [ ] Loss is demonstrated independently of total value locked.
- [ ] Reproduction stays entirely in the local EVM.

## Vulnerability reverse references

- [Contract callback reentrancy violates a state invariant](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/contract-reentrant-state.html) — Nested calls observe or alter state under assumptions that do not hold while an earlier operation is incomplete.
- [Contract initializer permits unauthorized ownership or configuration](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/contract-unprotected-initializer.html) — A reachable initialization path lets an ordinary actor establish or replace privileged state outside the intended deployment lifecycle.
- [Contract upgrade authority can be bypassed](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/contract-upgrade-authorization.html) — An actor outside the upgrade policy can change a proxy’s execution target or equivalent privileged configuration.
- [Vault share conversion or rounding breaks entitlement](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/contract-share-accounting.html) — Conversions, fees or rounding create an unintended claim on assets or an eligible loss under supported token behavior.
