# Contract signatures and oracles: context, freshness and units

Test signed-action context and price-consumer assumptions with local keys, mock feeds and explicit negative controls.

## Investigation sequence

1. Record trust contract
2. Prove valid baseline
3. Vary one binding
4. Vary feed metadata
5. Calculate consequence

## 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 invariants

Create two locally deployed verifier instances, a local-only signer, two ordinary actors and a mock feed whose state you can vary. Write the expected signed action as a tuple: signer, action type, recipient, amount, nonce, deadline, chain and verifying contract. Record which fields the application intentionally binds. The invariant is: **a signed instruction permits only its intended action and replay policy**. EIP-712 defines typed hashing and domain separation; replay protection remains the application's responsibility. [EIP-712](https://eips.ethereum.org/EIPS/eip-712)

For price consumers, record base/quote currency, feed decimals, token decimals, supported price range, freshness policy and dependency-failure behavior. The invariant is: **an accepted observation has the meaning and validity required for the resulting economic decision**. Chainlink exposes round metadata and timestamps; consumers must interpret them in their own integration. [Chainlink data-feed API](https://docs.chain.link/data-feeds/api-reference)

## Controlled procedure

1. **Prove both baselines.** A valid local signature executes its harmless ledger action once. A fresh positive-price feed produces the expected collateral or quote calculation. Verify an invalid signature and an explicitly disallowed stale observation are rejected, where that policy is part of the product's contract.
2. **Vary one signature dimension.** After the valid action, replay exactly the same bytes. Then use fresh baselines to vary only the recipient, amount, action type, verifier instance, chain context or expired timestamp. Record the recovered signer and nonce-consumption point. A reverting transaction normally rolls back its state; prove whether the replay state survives a successful action rather than assuming a pre-revert write consumed the nonce.
3. **Check alternate signer paths.** If contract wallets are supported, compare an owned wallet returning the ERC-1271 success value `0x1626ba7e`, a wallet returning a different value, and a reverting wallet. A non-reverting call alone does not establish a valid signature. ERC-1271 validity can depend on current contract state: change the authorized local signer after a valid baseline and repeat only where the consumer promises current authorization. Record validation at execution versus an intentionally earlier irrevocable authorization. Do not classify unsupported signature formats as a vulnerability. Reuse [identity and session binding](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/modules/identity-session.html) for off-chain issuance. [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271).
4. **Vary feed metadata.** Starting from a valid response, test an old timestamp, zero or negative answer where the feed type can produce it, changed decimals, failed feed call and mismatched quote currency. Keep all other fields realistic. Demonstrate the consumer's accepted result and economic effect; an artificial impossible feed response is a robustness result until reachable conditions are shown.
5. **Test L2 recovery if applicable.** Model sequencer down, just restarted and beyond the configured grace period separately. This is integration-specific: not every chain or feed uses identical checks. Chainlink's L2 guidance explains uptime signals and post-recovery grace periods. [L2 sequencer feeds](https://docs.chain.link/data-feeds/l2-sequencer-feeds)
6. **Calculate the consequence.** Compare collateral, debt, quote or liquidation outcome with an independently calculated expectation. Include price units, rounding, capital, timing, fees and user constraints. A missing named check without a reachable incorrect decision remains a review lead.

## Local cheat sheet and case matrix

Implement these names in your reviewed local Foundry harness; they are not scanner features. The signer key must be generated or hard-coded solely for this disposable local fixture.

```bash
rg -n 'ecrecover|nonces|deadline|DOMAIN_SEPARATOR|latestRoundData|decimals' src
forge test --match-test '^test_ValidSignature$' -vvvv
forge test --match-test '^test_ReplayRejected$' -vvvv
forge test --match-test '^test_WrongDomainRejected$' -vvvv
forge test --match-test '^test_StaleFeedRejected$' -vvvv
forge test --match-test '^test_PriceUnitInvariant$' -vvvv
```

`--match-test` selects target-specific tests and trace verbosity helps identify the accepted transition. Use preinstalled compiler/dependencies and no RPC/fork/FFI setup for these local fixtures. [Foundry test reference](https://www.getfoundry.sh/reference/forge/test)

| Comparison | Hold constant | Vary |
|---|---|---|
| Replay | Signature, actor, verifier | Prior successful consumption |
| Domain | Message and signature | Local verifier or chain context |
| Freshness | Price and units | Observation timestamp |
| Unit conversion | Economic value | Supported decimal representation |

## Evidence and checklist

- [ ] Exact message schema, domain and successful baseline are saved.
- [ ] Only one context field changes in each negative case.
- [ ] Mock feed deviations are separated from reachable attacker powers.
- [ ] Nonces, timestamps, units and downstream decisions appear in evidence.
- [ ] No real signatures, transactions or funds are used.

## Vulnerability reverse references

- [Signed contract action can be replayed unexpectedly](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/contract-signature-replay.html) — A successfully consumed authorization remains reusable despite a one-use or otherwise bounded execution contract.
- [Signed action does not bind its intended context](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/contract-signature-context.html) — A valid signature is accepted for another recipient, action, verifier or chain context contrary to the authorization contract.
- [Oracle freshness or dependency state permits an invalid decision](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/contract-stale-oracle.html) — A consumer accepts an observation outside its required freshness or availability conditions and makes an incorrect economic decision.
- [Oracle denomination or decimal conversion is incorrect](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/contract-oracle-unit-confusion.html) — The consumer mixes quote currencies, token precision or feed precision and assigns the wrong economic value.
