{"assessments":[],"deployments":[],"fuzz":[],"identity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"interpretation":"Records acceptance and evidence. Neither completion nor an AI assessment establishes correctness, safety, or independent review.","jobId":"c7efa792-d9f8-403d-9157-d7d1660f2b24","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"f697eb4cf8fd3e4eddb6ef5748f410ec131e9dbdd38cdef7b57da31757b89a89","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"245ee7ed9bec4d1b10b3f83df7483f6d29850031e81832dfa4d0000d99205b9b","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"37e2565be549f97ead229e8ffe3b530fdbfd940b64feef13df53a0fbc67df6ae","dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"3014f1ea5961918ca059453a484bf4c8bcbbfc2248dbe31d94ac7c5cdf8f50bd","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"3014f1ea5961918ca059453a484bf4c8bcbbfc2248dbe31d94ac7c5cdf8f50bd","skillId":"audit-judge","state":"accepted"},{"acceptedSubmissionHash":"913722ba3fb66bf51d5408a555bccbfdeb6767a96fd82ecfdc6d738c1631e6d0","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"e5837726e0a8355af2c8c57a824b084f856bccde55f79a78629a740d90a98a32","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"675a8fde125ed64e7ab8b94ea6dce55eec9e8cb7e6e9ef3616c7e1e39b860d59","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"b6503de65ad02f845827887c23da4c3b56ccc5df7a459db263bae6e549d92f7f","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"b6503de65ad02f845827887c23da4c3b56ccc5df7a459db263bae6e549d92f7f","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"c000c4a4cae6aa3eae572a9c17e26903c9a0528f7d11b27a3546352433cd40d5","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"31115b1cf5176de25131e376ba645691578a862a302a9d44ce926c13181c8812","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","state":"accepted"}],"objective":"Basket Protocol vault: an index vault for Stock Tokens on Robinhood Chain (chain id 4663). Contracts only: no launch token, pool or website. BASK is the vault's own ERC-20 share (18 decimals). Write \"Stock Tokens\", never \"tokenized\"; no Robinhood name, logo or ticker beyond the chain's name.\nToken name: Basket\nToken symbol: BASK\nTotal supply: 0 at deployment, no cap: deposit mints, redeem burns\n\nBUILD RULES\n- Simplest code that satisfies this text: add no feature, role, setting or safeguard.\n- solc 0.8.26, optimizer on, 200 runs, evm cancun, bytecode_hash none; custom errors.\n- If BaskVault exceeds 24,000 bytes of runtime, move views into BaskLens(address vault = $contract:BaskVault); never drop a check.\n- Constructors call no other contract. Time is block.timestamp, never block.number.\n- No proxy, delegatecall, selfdestruct, rescue or sweep. User-facing state changes are nonReentrant and emit events.\n\nMANIFEST\n1. BaskVault(address owner_, address guardian_): owner_ = 0x30B57ECf51D19ABcED7F6f70974e6fBb6f3b9Da3, guardian_ = 0x5ed39AF86f2C00ad99913B5d727bD68f2A904B68, written as these literals. Reverts if either is zero or they are equal.\nSTOCK_FACTORY = 0x4783C67b63dE2B358Ac5951a7D41F47A38F3C046 is a source constant.\n\nOutside contracts (on chain 4663 only; tests mock exactly these functions under test/; no fork tests, no vm.env):\n- Stock Token: ERC-20, 18 decimals, uid() returns bytes32, oraclePaused() returns bool.\n- STOCK_FACTORY.tokenAddress(bytes32 uid) returns address.\n- Feed: Chainlink proxy: decimals() is 8, aggregator() returns address, latestRoundData(); answer = USD per whole token.\n\nASSETS: a list of (token, feed, open, retired, minAnswer, maxAnswer), at most 64, empty at deployment, never removed. managed[token] is the accounting balance: value never uses balanceOf and tokens sent directly are ignored.\nListing checks, at proposal and again at execution: token not listed; token.decimals() == 18; STOCK_FACTORY.tokenAddress(token.uid()) == token; feed.decimals() == 8; feed.aggregator() != 0; feed not used by another unretired asset; answer > 0. On listing open = true, minAnswer = answer / 4, maxAnswer = answer * 4.\nGenesis: until the owner calls finalizeGenesis() (once, needs 3 or more assets), proposeAsset(token, feed) and proposeAssets(tokens[], feeds[]) list at once and deposits are impossible. Deposits open 72 hours after finalizeGenesis().\nOwner proposals (genesis listing is direct): list an asset; replace an asset's feed (feed checks and new answer inside the band, both times); re-centre a band on the answer at execution, under 26 hours old; reopen an asset (cancelled by any later close); retire an asset (closed both times); replace the guardian; raise NAV_CAP. A proposal waits 7 days, then anyone may execute it; it lapses 7 days later; the owner may cancel it, as may the guardian unless it replaces the guardian. One listing or feed replacement executes per 24 hours. A retired asset is closed for good, voids its pending and new proposals, is skipped by every deposit check, 0 in NAV.\n\nPRICE is valid only if the feed read succeeds (100,000 gas), answer > 0, minAnswer <= answer <= maxAnswer, updatedAt <= now, now - updatedAt <= 26 hours, and token.oraclePaused() returns false (100,000 gas). value(amount) = amount * answer / 1e8, rounded down (USD, 18 decimals). USD limits below are dollars times 1e18.\n\ndeposit(token, amount, receiver, minSharesOut, deadline) requires:\n- deposits open and not paused; token listed and open, vault balance >= totalOwed[token]; receiver not the vault;\n- market gate: (now / 86400 + 4) % 7 is 1 to 5 (0 = Sunday) and 55800 <= now % 86400 < 70200; and 3 or more listed assets have feed updatedAt within the last 4 hours;\n- a valid price for this token and every asset with managed > 0; no asset short or unreadable (see LOSSES).\nPull the tokens; the vault balance must rise by exactly amount. NAV = sum of value(managed) before the deposit; v = value(amount).\ngross = v if totalSupply is 0, else v * totalSupply / NAV rounded down (revert if NAV is 0). fee = gross * 50 / 10000, rounded up: minted to feeRecipient, or not minted while that is unset. The receiver gets gross - fee; on the first deposit 1e15 of that goes to address(0xdEaD) instead. The receiver's amount must be > 0 and >= minSharesOut.\nCaps after the deposit, with NAV2 = NAV + v:\n- NAV2 <= NAV_CAP (starts 1,000,000; the owner lowers it at once, cancelling pending raises, raises it by proposal, never above 10,000,000,000);\n- bucket <= max(NAV2 * 25 / 100, 100,000): one bucket for all deposits, which first decays (bucket -= bucket * elapsed / 86400, floor 0), then adds v.\n\nredeem(shares, minAmountsOut[], deadline) reads no price, ignores every pause and gate, and never reverts because of an asset. fee = shares * 50 / 10000 rounded up: transferred to feeRecipient, or burned with the rest while unset. net = shares - fee is burned. Per asset: available = balanceOf(vault) - totalOwed[token], floor 0 (low-level static call, 50,000 gas, copying 32 bytes; any other outcome: unreadable, available = managed); leg = min(managed, available) * net / totalSupplyBeforeBurn, rounded down; require leg >= minAmountsOut[i] (missing entry = 0); managed -= leg. Each leg is paid to msg.sender by an external function only the vault itself may call, given 250,000 gas, which reverts unless the transfer succeeds, returns nothing or true, and the vault balance falls by exactly leg. If it fails, owed[msg.sender][token] and totalOwed[token] grow by leg. claim(token, to), to not zero, pays min(caller's owed, vault balance) by the same function with no gas limit.\n\nLOSSES. An asset is short when available < managed. Nothing lowers managed automatically. flagDeficit(token), by anyone, records shortfall and time if larger than recorded. recognizeLoss(token), by anyone 7 days or more later, lowers managed by min(recorded, current shortfall) and clears the record. A deposit clears unretired records.\n\nWho can call what:\n- Owner (two-step transfer, never to the guardian, no renounce): the proposals; cancel; close an asset to deposits at once; pause and unpause deposits; lower NAV_CAP; setFeeRecipient(address) once, not zero or the vault, final. The vault never calls feeRecipient.\n- Guardian: pause deposits, close an asset, cancel proposals as stated.\n- Nobody can move assets, block redeem or claim, mint outside deposit, change a fee or upgrade.\nUpgrades and pausing: none except the deposit pause and per-asset close.\nNumbers the contracts enforce: all constants except NAV_CAP.\n\nVIEWS: all assets with feed, answer, updatedAt, band, open, retired, managed, short, totalOwed; previewDeposit; previewRedeem; depositStatus(token): a reason code and the asset at fault, as in deposit's revert; pending proposals.\n\nREVIEW. Accepted design, note only, add no mechanism: (1) deposit-then-redeem profit when a feed lags more than the 1% round-trip fee; (2) the owner pairs each token with its true feed; (3) an untransferable asset keeps its feed value until deposits are paused; (4) a retired asset counts 0 in NAV; (5) no per-asset limit: one asset may be any share of NAV. MUST ATTACK: redeem with paused, blocked or upgraded tokens (64 assets in any state: under 28,000,000 gas); any way a role blocks redeem.","parentJobId":null,"planHash":"19b3ac0790e9d551cfb82a70d022da1a4f6c627dedcbe5cf5e85dc78704089df","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"c7efa792-d9f8-403d-9157-d7d1660f2b24","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-929-basket"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52162","feedbackHash":"12754e9028138ecf75a18ba4b636a06cf461a1745f902f24ac0d95d101cb5feb","nodeKey":"audit_economics","submissionHash":"f697eb4cf8fd3e4eddb6ef5748f410ec131e9dbdd38cdef7b57da31757b89a89","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52170","feedbackHash":"ee44cd370bcc9326c986f1797b886a35a642dffafba383468dba6ab743803dd9","nodeKey":"audit_flow","submissionHash":"245ee7ed9bec4d1b10b3f83df7483f6d29850031e81832dfa4d0000d99205b9b","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51125","feedbackHash":"4bc0a8987b10aa3203f339b83038c78d286156a3230f8e4bc0ecf154a91e2327","nodeKey":"audit_judge","submissionHash":"37e2565be549f97ead229e8ffe3b530fdbfd940b64feef13df53a0fbc67df6ae","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51316","feedbackHash":"fca079ce70c77ff2dc5a8a57a3270ca130d10fba7d0715a6825cb83260da6822","nodeKey":"audit_judge","submissionHash":"b476ef0b908a00bb64a34439630127aa0cb0855dd5cfe1eb1a94d8af6883d668","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52160","feedbackHash":"88ed932d7b71feaf9faefdda88d7e4816217fb6da48f4972a071452eeb011c46","nodeKey":"audit_math","submissionHash":"913722ba3fb66bf51d5408a555bccbfdeb6767a96fd82ecfdc6d738c1631e6d0","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52176","feedbackHash":"30a5987368b5fc1782f8a47104a82ab5f21d4e908cf8d7898d15d8eff00e2d75","nodeKey":"audit_permissions","submissionHash":"e5837726e0a8355af2c8c57a824b084f856bccde55f79a78629a740d90a98a32","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51178","feedbackHash":"17056424b45e74dfe56c07aed81110e028e4610cb038832f6e415253e492a5ef","nodeKey":"build_contract_project","submissionHash":"675a8fde125ed64e7ab8b94ea6dce55eec9e8cb7e6e9ef3616c7e1e39b860d59","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52371","feedbackHash":"96028cfe8e799ed921b89414ef96dcecac8b4fe84cd5f7e35e79c883a533335a","nodeKey":"build_contract_project","submissionHash":"94786519427eb45010402184c91c1013a22c82cf55375623c14ef322a819c58b","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51085","feedbackHash":"fe41e2c40f786a43ccfd671967b83c48c35160b8481e5bca4972e4cf9be979c9","nodeKey":"manifest","submissionHash":"1f768736ab16479c3d0f727b0959958a92c25f94ec8002188b5e7641539ccff2","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"50979","feedbackHash":"6b6c09aa558595c76c82172ce6e4449a0f9a3b6d8f382ffd2c6a92739ded5b36","nodeKey":"manifest","submissionHash":"c000c4a4cae6aa3eae572a9c17e26903c9a0528f7d11b27a3546352433cd40d5","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51190","feedbackHash":"a44f31fb3d9f1e403c77fee6ce3e48fbbade2a759d5e82565cfbbe62f97f6289","nodeKey":"write_foundry_tests","submissionHash":"75e9ed1897b2cb8c075d190941d7b8ddba8bf1d65c0efcb892ecec63b20a02e1","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51208","feedbackHash":"7a4133631e677c0c0153538a9f142f09c4a5d7470ff6f07dde5bed64ee195755","nodeKey":"write_foundry_tests","submissionHash":"31115b1cf5176de25131e376ba645691578a862a302a9d44ce926c13181c8812","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"ab85ad065782929e4eda34cf98d47946a379937daeb6570a9bb44103ec715a43","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"c4bded1622603be5d1cbc5c5425a987921e6ed7983ba8463f747c08b2bcb8cc3","device":"e8f1969b1b8ff9d4","findings":[],"hash":"1f768736ab16479c3d0f727b0959958a92c25f94ec8002188b5e7641539ccff2","nodeId":"131c3a12-bbbd-426e-b1ee-cfc4c1b70102","outcome":"completed","summary":"Updated [launch.json](/home/imd/.identitymd/work/c7efa792-d9f8-403d-9157-d7d1660f2b24/131c3a12-bbbd-426e-b1ee-cfc4c1b70102/launch.json) with BASK supply details and all five accepted design notes, preserving the exact constructor addresses.\n\nManifest structure and compiled ABI checks passed. `forge build` succeeded; all 57 tests passed, including adversarial redemption checks. Only `launch.json` changed outside permitted scratch files.","treeHash":"97d8ebb77717be6e41d4555c59e90c1b6e47652e","usage":{"cachedInputTokens":225024,"inputTokens":37256,"model":"gpt-6-astra","outputTokens":3462,"runtime":"codex","turns":4,"wallClockMs":201635}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fa99051b60a858d6","findings":[{"citation":"resolved","description":"The manifest gives redeem a 50,000-gas balance read (unreadable => leg deferred to owed) and then says claim(token, to) 'pays min(caller's owed, vault balance) by the same function with no gas limit'. Only the payLeg call itself is uncapped: claim() first reads the vault balance through _balance(), which is _word(token, balanceOf, 50_000) (src/BaskVault.sol:820-822), and payLeg() reads the balance twice through the same 50k-capped helper (lines 641 and 645). Any Stock Token upgraded so that a correct balanceOf costs more than ~48k gas (an extra compliance/registry hop, a per-holder loop, a snapshot lookup) therefore makes redeem defer every leg of that asset to owed as designed, but then makes claim() revert BalanceUnreadable unconditionally, no matter how much gas the caller supplies and even though the tokens sit in the vault and transfer() works. No role can repair this: the asset is never removed, managed/owed are only lowered by claim or recognizeLoss (which also reverts on the same read), and the token is administered by a third party. The 'upgraded tokens' case is one the brief asks to attack explicitly; here the exit survives redeem but dies at claim.","line":654,"path":"src/BaskVault.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {BaskVault} from \"src/BaskVault.sol\";\n\ncontract ProofFactory {\n    mapping(bytes32 => address) public tokenAddress;\n    function set(bytes32 uid, address token) external { tokenAddress[uid] = token; }\n}\n\ncontract ProofFeed {\n    uint8 public constant decimals = 8;\n    address public constant aggregator = address(1);\n    int256 public answer = 100e8;\n    uint256 public updatedAt;\n    function set(uint256 ts) external { updatedAt = ts; }\n    function latestRoundData() external view returns (uint80, int256, uint256, uint256, uint80) {\n        return (1, answer, updatedAt, updatedAt, 1);\n    }\n}\n\n/// A well-behaved Stock Token whose balanceOf becomes more expensive after an upgrade\n/// (still returns the correct balance; it just needs more than 50,000 gas).\ncontract ProofStock {\n    uint8 public constant decimals = 18;\n    bytes32 public uid;\n    mapping(address => uint256) public bal;\n    uint256 public balanceGas;\n    constructor(bytes32 u) { uid = u; }\n    function mint(address to, uint256 amount) external { bal[to] += amount; }\n    function upgrade(uint256 gasNeeded) external { balanceGas = gasNeeded; }\n    function oraclePaused() external pure returns (bool) { return false; }\n    function balanceOf(address who) external view returns (uint256) {\n        uint256 start = gasleft();\n        uint256 need = balanceGas;\n        while (start - gasleft() < need) { assembly { pop(keccak256(0, 32)) } }\n        return bal[who];\n    }\n    function approve(address, uint256) external pure returns (bool) { return true; }\n    function transferFrom(address from, address to, uint256 amount) external returns (bool) {\n        bal[from] -= amount; bal[to] += amount; return true;\n    }\n    function transfer(address to, uint256 amount) external returns (bool) {\n        bal[msg.sender] -= amount; bal[to] += amount; return true;\n    }\n}\n\ncontract ClaimBalanceGasTest is Test {\n    address constant OWNER = 0x30B57ECf51D19ABcED7F6f70974e6fBb6f3b9Da3;\n    address constant GUARDIAN = 0x5ed39AF86f2C00ad99913B5d727bD68f2A904B68;\n    address constant FACTORY = 0x4783C67b63dE2B358Ac5951a7D41F47A38F3C046;\n    address constant ALICE = address(0xA11CE);\n    uint256 constant MONDAY = 20003 days + 55800; // Monday 15:30 UTC\n\n    BaskVault vault;\n    ProofStock stock;\n    ProofFeed[] feeds;\n\n    function setUp() public {\n        vm.chainId(4663);\n        vm.warp(MONDAY - 3 days);\n        vm.etch(FACTORY, address(new ProofFactory()).code);\n        vault = new BaskVault(OWNER, GUARDIAN);\n        for (uint256 i = 1; i <= 3; ++i) {\n            ProofStock s = new ProofStock(bytes32(i));\n            ProofFactory(FACTORY).set(bytes32(i), address(s));\n            ProofFeed f = new ProofFeed();\n            f.set(block.timestamp);\n            feeds.push(f);\n            vm.prank(OWNER);\n            vault.proposeAsset(address(s), address(f));\n            if (i == 1) stock = s;\n        }\n        vm.prank(OWNER);\n        vault.finalizeGenesis();\n        vm.warp(MONDAY);\n        for (uint256 i; i < 3; ++i) feeds[i].set(block.timestamp);\n    }\n\n    /// Fails on the current code: claim() reverts BalanceUnreadable forever, the owed leg is stranded.\n    /// Passes once claim's balance reads (claim and the payLeg frame it calls) are not capped at 50,000 gas.\n    function testOwedLegClaimableWhenBalanceOfNeedsMoreThan50kGas() public {\n        stock.mint(ALICE, 10e18);\n        vm.startPrank(ALICE);\n        stock.approve(address(vault), 10e18);\n        uint256 shares = vault.deposit(address(stock), 10e18, ALICE, 0, block.timestamp);\n        vm.stopPrank();\n\n        // Token upgraded: balanceOf still correct but needs ~60k gas.\n        stock.upgrade(60_000);\n\n        vm.prank(ALICE);\n        uint256[] memory legs = vault.redeem(shares, new uint256[](0), block.timestamp);\n        assertGt(legs[0], 0);\n        // redeem deferred the leg as specified (balance unreadable within 50k -> payout frame reverts).\n        assertEq(vault.owed(ALICE, address(stock)), legs[0]);\n        assertEq(stock.bal(address(vault)), 10e18);\n\n        // Spec: claim pays min(owed, vault balance) \"with no gas limit\". The vault holds 10e18 of the token.\n        vm.prank(ALICE);\n        uint256 paid = vault.claim{gas: 5_000_000}(address(stock), ALICE);\n        assertEq(paid, legs[0]);\n        assertEq(stock.bal(ALICE), legs[0]);\n        assertEq(vault.owed(ALICE, address(stock)), 0);\n    }\n}","reproduction":"State: genesis finalized with 3 assets, Monday 15:30 UTC, fresh feeds. 1) ALICE deposits 10e18 of token T (balanceOf costs normal gas) and receives shares. 2) T is upgraded so balanceOf(address) still returns the right number but consumes 60,000 gas. 3) ALICE calls redeem(shares, [], now): _available is unreadable => available = managed, leg = 9.94999e18 is computed, payLeg's first _balance fails => frame reverts => owed[ALICE][T] = leg, totalOwed[T] = leg, vault still holds 10e18 T. Expected per manifest: claim(T, ALICE) with ample gas pays min(owed, 10e18) = leg. Actual: claim{gas: 5_000_000}(T, ALICE) reverts BalanceUnreadable(T) (line 655) and would keep doing so; the leg is unrecoverable. Run: forge test --match-path test/scratch/ClaimBalanceGas.t.sol (fails on current code with BalanceUnreadable).","severity":"medium","snippet":"        (bool ok, uint256 available) = _balance(token);\n        if (!ok) revert BalanceUnreadable(token);","title":"claim() is still gated by the 50,000-gas balance read, so an owed leg of a token whose balanceOf needs more gas is stranded forever"},{"citation":"resolved","description":"Note only; it follows from manifest rules (gross 'revert if NAV is 0', retired asset '0 in NAV', first-deposit 1e15 lock to 0xdEaD). The 0xdEaD shares can never be burned, so totalSupply stays >= 1e15 after the first deposit. If every asset with managed > 0 is retired, or every position is written off through recognizeLoss, NAV becomes 0 while totalSupply != 0 and _snapshot returns ZeroNAV for every token forever; newly listed assets cannot be seeded because any deposit is itself blocked. Redeem/claim still work, so no funds are lost, but the vault cannot be restarted and there is no owner action that recovers it. Worth a line in the operator documentation (retiring the last valued asset is terminal).","line":794,"path":"src/BaskVault.sol","reproduction":"Existing test BaskLossesTest.testNonzeroSupplyWithZeroNAVRejectsDepositsButRedeems reaches the state: deposit 10e18 of asset 0, list asset 4, close + retire asset 0 => depositStatus(asset 1) = ZeroNAV. Additional steps: redeem all of ALICE's shares (totalSupply = 1e15 held by 0xdEaD), warp to any open market time, refresh feeds, try deposit(asset1 or asset4, 1e18, ...): still DepositUnavailable(ZeroNAV, 0) because totalSupply = 1e15 != 0 and NAV = 0. No sequence of owner/guardian/user calls changes this.","severity":"info","snippet":"        if (totalSupply != 0 && s.nav == 0) return _fail(s, Reason.ZeroNAV, address(0));","title":"Once NAV reaches 0 with shares outstanding, deposits are permanently impossible (locked 1e15 shares keep totalSupply nonzero), even after listing new assets"}],"hash":"245ee7ed9bec4d1b10b3f83df7483f6d29850031e81832dfa4d0000d99205b9b","nodeId":"242a220e-8dee-49ef-b718-5be72baee6f4","outcome":"completed","summary":"Review complete. No source files were changed; the only artifact is `.imd-findings.json`.\n\n## Summary\n\n**Scope covered:** Execution Trace, Periphery, and First Principles passes over `src/BaskVault.sol` and `src/BaskMath.sol`, every one of the 27 listed entry points, plus the test suite as a critical reader. Build and all 57 existing tests pass under the pinned toolchain.\n\n**Findings (2):**\n\n1. **Medium — `claim()` strands owed legs when a token's `balanceOf` needs >50k gas** (`src/BaskVault.sol:654`). The manifest says claim pays \"with no gas limit\", but `claim` pre-reads the balance through the 50k-capped `_balance()`, and `payLeg` reads it twice through the same helper. A Stock Token upgraded so a *correct* `balanceOf` costs ~60k gas makes `redeem` defer legs to `owed` as designed, but then `claim` reverts `BalanceUnreadable` forever regardless of gas supplied; `recognizeLoss` hits the same read, and no role can repair it. Self-contained Foundry proof included — it fails on the current code with `BalanceUnreadable` and passes once claim's reads are uncapped.\n\n2. **Info — ZeroNAV is a terminal state.** Because 1e15 shares are locked at `0xdEaD`, `totalSupply` can never return to 0, so once NAV hits 0 (all valued assets retired or written off) deposits are permanently impossible even after listing fresh assets. Consequence of accepted design (4) and the \"revert if NAV is 0\" rule; noted for operator documentation, not a mechanism change.\n\n**What held (notable):**\n- `mulDiv` verified algebraically by fuzz (`r·d ≤ x·y < (r+1)·d` against a 512-bit reference); slither's `incorrect-exp` is a false positive.\n- 64-asset redeem worst case measured at **~22.8M gas** (balanceOf burning just under 50k + transfer consuming the whole 250k frame + fresh `owed`/`totalOwed` slots); above ~48k the balance read fails and the path gets cheaper, so 28M holds with ~5M margin.\n- No role can block `redeem`: fee transfer to `feeRecipient` can't revert, `leg ≤ managed` by construction, `mulDiv` can't overflow there, `payLeg` failures are absorbed.\n- All manifest rules traced against the code; no deviations found in deposit gates, quote/fee/lock math, caps, proposals, voiding, rate limit, loss accounting, or role boundaries.\n\n**Not reached:** nothing within the assigned area; off-area items (economic/oracle-lag analysis beyond the accepted-design notes) were only checked where they intersected execution flow.","treeHash":null,"usage":{"cachedInputTokens":1779932,"inputTokens":36,"model":"claude-fable-5-1","outputTokens":55804,"runtime":"claude","turns":19,"wallClockMs":842465}},{"artifacts":[],"attempt":1,"bundleHash":"9cfc5d0bce72368c945488a19181d6f81e3788022105fd68d985e3cda07f5949","device":"c4f9adf8d634c796","findings":[],"hash":"31115b1cf5176de25131e376ba645691578a862a302a9d44ce926c13181c8812","nodeId":"9efe6d5a-c11e-4bc1-b0f9-02c3ccc67c2f","outcome":"completed","summary":"Added regression tests for redemption rollback across paid and deferred legs, and failed listing execution preserving its proposal and daily allowance.\n\n`forge build` succeeded. `forge test`: **70 passed, 0 failed**, including 1,000 new fuzz cases and 24,576 invariant calls.\n\nChanges are limited to `test/`. No new contract defects were reproduced.","treeHash":"d5b99f72b10d8d71140fa9ef94b5f531089006ed","usage":{"cachedInputTokens":1945344,"inputTokens":131433,"model":"gpt-6-astra","outputTokens":7248,"runtime":"codex","turns":6,"wallClockMs":475733}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"42dc54b22317eb81","findings":[],"hash":"37e2565be549f97ead229e8ffe3b530fdbfd940b64feef13df53a0fbc67df6ae","nodeId":"f3aea595-28f8-4b98-a8de-96437f1004a8","outcome":"completed","summary":"Wrote [`.imd-findings.json`](/home/worker/.identitymd/work/c7efa792-d9f8-403d-9157-d7d1660f2b24/f3aea595-28f8-4b98-a8de-96437f1004a8/.imd-findings.json) with **no unresolved findings** and **27/27 entry points covered**.\n\n| Previous finding | Resolution |\n|---|---|\n| Claim balance-read gas cap | Fixed; supplied proof and expensive-read regressions pass. |\n| Terminal ZeroNAV | Reproduced; documented specified behavior. |\n| Unset fee recipient economics | Reproduced 54 versus 99 bps; documentation corrected. |\n| Atomic feed replacement repricing | Reproduced; operational guidance documented. |\n| Deposit bucket consumption | Reproduced; documentation correctly explains decay. |\n| Unmanaged surplus/restored losses | Both cases reproduced and documented. |\n| Retired-position extraction | Reproduced; accepted-design note documented. |\n\nAll **70 retained tests** and **eight advisory reproductions** passed. Maximum measured 64-asset redemption: **22,795,771 gas**.\n\nThe older specialist proof fails only because it expects deferred payment where redemption now pays immediately. It does not reproduce stranded funds.\n\nScratch tests were removed; source and configuration remain unchanged.","treeHash":null,"usage":{"cachedInputTokens":1113472,"inputTokens":124460,"model":"gpt-6-astra","outputTokens":9276,"runtime":"codex","turns":5,"wallClockMs":511583}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"a9158e223bd79f25","findings":[],"hash":"3ff9539a723222c7da93cf64b2cf79736e47b610e2ce0196fb7e0deeae05f116","nodeId":"131c3a12-bbbd-426e-b1ee-cfc4c1b70102","outcome":"failed","summary":"the task produced no changes; the agent's last message was: `launch.json` already matches the accepted implementation and required literal addresses, so no revision was needed.\n\n- Schema and constructor ABI checks passed.\n- `forge build` succeeded; all 60 tests passed.\n- Runtime: 22,258 bytes.\n- Tested 64-asset redemptions stayed below 28 million gas.\n\nNo tracked files changed.","treeHash":null,"usage":{"cachedInputTokens":337024,"inputTokens":44311,"model":"gpt-6-astra","outputTokens":3564,"runtime":"codex","turns":3,"wallClockMs":121369}},{"artifacts":[],"attempt":1,"bundleHash":"1442422b2d2b456668f4627945d657541c39ab5707b38146b511d6fbee51c91a","device":"41ff1f83c6e68e78","findings":[],"hash":"675a8fde125ed64e7ab8b94ea6dce55eec9e8cb7e6e9ef3616c7e1e39b860d59","nodeId":"8b2934f3-ce98-4edb-8d3f-2e7fa8d2c846","outcome":"completed","summary":"Fixed uncapped balance reads for claims and payouts, with three regression tests. Documented advisory risks while preserving the specified economics. Recorded all seven findings in `.imd-responses.json`.\n\nValidation passed: `forge build`, `forge test` (69 tests), and `forge fmt --check`. Maximum measured 64-asset redemption: 22.80M gas, below 28M.","treeHash":"0b80e8fbfed981abb1d4daeb50c3923a6a69142c","usage":{"cachedInputTokens":938752,"inputTokens":95398,"model":"gpt-6-astra","outputTokens":10889,"runtime":"codex","turns":5,"wallClockMs":307586}},{"artifacts":[],"attempt":1,"bundleHash":"58969c6a5670d8630d81ae40f6554111c2b869e8fb92e5ff1f86a29ef98c923e","device":"107def308610130e","findings":[],"hash":"75e9ed1897b2cb8c075d190941d7b8ddba8bf1d65c0efcb892ecec63b20a02e1","nodeId":"9efe6d5a-c11e-4bc1-b0f9-02c3ccc67c2f","outcome":"completed","summary":"Added stateful accounting and exit-liveness invariants, economic fuzz tests, and failure-path, boundary, and event checks under `test/`.\n\nVerified `forge build` and `forge test`: **65 passed**, including 24,576 random handler calls and two 1,000-case fuzz campaigns.\n\nNo confirmed contract defects found. Only `test/` files were added.","treeHash":"4631baf71fe229fdf655035cbc2f1a5394b5d065","usage":{"cachedInputTokens":1593088,"inputTokens":141454,"model":"gpt-6-astra","outputTokens":19715,"runtime":"codex","turns":6,"wallClockMs":571968}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"cd8076510aad8b8e","findings":[{"citation":"resolved","description":"Seam: precision x invariant. While feeRecipient is unset (the state at deployment, and possibly forever since setFeeRecipient is optional), the deposit fee is deducted from the depositor's shares (src/BaskVault.sol:575-577: gross = value*totalSupply/nav; fee = _fee(gross); shares = gross - fee) but minted to nobody. NAV still rises by the full value v, so the share price rises for every holder, including the depositor who just paid the fee. A depositor who ends up owning fraction p of supply immediately recovers about p * 0.5% of v through the higher share price. The closed form at a constant price is out = 0.995^2 * v * (NAV0 + v) / (NAV0 + 0.995 v), which tends to 0.995 v as v grows relative to NAV0. The redeem fee (burned, line 603) is lost by the redeemer, so the round-trip cost is bounded below by 0.5%, but the brief's accepted design (1) and README state that feed-lag deposit-then-redeem is only profitable when the lag exceeds a 1% round-trip fee. For a depositor that is large relative to the pool the real threshold is ~0.5%, so the lag window that is exploitable is roughly twice as wide as documented. This is a consequence of the brief's own 'not minted while unset' rule, so it is reported as a note on the stated guarantee, not as a code change request; the fix, if any, is a documentation/operations decision (set feeRecipient at launch, or state the 0.5% floor). A fuzz over deposit sizes 1..200e18, seed holders 2e15..200e18, prices 25/100/400 and both fee states confirmed no other rounding leak: the redeemer never recovers more than 0.995 v (3000 runs).","line":566,"path":"src/BaskVault.sol","reproduction":"State: genesis with 3 assets, every feed answer = 100e8 fresh, market open (e.g. timestamp 20003 days + 55800), feeRecipient unset. 1) ALICE deposits 10e18 of asset 0 (value $1,000): totalSupply = 995e18, NAV = $1,000. 2) BOB deposits 100e18 of asset 1 (v = $10,000): gross = 1e22*995e18/1e21 = 9,950e18; fee = 49.75e18 (not minted); BOB shares = 9,900.25e18; supply = 10,895.25e18; NAV = $11,000. 3) BOB immediately redeems all 9,900.25e18 shares: redeem fee = 49.50125e18 (burned); net = 9,850.74875e18; legs = managed_i * net / 10,895.25e18 => BOB receives 9.0413e18 of asset 0 and 90.413e18 of asset 1, worth $9,945.5. Expected (per README/accepted design 1): round trip costs ~1% => about $9,900.25 back. Actual: $9,945.5 back, i.e. 54 bps cost. Control: same sequence with setFeeRecipient(0xFEE) first gives 99 bps. Scratch tests testUnsetFeeRecipientHalvesRoundTripCost / testSetFeeRecipientFullRoundTripCost (test/scratch/SeamProbe.t.sol) log 54 and 99 bps respectively.","severity":"low","snippet":"        if (feeRecipient != address(0)) _mint(feeRecipient, fee);","title":"Unminted deposit fee is partly recovered by the depositor: effective round trip is ~0.5%, not the 1% the accepted feed-lag design assumes"},{"citation":"resolved","description":"Seam: boundary x invariant. The ZeroNAV guard is required by the brief ('revert if NAV is 0'), and the 1e15 shares minted to 0xdEaD on the first deposit can never be burned (0xdEaD cannot call redeem and grants no allowance), so totalSupply is never 0 again after the first deposit. Retired assets are skipped in NAV (src/BaskVault.sol:779 'if (a.retired) continue;') and recognizeLoss can lower managed to 0. Therefore once NAV reaches 0 (the only managed asset is retired, or all managed positions are written off), the first-deposit branch (totalSupply == 0 => gross = value) is unreachable and the second branch is blocked by ZeroNAV forever. Listing new assets does not help because a new asset has managed 0 and contributes nothing to NAV. Given accepted design (5) (one asset may be any share of NAV), a vault concentrated in one Stock Token whose feed dies has exactly one remedy in the brief, retirement, and taking it permanently disables deposits while redemptions keep working. No funds are lost; the vault is reduced to redeem-only. Reported so the operator knows retirement of the last managed asset is irreversible for deposits; if that is unacceptable it needs a scope decision (e.g. allow the first-deposit branch when NAV == 0), which the brief does not currently permit.","line":794,"path":"src/BaskVault.sol","reproduction":"State: genesis with assets A0, A1, A2, all feeds 100e8 and fresh, market open. 1) ALICE deposits 10e18 of A0 (NAV $1,000, supply 995e18, dead 1e15). 2) Owner: closeAsset(A0); proposeRetire(A0); proposeAsset(A3, feed3). 3) +7 days: executeProposal(retire); executeProposal(list A3). Now A1, A2, A3 are open, unretired, fresh (3 fresh feeds), no deficits. 4) depositStatus(A1) returns (ZeroNAV=19, 0x0) and deposit(A1, 1e18, ALICE, 0, now) reverts DepositUnavailable(19, 0). 5) ALICE redeems all her shares (gets A0 pro rata); totalSupply == 1e15 (dead shares only), NAV still 0. 6) Any later time, all feeds fresh: depositStatus(A1) and depositStatus(A3) still return ZeroNAV. Expected: with three healthy listed assets and no live positions, a deposit should be acceptable (as it was at genesis). Actual: deposits are impossible forever. Scratch test testZeroNavIsTerminal (test/scratch/SeamProbe.t.sol) passes on the current code.","severity":"low","snippet":"        if (totalSupply != 0 && s.nav == 0) return _fail(s, Reason.ZeroNAV, address(0));","title":"NAV == 0 with nonzero supply is a terminal state: once every managed asset is retired or fully lost, deposits can never resume, even into newly listed healthy assets"},{"citation":"resolved","description":"Note only, per the brief ('Accepted design, note only, add no mechanism'). Because a retired asset counts 0 in NAV for deposit pricing but is still paid out pro rata by redeem (src/BaskVault.sol:609-611 iterate every asset including retired ones), retirement of an asset holding most of the NAV collapses the share price to the remaining managed value. The next depositor receives supply * v / NAV_residual shares and can immediately redeem a near-total share of the retired asset's balance. No mechanism is requested; the magnitude is recorded so the operator pauses deposits before retiring any asset with a material managed balance.","line":779,"path":"src/BaskVault.sol","reproduction":"State: genesis with A0, A1, A2 at $100, fresh, market open, plus A3 listed later. 1) ALICE deposits 1,000e18 of A0 ($100,000). 2) Next day ALICE deposits 1e16 of A1 ($1). 3) Owner closes and retires A0 (7-day proposal), lists A3. 4) After the executions, NAV = $1 (A1 only), supply ~ 99,500.995e18. 5) BOB deposits 1,000e18 of A2 ($100,000): gross = 1e23 * 99,500.995e18 / 1e18 => BOB owns 9,999 bps of supply. 6) BOB redeems: receives 994e18 of retired A0 (of 1,000e18 held) plus 994e18 of A2. Expected under a fair NAV: BOB should receive about half the vault. Actual: BOB takes ~99.4% of A0 (worth ~$99,400 at the last price) for $100,000 of A2 plus a 1% fee. Scratch test testRetireCollapseQuantified logs bob share 9999 bps, A0 leg 994e18.","severity":"info","snippet":"            if (a.retired) continue;","title":"Accepted design (4) quantified: retiring the dominant asset lets the next depositor take ~99.4% of the retired holdings for the price of the residual NAV"}],"hash":"913722ba3fb66bf51d5408a555bccbfdeb6767a96fd82ecfdc6d738c1631e6d0","nodeId":"c4d9137c-4191-4a81-8eb7-b2ed24d4c9c6","outcome":"completed","summary":"The review is complete and written to `.imd-findings.json` at the repository root. No tracked file was changed; only the findings file and my scratch tests under `test/scratch/` (both git-ignored) were added.\n\n**Outcome: no critical or high defect in the math.** The arithmetic in `BaskVault` matches the brief's formulas, and the custom `mulDiv` is correct. Three lower-severity findings are recorded, each with a concrete reproduction.\n\n**Findings**\n\n1. **Low. Unminted deposit fee is partly recovered by the depositor.** While the fee recipient is unset, the 0.5% deposit fee is deducted from the depositor's shares but minted to nobody, so share price rises for all holders including the depositor. A depositor ten times the pool pays 54 bps round trip instead of the 99 bps the accepted feed-lag design assumes. The exploitable lag window is roughly double what the README states. This follows from the brief's own rule, so it is a note on the stated guarantee.\n\n2. **Low. Zero NAV with nonzero supply is terminal.** The dead shares keep total supply above zero forever, so once the last managed asset is retired or fully written off, the ZeroNAV guard blocks deposits permanently, even after listing new healthy assets. Redeem keeps working. Concrete sequence: one deposit, retire that asset, list a fourth asset, deposit reverts with reason 19 forever.\n\n3. **Info, accepted design 4 quantified.** Retiring the dominant asset collapses NAV to the residual. The next depositor took 99.4% of the retired holdings for a deposit equal to the residual NAV plus fee.\n\n**What held**\n\n- `BaskMath.mulDiv` passed a 512-bit identity check over 8,000 fuzz runs and edge cases. The slither `incorrect-exp` and `divide-before-multiply` leads are false positives on the canonical algorithm.\n- Deposit value, gross shares, ceil fee, 1e15 lock, NAV cap, and bucket limit all match the brief. A 3,000-run round-trip fuzz found no rounding path that returns more than 99.5% of the deposit.\n- Redeem legs floor correctly with supply captured before burn. The 64-asset worst case measured 22.67M gas, under the 28M bound. No role can block redeem or claim.\n- Market gate, price age, band age, and freshness boundaries are as specified, with timestamp underflow paths guarded.\n\n**Coverage:** all 27 listed entry points have rows, plus four invariant rows. Two entry points carry findings (deposit, proposeRetire); the rest hold. Nothing was left unreached.","treeHash":null,"usage":{"cachedInputTokens":2428827,"inputTokens":546,"model":"claude-fable-5-1","outputTokens":60202,"runtime":"claude","turns":32,"wallClockMs":936506}},{"artifacts":[],"attempt":1,"bundleHash":"54fd08e85e0b8ed190af1593cdab8d87944963564e14590962a54d41e02aec54","device":"c69899cad79c228f","findings":[],"hash":"94786519427eb45010402184c91c1013a22c82cf55375623c14ef322a819c58b","nodeId":"8b2934f3-ce98-4edb-8d3f-2e7fa8d2c846","outcome":"completed","summary":"Implemented the vault, deployment manifest, vendored dependencies, adversarial tests, and documentation.\n\n- `forge build`, `forge test`, and `forge fmt --check` pass.\n- All 57 tests also pass offline with an empty environment.\n- Runtime: **22,203 bytes**.\n- Worst tested 64-asset redemption: **22,674,427 gas**, below 28 million.\n\nDeployment parameters, assumptions, and operational responsibilities are documented in `README.md`.","treeHash":"42b2c74ec6bce1eeffd90ffe54d8120e31ef5589","usage":{"cachedInputTokens":1694464,"inputTokens":106062,"model":"gpt-6-astra","outputTokens":44062,"runtime":"codex","turns":7,"wallClockMs":2324609}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"6b0a28df3d585600","findings":[{"citation":"resolved","description":"The brief gives redeem a 50,000-gas balance read (unreadable => leg deferred to owed) and says claim(token, to) 'pays min(caller's owed, vault balance) by the same function with no gas limit'. Only the self-call to payLeg is uncapped: claim() first reads the vault balance through _balance(), which is _word(token, balanceOf, 50_000) (lines 820-822), and payLeg() reads the balance twice through the same capped helper (lines 641 and 645). A Stock Token upgraded so that a correct balanceOf costs more than roughly 48k gas (compliance registry hop, snapshot lookup, per-holder loop) makes redeem defer every leg of that asset to owed as designed, but then makes claim() revert BalanceUnreadable regardless of the gas the caller supplies, even though the tokens sit in the vault and transfer() works. No role can repair this: the asset is never removed, managed/owed only fall through claim or recognizeLoss (which reverts on the same read), and the token is administered by a third party. This is the 'upgraded tokens' case the brief asks to attack: the exit survives redeem but dies at claim, and every redeemer of that asset is affected. Merged from audit_flow (same root cause). Fix that preserves the design: in claim() and in the payLeg frame, read balanceOf with gasleft() instead of the 50,000 cap (the redeem path keeps its cap and its 250,000-gas frame).","line":654,"path":"src/BaskVault.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {BaskVault} from \"src/BaskVault.sol\";\n\ncontract ProofFactory {\n    mapping(bytes32 => address) public tokenAddress;\n    function set(bytes32 uid, address token) external { tokenAddress[uid] = token; }\n}\n\ncontract ProofFeed {\n    uint8 public constant decimals = 8;\n    address public constant aggregator = address(1);\n    int256 public answer = 100e8;\n    uint256 public updatedAt;\n    function set(uint256 ts) external { updatedAt = ts; }\n    function latestRoundData() external view returns (uint80, int256, uint256, uint256, uint80) {\n        return (1, answer, updatedAt, updatedAt, 1);\n    }\n}\n\n/// A well-behaved Stock Token whose balanceOf becomes more expensive after an upgrade\n/// (still returns the correct balance; it just needs more than 50,000 gas).\ncontract ProofStock {\n    uint8 public constant decimals = 18;\n    bytes32 public uid;\n    mapping(address => uint256) public bal;\n    uint256 public balanceGas;\n    constructor(bytes32 u) { uid = u; }\n    function mint(address to, uint256 amount) external { bal[to] += amount; }\n    function upgrade(uint256 gasNeeded) external { balanceGas = gasNeeded; }\n    function oraclePaused() external pure returns (bool) { return false; }\n    function balanceOf(address who) external view returns (uint256) {\n        uint256 start = gasleft();\n        uint256 need = balanceGas;\n        while (start - gasleft() < need) { assembly { pop(keccak256(0, 32)) } }\n        return bal[who];\n    }\n    function approve(address, uint256) external pure returns (bool) { return true; }\n    function transferFrom(address from, address to, uint256 amount) external returns (bool) {\n        bal[from] -= amount; bal[to] += amount; return true;\n    }\n    function transfer(address to, uint256 amount) external returns (bool) {\n        bal[msg.sender] -= amount; bal[to] += amount; return true;\n    }\n}\n\ncontract ClaimBalanceGasTest is Test {\n    address constant OWNER = 0x30B57ECf51D19ABcED7F6f70974e6fBb6f3b9Da3;\n    address constant GUARDIAN = 0x5ed39AF86f2C00ad99913B5d727bD68f2A904B68;\n    address constant FACTORY = 0x4783C67b63dE2B358Ac5951a7D41F47A38F3C046;\n    address constant ALICE = address(0xA11CE);\n    uint256 constant MONDAY = 20003 days + 55800; // Monday 15:30 UTC\n\n    BaskVault vault;\n    ProofStock stock;\n    ProofFeed[] feeds;\n\n    function setUp() public {\n        vm.chainId(4663);\n        vm.warp(MONDAY - 3 days);\n        vm.etch(FACTORY, address(new ProofFactory()).code);\n        vault = new BaskVault(OWNER, GUARDIAN);\n        for (uint256 i = 1; i <= 3; ++i) {\n            ProofStock s = new ProofStock(bytes32(i));\n            ProofFactory(FACTORY).set(bytes32(i), address(s));\n            ProofFeed f = new ProofFeed();\n            f.set(block.timestamp);\n            feeds.push(f);\n            vm.prank(OWNER);\n            vault.proposeAsset(address(s), address(f));\n            if (i == 1) stock = s;\n        }\n        vm.prank(OWNER);\n        vault.finalizeGenesis();\n        vm.warp(MONDAY);\n        for (uint256 i; i < 3; ++i) feeds[i].set(block.timestamp);\n    }\n\n    /// Fails on the current code: claim() reverts BalanceUnreadable forever, the owed leg is stranded.\n    /// Passes once the balance reads used by claim (in claim and in the payLeg frame) are not capped at 50,000 gas.\n    function testOwedLegClaimableWhenBalanceOfNeedsMoreThan50kGas() public {\n        stock.mint(ALICE, 10e18);\n        vm.startPrank(ALICE);\n        stock.approve(address(vault), 10e18);\n        uint256 shares = vault.deposit(address(stock), 10e18, ALICE, 0, block.timestamp);\n        vm.stopPrank();\n\n        // Token upgraded: balanceOf still correct but needs ~60k gas.\n        stock.upgrade(60_000);\n\n        vm.prank(ALICE);\n        uint256[] memory legs = vault.redeem(shares, new uint256[](0), block.timestamp);\n        assertGt(legs[0], 0);\n        // On the current code redeem defers the leg (balance unreadable within 50k -> payout frame reverts)\n        // and the vault still holds all 10e18. A fix may instead pay the leg directly; either is accepted.\n        assertEq(stock.bal(address(vault)) + stock.bal(ALICE), 10e18);\n\n        // Spec: claim pays min(owed, vault balance) \"with no gas limit\". The vault holds the tokens.\n        // Current code: reverts BalanceUnreadable(stock) no matter how much gas is supplied.\n        uint256 owedBefore = vault.owed(ALICE, address(stock));\n        if (owedBefore != 0) {\n            vm.prank(ALICE);\n            uint256 paid = vault.claim{gas: 5_000_000}(address(stock), ALICE);\n            assertEq(paid, owedBefore);\n        }\n        assertEq(stock.bal(ALICE), legs[0]);\n        assertEq(vault.owed(ALICE, address(stock)), 0);\n        assertEq(vault.totalOwed(address(stock)), 0);\n    }\n}","reproduction":"State: genesis finalized with 3 assets, Monday 15:30 UTC, fresh feeds. 1) ALICE deposits 10e18 of token T (normal balanceOf) and receives shares. 2) T is upgraded so balanceOf(address) returns the correct number but burns 60,000 gas. 3) ALICE calls redeem(shares, [], now): _available is unreadable => available = managed, leg = 9.94999e18 is allocated; payLeg's first _balance fails => frame reverts => owed[ALICE][T] = leg, totalOwed[T] = leg, vault still holds 10e18 T. 4) Expected per brief: claim(T, ALICE) with ample gas pays min(owed, 10e18) = leg. Actual: claim{gas: 5_000_000}(T, ALICE) reverts BalanceUnreadable(T) at line 655, now and forever. Run: forge test --match-path test/scratch/ClaimBalanceGas.t.sol => [FAIL: BalanceUnreadable(0x...)] testOwedLegClaimableWhenBalanceOfNeedsMoreThan50kGas on this tree; the same test passes when the balance reads in claim() and payLeg() use gasleft() instead of 50,000 (verified on a patched copy under test/scratch/).","severity":"medium","snippet":"        (bool ok, uint256 available) = _balance(token);\n        if (!ok) revert BalanceUnreadable(token);","title":"claim() and payLeg still read balanceOf with the 50,000-gas cap, so an owed leg of a token whose balanceOf needs more gas can never be claimed"},{"citation":"resolved","description":"Spec-faithful emergent state, reported so the author and operator decide on it (merged from audit_permissions, audit_math, audit_flow and audit_economics, same root cause). NAV sums value(managed) over unretired assets only (line 779 skips retired), the first deposit locks 1e15 shares at 0xdEaD (line 564) that nothing can burn, so totalSupply never returns to 0 after the first deposit. If every unretired asset ends with managed == 0 (the owner retires the only valued asset, which accepted design 5 makes a normal configuration, or recognizeLoss writes the positions to 0 after a seizure), _snapshot returns ZeroNAV for every token forever: the totalSupply == 0 branch of _depositQuote is unreachable and the other branch is blocked. Listing new assets does not help because a new asset has managed 0. Nothing but a deposit raises managed and no deposit can pass; no owner lever changes it. Redeem and claim keep working, so no funds are lost; the vault is reduced to redeem-only. Any remedy (e.g. treating a dead-shares-only supply as a fresh start) changes the brief's 'revert if NAV is 0' rule, so this needs a scope decision rather than a code change under the current build rules; at minimum the operator must never retire the last unretired asset that has managed > 0.","line":794,"path":"src/BaskVault.sol","reproduction":"Genesis with assets A0, A1, A2 (feeds 100e8, fresh, Monday 15:30 UTC). 1) ALICE deposits 10e18 of A0: NAV $1,000, supply 995e18 + 1e15 dead. 2) Owner: closeAsset(A0); proposeRetire(A0); proposeAsset(A3, feed3). 3) +7 days: executeProposal(retire); executeProposal(list A3); refresh feeds. depositStatus(A1) == (ZeroNAV=19, 0x0). 4) ALICE redeems all her shares: totalSupply == 1e15 (dead only). 5) +7 days, feeds fresh: depositStatus(A1) and depositStatus(A3) still return ZeroNAV and deposit(A3, 1e18, ALICE, 0, now) reverts DepositUnavailable(19, 0x0). Expected: three healthy listed assets and no live positions should accept a deposit as at genesis; actual: deposits impossible forever. Reproduced by test/scratch/Review.t.sol::testZeroNavTerminal (passes on this tree, asserting the revert).","severity":"low","snippet":"        if (totalSupply != 0 && s.nav == 0) return _fail(s, Reason.ZeroNAV, address(0));","title":"NAV == 0 with nonzero supply is terminal: once every unretired asset has managed == 0, deposits can never resume, even into newly listed assets"},{"citation":"resolved","description":"At deployment feeRecipient is unset and setFeeRecipient is optional. The deposit fee is deducted from the depositor's shares (lines 575-577) but minted to nobody, while NAV rises by the full deposit value, so the share price rises for all holders including the depositor. A depositor who ends up owning fraction p of supply immediately recovers about p * 0.5% of the deposit. The redeem fee is burned (line 603) and lost, so the round-trip cost floor is 0.5%, not the 1% the README and accepted design (1) state as the threshold at which a lagging feed becomes exploitable. For a depositor that is large relative to the pool the exploitable lag window is roughly twice as wide as documented. Consequence of the brief's 'not minted while unset' rule: a documentation/operations item (set feeRecipient at launch, or state the 0.5% floor), not a code change request. Reproduced from audit_math.","line":566,"path":"src/BaskVault.sol","reproduction":"Genesis with 3 assets at 100e8, fresh, Monday 15:30 UTC, feeRecipient unset. 1) ALICE deposits 10e18 of asset 0 (NAV $1,000, supply 995e18). 2) BOB deposits 100e18 of asset 1 (v = $10,000): gross = 1e22*995e18/1e21 = 9,950e18; fee 49.75e18 unminted; BOB shares 9,900.25e18; supply 10,895.25e18; NAV $11,000. 3) BOB redeems all: fee 49.50125e18 burned, net 9,850.74875e18; legs = managed_i * net / 10,895.25e18 => 9.0413e18 of asset 0 + 90.413e18 of asset 1 = $9,945.5. Expected per README: about $9,900 back (1%). Actual: 54 bps. Control with setFeeRecipient(0xFEE) first: 99 bps. test/scratch/Review.t.sol::testRoundTripCost logs 'bps cost unset: 54' and testRoundTripCostFeeSet logs 'bps cost set: 99'.","severity":"low","snippet":"        if (feeRecipient != address(0)) _mint(feeRecipient, fee);","title":"While feeRecipient is unset the deposit fee is not minted, so the depositor recovers part of it and the real round trip is about 0.5%, not the 1% stated for accepted design (1)"},{"citation":"resolved","description":"A feed replacement reprices an asset atomically at execution; _checkReplacement only requires the new answer inside the existing band, so the old and new answers may differ by a large factor. Because anyone may execute a Ready proposal, the attacker controls the exact moment of the repricing and wraps it in one transaction: deposit at the stale NAV, executeProposal, redeem at the corrected NAV. The round-trip fee is at most 1%; the gain is the attacker's fraction of the revaluation. Accepted design (1) covers feed lag, but here the correction is public 7 days ahead, its size is known and its trigger is in the attacker's hands, so it is riskless. The same bundling applies to retirement execution (NAV drops by the retired asset while its tokens stay redeemable; see the info note). Design observation: the mitigation that keeps the agreed design is operational (pause deposits across the Ready window, or execute at the first Ready second). Reproduced from audit_economics.","line":397,"path":"src/BaskVault.sol","reproduction":"Genesis with 3 assets at $100. ALICE deposits 1000e18 of A0 ($100k) on day 1 and 1000e18 of A1 ($100k) on day 2: NAV $200k. Owner proposes feed F' for A0 reading $300 (inside band [25, 400]). At Ready, BOB in one tx: deposit(A1, 1000e18) = $100k (bucket limit max(300k/4, 100k) = 100k) -> executeProposal(id) -> redeem(all). Measured: BOB's legs are worth $165,279 at the new prices for $100,000 in; ALICE bears the $65k. test/scratch/Review.t.sol::testFeedReplacementSandwich logs 'bob out usd: 165279'.","severity":"low","snippet":"            a.feed = p.target;\n            emit FeedChanged(p.token, p.target);","title":"Permissionless executeProposal lets anyone bundle deposit, feed replacement and redeem in one transaction to capture the repricing risk-free"},{"citation":"resolved","description":"The global bucket only grows by deposit value and decays linearly over 24h; redeem does not reduce it. Anyone can deposit the whole allowance max(NAV2/4, $100,000) and redeem at once, leaving the bucket full while NAV returns to its prior level. Every other deposit then reverts BucketExceeded until decay frees room (1/24 per hour), and the attacker can top up hourly. Cost: 0.5% deposit fee plus 0.5% redeem fee on the bucket amount, $749 per day at NAV $100k, about $2,500 per day at NAV $1M. The brief defines the bucket as add-only, so this is a griefing property of the agreed mechanism, reported for operator awareness. Reproduced from audit_economics.","line":555,"path":"src/BaskVault.sol","reproduction":"Genesis with 3 assets at $100. ALICE deposits 1000e18 of A0 ($100k). Next day BOB deposits 1000e18 of A1 ($100k, exactly the limit) and redeems all his shares in the same block. bucket() == 100_000e18 while NAV is back to about $100k. ALICE's deposit(A2, 1e18, ALICE, 0, now) reverts BucketExceeded. test/scratch/Review.t.sol::testBucketGrief asserts bucket() == 100_000e18 and the BucketExceeded revert.","severity":"low","snippet":"        bucket = nextBucket;\n        bucketUpdatedAt = block.timestamp;","title":"Deposit bucket is never released by redeem, so a deposit-and-redeem round trip blocks all other deposits for a day at about 1% cost"},{"citation":"resolved","description":"Redeem pays min(managed, available) * net / supply and NAV values only managed, by the brief ('value never uses balanceOf and tokens sent directly are ignored'). Any balance the vault receives without a deposit is never distributed and never priced, and no sweep or re-sync exists by design. For Stock Tokens this is not exotic: a 2:1 split that credits holders with additional units halves the feed answer, so NAV halves while the extra units sit unreachable; a token dividend paid in kind is likewise lost. The same root cause bites recognizeLoss (line 681): anyone may write managed down 7 days after a readable zero balance, so a compliance hold or seizure that is later reversed leaves the restored tokens outside managed and redeem pays 0 for that asset forever. Merged from audit_permissions (corporate actions) and audit_economics (split surplus, transient freeze). Spec-mandated; a scope decision for the author, and an operational rule for the owner: pause deposits and close the asset around any balance-changing corporate action, and do not let a temporary hold reach recognizeLoss.","line":627,"path":"src/BaskVault.sol","reproduction":"(a) ALICE deposits 1000e18 of A0 at $100. Issuer credits the vault with 1000e18 more (2:1 split) and the feed moves to $50. ALICE redeems all her shares. Vault still holds 1005.00001e18 A0 with managed 5.00001e18 (fee dust): 1000e18 A0 (worth $50k) is unreachable by any function. test/scratch/Review.t.sol::testSplitStranded logs vault bal 1005000010000000000000, managed 5000010000000000000. (b) ALICE deposits 1000e18 of A0. Issuer sets the vault's balance to 0. Anyone calls flagDeficit(A0); 7 days later anyone calls recognizeLoss(A0): managed[A0] == 0. Issuer restores 1000e18. ALICE redeems all: leg for A0 == 0; vault still holds 1000e18 A0 that no function can pay out. testFreezeRecognize asserts legs[0] == 0 and balance 1000e18.","severity":"low","snippet":"        uint256 amount = managed[token];\n        if (available < amount) amount = available;","title":"managed never increases outside deposit, so balance that arrives otherwise (stock splits, in-kind dividends, a seizure reversed after recognizeLoss) is stranded forever"},{"citation":"resolved","description":"Note only, per the brief. Deposit prices shares against NAV that excludes the retired asset, but redeem (lines 609-611) iterates every asset in the permanent list including retired ones. The difference is a transfer from existing holders to whoever deposits after retirement, bounded per day only by the bucket and the 1% round-trip fee, and repeatable daily until the retired position is drained. With the retired asset at 50% of pre-retirement NAV a $10,000 deposit leaves with about $14,887 of tokens; with the retired asset dominant, the next depositor takes about 99.4% of it. Anyone can also execute the Ready retirement and bundle deposit+redeem in the same transaction. The exposure exists only while the retired token is still transferable. Merged from audit_permissions, audit_math and audit_economics. Operational: pause deposits before retiring any asset with a material managed balance.","line":779,"path":"src/BaskVault.sol","reproduction":"Genesis with 4 assets at $100. ALICE deposits 100e18 of A0 and 100e18 of A1 (NAV $20,000). Owner closes and retires A0 (7-day proposal): NAV $10,000 while the vault holds 100e18 A0. BOB deposits 100e18 of A1 ($10,000) and redeems all his shares: legs 49.625e18 A0 + 99.25e18 A1 = $14,887 for $10,000 in. test/scratch/Review.t.sol::testRetireExtraction logs leg0 49625313283208020050, leg1 99250626566416040100.","severity":"info","snippet":"            if (a.retired) continue;","title":"Accepted design (4) quantified: a retired asset counts 0 in NAV but is still paid pro rata by redeem, so the next depositor extracts the retired position from existing holders"}],"hash":"b476ef0b908a00bb64a34439630127aa0cb0855dd5cfe1eb1a94d8af6883d668","nodeId":"f3aea595-28f8-4b98-a8de-96437f1004a8","outcome":"completed","summary":"The review is complete. `.imd-findings.json` holds 7 merged findings and a 30-row coverage record (all 27 entry points answered, plus three invariants). No tracked file was changed; only the findings file and `test/scratch/` were written, both git-ignored.\n\n**What I kept, after reproducing each against the code**\n\n- **Medium (with proof):** `claim()` and the `payLeg` frame still read `balanceOf` under the 50,000-gas cap, so an owed leg of a Stock Token whose `balanceOf` later needs more gas can never be claimed, however much gas the caller supplies. The brief says claim pays \"with no gas limit\". I ran the specialist's proof and it failed as stated, but it also asserted the leg is deferred before claiming, which the simplest fix would break. I rewrote it to assert only the end state, confirmed it fails now and passes on a patched copy.\n- **Low, merged from four specialists:** the ZeroNAV guard plus the unburnable 0xdEaD shares make \"every unretired asset at managed 0\" a terminal, redeem-only state. Spec-faithful, so it needs a scope decision or an operator rule.\n- **Low:** with feeRecipient unset the real round-trip cost is about 0.5%, not the 1% the accepted-design note states. Measured 54 bps unset vs 99 bps set.\n- **Low:** permissionless `executeProposal` lets anyone bundle deposit, feed replacement and redeem atomically. Measured $165,279 out for $100,000 in.\n- **Low:** redeem never releases the deposit bucket, so a 1% round trip blocks all deposits for a day.\n- **Low, merged from three reports:** `managed` never increases outside deposit, so splits, in-kind dividends, or a seizure reversed after `recognizeLoss` are stranded.\n- **Info, merged from three reports:** accepted design 4 quantified, a retired asset is paid pro rata by redeem but counts 0 in NAV.\n\n**What I dropped or recalibrated:** the economics specialist's medium on ZeroNAV is downgraded to low since no funds are lost and the brief mandates the rule. All static-analysis leads are false positives (calendar arithmetic, intended XOR in mulDiv, intended strict equality).\n\n**My own pass** found nothing new. Every role lever (pause, close, retire, cap, fee recipient, guardian or owner change) was traced and none touches redeem's or claim's path. The 64-asset redeem suite stays under 28M gas, runtime is 22,203 bytes, and constructor literals match the brief.","treeHash":null,"usage":{"cachedInputTokens":1077563,"inputTokens":290,"model":"claude-fable-5-1","outputTokens":46350,"runtime":"claude","turns":20,"wallClockMs":838908}},{"artifacts":[],"attempt":2,"bundleHash":"dd5fc922a83a27f14da93dc2a004554c2d587dfd2befa1fb9acc0f6f65c72466","device":"eaa98ad0794d4f76","findings":[],"hash":"c000c4a4cae6aa3eae572a9c17e26903c9a0528f7d11b27a3546352433cd40d5","nodeId":"131c3a12-bbbd-426e-b1ee-cfc4c1b70102","outcome":"completed","summary":"Updated [launch.json](/home/imd/.identitymd/work/c7efa792-d9f8-403d-9157-d7d1660f2b24/131c3a12-bbbd-426e-b1ee-cfc4c1b70102/launch.json) to clarify redemption gas limits and deferred claims.\n\nSchema and constructor checks passed. `forge build` succeeded; all 60 tests passed, including hostile-token redemptions below 28 million gas.\n\nOnly `launch.json` changed.","treeHash":"1f02d71317d4760052a6f0195579e0c02072b8cc","usage":{"cachedInputTokens":323200,"inputTokens":38409,"model":"gpt-6-astra","outputTokens":4261,"runtime":"codex","turns":4,"wallClockMs":126277}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"ee2cc12e7dfe571a","findings":[{"citation":"resolved","description":"Spec-conformant behaviour with an unrecoverable emergent consequence, reported so the author/operator knows. NAV counts only unretired assets (line 779 `if (a.retired) continue;`) and new listings start with managed == 0. After the first deposit totalSupply can never return to 0 because 1e15 shares are locked at 0xdEaD. So if the owner retires (close -> proposeRetire -> 7 days -> executeProposal) every asset that currently has managed > 0, NAV becomes 0 with totalSupply != 0 and `_snapshot` returns ZeroNAV for every token, including freshly listed ones. Nothing can raise managed except deposit, which is blocked; there is no mint, rescue or un-retire. The same terminal state is reachable without the owner if every managed asset is fully confiscated by its issuer and anyone calls recognizeLoss after 7 days. Redeem and claim keep working, so no funds are lost, but the vault can never accept deposits again. The brief mandates `revert if NAV is 0` and `a retired asset counts 0 in NAV`, so this needs no code change under the build rules; it is an operational constraint: never retire the last unretired asset that has managed > 0 while supply exists.","line":794,"path":"src/BaskVault.sol","reproduction":"Genesis with 4 assets, finalize, warp to a Monday 15:30 UTC, refresh feeds. ALICE deposits 10e18 of asset0 (only asset with managed > 0). OWNER: closeAsset(asset0); id = proposeRetire(asset0); warp +7 days (Monday again), refresh feeds; executeProposal(id). Now depositStatus(asset1) == (ZeroNAV, 0x0) and deposit(asset1, 1e18, BOB, 0, now) reverts DepositUnavailable(ZeroNAV, 0x0) although asset1 is open, unretired, fresh and healthy. After ALICE redeems everything totalSupply == 1e15 (dEaD) and depositStatus still returns ZeroNAV. Expected: a way for the vault to resume deposits; actual: permanent. Confirmed by test/scratch/Probe.t.sol::testZeroNavBrickAfterRetiringAllManaged.","severity":"low","snippet":"        if (totalSupply != 0 && s.nav == 0) return _fail(s, Reason.ZeroNAV, address(0));","title":"Deposits are permanently bricked once every asset holding managed balance is retired (or fully lost) while shares exist"},{"citation":"resolved","description":"The brief lists this as accepted design, note only. Quantification for the author: deposit prices shares against NAV that excludes the retired asset, but redeem (lines 609-611) pays every asset in the permanent list pro rata, including the retired one. The difference is a transfer from existing holders to whoever deposits after retirement, bounded per day only by the bucket (max(25% of NAV2, $100,000)) and the 1% round-trip fee. With the retired asset at 50% of pre-retirement NAV a $10,000 deposit leaves with ~$14,887 of tokens (48.9% gain). Economics x asymmetry seam; no privileged action is needed beyond the retirement itself, and the extraction can be repeated daily until the retired position is drained. Operators should expect the retired position to be taken by arbitrageurs, not by long-term holders.","line":779,"path":"src/BaskVault.sol","reproduction":"Genesis with 4 assets at $100, finalize, Monday 15:30 UTC. ALICE deposits 100e18 of asset0 and 100e18 of asset1 (NAV $20,000). OWNER closes and retires asset0 (7-day proposal), NAV is now $10,000 while the vault still holds 100e18 of asset0. BOB deposits 100e18 of asset1 ($10,000) and immediately redeems all his shares: legs = 49.625e18 asset0 + 99.25e18 asset1 (test/scratch/Probe.t.sol::testRetiredAssetExtraction logs 49625313283208020050 and 99250626566416040100). BOB put in $10,000 and leaves with $14,887 of feed value; ALICE's remaining shares lost the same amount.","severity":"info","snippet":"            if (a.retired) continue;","title":"Note on accepted design (4): retiring an asset lets any depositor extract the retired position from existing holders via deposit-then-redeem"},{"citation":"resolved","description":"Spec-mandated (`value never uses balanceOf and tokens sent directly are ignored`), recorded as a trust assumption specific to the asset class. If a Stock Token issuer executes a 2:1 split by crediting holders with additional units (balance doubles, feed answer halves), `managed` stays at the pre-split quantity: NAV halves for deposit pricing and redeem pays min(managed, available) = managed, so half of the vault's real holding is unreachable by any redeemer and by every role (no sweep by design). Depositors after the split get shares at the halved NAV and redeem the managed fraction only, so the stranded half is never recovered. The reverse case (reverse split reducing balances) is handled as a shortfall via flagDeficit/recognizeLoss. Not a code defect under the brief; the owner should pause deposits and close/retire the asset around any corporate action that changes balances, or confirm from the issuer that Stock Tokens never rebase balances.","line":627,"path":"src/BaskVault.sol","reproduction":"Any listed asset with managed = M and balance = M. Issuer credits the vault with M more units (equivalent to stocks[i].mint(address(vault), M) in the mocks) and the feed answer halves. allAssets() still reports managed = M; previewRedeem(totalSupply) sums to at most M for that asset; redeem of 100% of circulating shares pays M, leaving M units in the vault that no function can move. Expected by holders: the vault's full holding is redeemable; actual: half is permanently stranded.","severity":"info","snippet":"        uint256 amount = managed[token];\n        if (available < amount) amount = available;","title":"Note: accounting ignores balance-increasing corporate actions on Stock Tokens (splits, stock dividends), stranding the new units"}],"hash":"e5837726e0a8355af2c8c57a824b084f856bccde55f79a78629a740d90a98a32","nodeId":"2b989b3b-1bd7-4a1a-94c4-bec43a0a1854","outcome":"completed","summary":"Review complete. `.imd-findings.json` holds 3 findings and 30 coverage rows (all 27 ABI entry points plus 3 invariants); line/snippet checks pass and no tracked file changed (scratch tests sit under `test/scratch/`).\n\n## Summary\n\n**Area: Access Control, Trust Gap, Asymmetry** — mapped every role, modifier and paired surface and traced each against the Pashov checklists. The permission model is tight:\n\n- Owner/guardian separation is enforced in all four directions (`constructor`, `transferOwnership`, `acceptOwnership`, `_checkGuardian` at proposal *and* execution), guardian cannot cancel its own replacement, `setFeeRecipient` is one-shot and never called by the vault.\n- Every proposal kind re-runs its checks at execution; retire voids via `proposalState`; `closeEpoch`/`capEpoch` invalidate reopen/raise correctly.\n- **MUST ATTACK (redeem with hostile/upgraded tokens; roles blocking exit):** holds. No owner/guardian write appears anywhere in `redeem`/`claim`; tokens are isolated by 50k/250k gas-capped calls with no returndata copy; `mulDiv(amount, net, supply)` cannot overflow-revert since `net ≤ supply`. I verified the invariant `balance − totalOwed − managed ≥ 0` across all operations, so no unprivileged actor can fabricate a `Deficit`/`OwedUnderfunded` state to block deposits or reset the loss clock.\n- All static-analysis leads were false positives (calendar math, correct XOR seed in `mulDiv`).\n\n**Findings (none critical/high — no proofs attached):**\n1. **Low** — Permanent deposit brick: retiring (or fully losing) every asset with `managed > 0` while shares exist yields `ZeroNAV` forever, since new listings start at 0 and the 1e15 dEaD lock keeps `totalSupply ≠ 0`. Spec-mandated, but unrecoverable; reproduced in `test/scratch/Probe.t.sol`.\n2. **Info** — Accepted design (4) quantified: with the retired asset at 50% of NAV, a $10,000 deposit-then-redeem extracts ~$14,887 from existing holders (48.9%), repeatable daily within the bucket.\n3. **Info** — Balance-increasing corporate actions (splits) on Stock Tokens strand the new units permanently under the \"ignore `balanceOf`\" accounting; recorded as a trust assumption.\n\nNot reached: nothing within the assigned entry points; economic/periphery passes (feed-lag arbitrage, oracle round semantics) were only skimmed since they belong to the other specialists.","treeHash":null,"usage":{"cachedInputTokens":1381089,"inputTokens":33,"model":"claude-fable-5-1","outputTokens":45743,"runtime":"claude","turns":17,"wallClockMs":700611}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"f9cb4fd544aa3c68","findings":[{"citation":"resolved","description":"NAV sums value(managed) over unretired assets only. The first deposit mints 1e15 shares to 0xdEaD (line 564), so totalSupply never returns to zero. If every unretired asset ends with managed == 0 (the valued asset is retired, or recognizeLoss writes it to zero after a seizure), _snapshot returns ZeroNAV on every later deposit, for every token, including freshly listed ones. Nothing but a deposit can raise managed, and no deposit can pass, so the state is absorbing: the vault can only be redeemed, never funded again, and the owner has no lever (no unretire, no cap, no pause) that changes it. This is spec-faithful ('revert if NAV is 0', accepted design 4) but the permanence is an emergent consequence of the dead-share lock, and the precondition (all value in one asset that later must be retired) is normal operation under accepted design 5 (no per-asset limit). Fix needs a scope decision: e.g. treat totalSupply == LOCKED_SHARES-only supply as a fresh start, or let the first deposit after ZeroNAV re-seed (gross = v) while accepting dilution of the worthless shares.","line":794,"path":"src/BaskVault.sol","reproduction":"Genesis with 4 assets A,B,C,D (all $100 feeds). Alice deposits 1000e18 A ($100k) only. Owner closeAsset(A), proposeRetire(A); 7 days later anyone executes. depositStatus(B) == ZeroNAV (19). Alice redeems all shares: totalSupply == 1e15 (dead shares), depositStatus(B) still ZeroNAV. Owner lists new asset E via proposal and executes 7 days later; depositStatus(E) == ZeroNAV and deposit(E, 1e18, bob, 0, now) reverts DepositUnavailable(ZeroNAV, 0x0). Expected: a vault with no live positions should be fundable again; actual: deposits are impossible forever. Verified with a scratch Foundry test (testZeroNavPermanentAfterRetiringOnlyValuedAsset) on this tree.","severity":"medium","snippet":"        if (totalSupply != 0 && s.nav == 0) return _fail(s, Reason.ZeroNAV, address(0));","title":"Deposits lock permanently once no unretired asset carries managed value (ZeroNAV with dead shares)"},{"citation":"resolved","description":"A feed replacement reprices an asset atomically at execution; _checkReplacement only requires the new answer inside the existing band, so old and new answers may differ by up to 16x. Because anyone may execute a Ready proposal, an attacker controls the exact moment of the repricing and can wrap it in one transaction: deposit at the stale NAV, executeProposal, redeem at the corrected NAV. The round-trip fee is 1%; the gain is the attacker's fraction of the revaluation. Accepted design (1) covers feed lag, but here the lag is known 7 days in advance (the proposal is public), the correction size is known, and the trigger is in the attacker's hands, so it is riskless rather than speculative. Noted as a design observation: a mitigation that keeps the agreed design is operational (owner pauses deposits across the Ready window, or executes at the first Ready second), not a code change.","line":397,"path":"src/BaskVault.sol","reproduction":"Genesis with 4 assets at $100. Alice deposits 1000e18 A ($100k) day 1 and 1000e18 B ($100k) day 2: NAV $200k. Owner proposes feed F' for A reading $300 (inside band [25,400]). At Ready, Bob in one tx: deposit(B, 1000e18) = $100k (bucket limit max(300k/4,100k) = 100k) -> executeProposal(id) -> redeem(all). Measured: Bob receives legs worth $165,279 at the new prices for $100,000 in; Alice bears the $65k. Scratch test testFeedReplacementSandwichProfit on this tree.","severity":"low","snippet":"            a.feed = p.target;","title":"Permissionless executeProposal lets anyone bundle deposit -> feed replacement -> redeem to capture the repricing (accepted design 1, amplified)"},{"citation":"resolved","description":"At retirement the asset counts 0 in NAV but its managed balance is still paid out pro rata by redeem. Anyone can execute the Ready retirement and in the same transaction deposit at the depressed NAV and redeem, taking a fraction of the retired tokens from existing holders. Accepted design (4); recorded so the operator knows the magnitude: with the retired asset at one third of the book the attacker clears ~32% on the maximum bucket deposit after fees. The exposure only exists when the retired token is still transferable (retired for feed reasons rather than because it is frozen).","line":413,"path":"src/BaskVault.sol","reproduction":"Genesis with 4 assets at $100. Alice deposits $100k each into A, B, C on three days (NAV $300k). Owner closes A and proposes retirement. At Ready, Bob in one tx: executeProposal(retire A) (NAV -> $200k) -> deposit(B, 1000e18 = $100k; bucket limit max(300k/4,100k) = 100k) -> redeem(all). Measured: Bob's legs are worth $132,223 for $100,000 in. Scratch test testRetireSandwichProfit on this tree.","severity":"info","snippet":"            a.retired = true;","title":"Retirement execution drops NAV by the retired asset's value while its tokens stay redeemable; bundled deposit after execute extracts it (accepted design 4, numbers)"},{"citation":"resolved","description":"The global bucket only grows (by deposit value) and decays linearly over 24h; redeem does not reduce it. An attacker can deposit the whole allowance max(NAV2/4, 100k) and immediately redeem, leaving the bucket full while NAV returns to its prior level. Every other deposit then reverts BucketExceeded until decay frees room (1/24 per hour), and the attacker can top up hourly. Cost is the 0.5% deposit fee plus 0.5% redeem fee on the bucket amount: at NAV $100k the measured cost is $749 per day to deny all deposits; at NAV $1M it is ~$2,500 per day (1% of NAV/4). Spec defines the bucket as add-only, so this is a griefing property of the agreed mechanism rather than a coding error; reported for the operator's awareness.","line":555,"path":"src/BaskVault.sol","reproduction":"Genesis with 4 assets at $100. Alice deposits 1000e18 A ($100k). Next day Bob deposits 1000e18 B ($100k, exactly the limit) and redeems all his shares in the same block. bucket() == 100_000e18 while NAV is back to ~$100k. Alice's deposit(C, 1e18, ...) reverts BucketExceeded. Bob's measured cost: $749.37 of his $100k. Scratch test testBucketGriefingCost on this tree.","severity":"low","snippet":"        bucket = nextBucket;","title":"Deposit bucket is never released by redeem, so a deposit-and-redeem round trip blocks all other deposits for a day at ~1% cost"},{"citation":"resolved","description":"Redeem pays min(managed, available) * net / supply and NAV values only managed. Any balance the vault receives without a deposit is invisible: it is never distributed and never priced. For Stock Tokens this is not exotic: a 2:1 split that credits holders with additional tokens halves the feed answer, so NAV halves while the extra tokens sit unreachable; a token dividend paid in kind is likewise lost. The spec says tokens sent directly are ignored, so this is a design consequence, but it means a realistic corporate action permanently destroys half the holders' value in that position, with no owner lever to recover it (no sweep or re-sync exists by design).","line":628,"path":"src/BaskVault.sol","reproduction":"Alice deposits 1000e18 A at $100. Issuer performs a 2:1 split: vault balance becomes 2000e18, feed set to $50. Alice redeems all her shares. Measured: vault still holds 1005e18 A with managed 5e18 (fee dust); 1000e18 A (worth $50k) is permanently unreachable by any function. Scratch test testSplitSurplusStranded on this tree.","severity":"low","snippet":"        if (available < amount) amount = available;","title":"Surplus token balance from corporate actions (splits, in-kind dividends, returned seizures) is stranded forever because managed never increases outside deposit"},{"citation":"resolved","description":"flagDeficit/recognizeLoss treat a readable zero balance as a real loss after 7 days, and anyone can call them. A compliance hold or issuer freeze that makes balanceOf(vault) read 0 for a week (while the tokens are later restored) lets any third party write managed to 0. Deposits then price the asset at nothing, and when the hold lifts the restored tokens are outside managed, so redeem pays 0 for that asset forever (see also the surplus finding). Nothing distinguishes a temporary hold from a seizure, and the owner cannot block the recognition (pausing deposits does not gate recognizeLoss). Spec-faithful; flagged because the irreversible write-down is triggered by an unprivileged party on an event the owner may know to be temporary.","line":681,"path":"src/BaskVault.sol","reproduction":"Alice deposits 1000e18 A. Issuer sets the vault's balance to 0 (freeze). Anyone calls flagDeficit(A); 7 days later anyone calls recognizeLoss(A): managed[A] == 0. Issuer restores the 1000e18 balance. Alice redeems all: leg for A == 0, vault still holds 1000e18 A that no function can ever pay out. Scratch test testTransientFreezeThenRecognizeLossStrands on this tree.","severity":"low","snippet":"        managed[token] -= amount;","title":"Permissionless recognizeLoss on a transient freeze zeroes managed; when the balance returns the whole position is stranded"}],"hash":"f697eb4cf8fd3e4eddb6ef5748f410ec131e9dbdd38cdef7b57da31757b89a89","nodeId":"2ab019cc-1175-43a6-9f34-573adc73cee9","outcome":"completed","summary":"The review is complete. The tree is unchanged apart from `.imd-findings.json`, and the scratch tests I used are removed.\n\n**Outcome.** The vault implements the brief faithfully. I found no implementation defect that loses or misdirects funds, and nothing a role can do blocks `redeem` or `claim`. The six findings are economic consequences of the agreed design, written up with concrete reproductions so the author and judge can decide whether any warrant a spec change.\n\n**Findings written to `.imd-findings.json`:**\n\n1. **Medium.** Deposits lock permanently once no unretired asset has managed value. Retiring the only valued asset, or a full loss recognition, makes every later deposit revert with ZeroNAV forever, because the dead shares keep supply above zero and only deposits can raise managed. Verified: even a freshly listed asset cannot be deposited afterwards.\n2. **Low.** Anyone can bundle deposit, feed-replacement execution and redeem in one transaction. Measured gain of $65k on $100k when a lagging $100 feed is replaced by a $300 feed inside the band. This is accepted design 1, but the trigger is in the attacker's hands.\n3. **Info.** The same bundling around retirement execution yields $32k on $100k. Accepted design 4, recorded with numbers.\n4. **Low.** The bucket is add-only, so deposit-then-redeem blocks all deposits for a day. Measured cost is $749 at a $100k NAV.\n5. **Low.** Surplus balance from a stock split or in-kind dividend is stranded forever. After a 2:1 split and full exit, 1000 tokens remain unreachable.\n6. **Low.** Permissionless loss recognition on a transient freeze zeroes managed. When the balance returns the position pays nothing and is stranded.\n\n**Independently verified as holding.** Worst-case 64-asset redeem with every token burning its full balance-read and payout gas, a fee recipient set and 64 minimums, used 22.70M gas. Conservation of managed plus owed against balance holds through every writer. The static-analysis leads on `BaskMath.mulDiv` and the calendar gate are false positives.\n\n**Coverage.** All 27 entry points have a row, plus three invariant rows. Deposit, executeProposal and recognizeLoss reference findings 1, 2 and 6. The remaining entry points hold.","treeHash":null,"usage":{"cachedInputTokens":1343636,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":64950,"runtime":"claude","turns":26,"wallClockMs":996068}}],"verification":[{"checks":[{"durationMs":19790,"exitCode":0,"name":"build","output":"Compiling 28 files with Solc 0.8.26\nSolc 0.8.26 finished in 19.44s\nCompiler run successful!\nwarning[boolean-cst]: misuse of a boolean constant\n    ╭▸ src/BaskVault.sol:815:32\n    │\n815 │         if (!readable) return (false, managed[token]);\n    │                                ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[boolean-cst]: misuse of a boolean constant\n    ╭▸ src/BaskVault.sol:846:26\n    │\n846 │         if (!ok) return (false, 0, 0);\n    │                          ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[weak-prng]: weak randomness derived from a predictable on-chain value\n    ╭▸ src/BaskVault.sol:771:23\n    │\n771 │         uint256 day = (block.timestamp / 1 days + 4) % 7;\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/weak-prng\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:520:9\n    │\n520 │         emit AssetListed(token, feed, low, high);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:372:9\n    │\n372 │         emit ProposalCreated(id, kind, token, target, value);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:478:44\n    │\n478 │         if (assetIndexPlusOne[token] != 0) revert InvalidAsset(token);\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:479:42\n    │\n479 │         if (assets.length == MAX_ASSETS) revert AssetLimit();\n    │                                          ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:481:32\n    │\n481 │         if (!ok || word != 18) revert InvalidAsset(token);\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:483:18\n    │\n483 │         if (!ok) revert InvalidAsset(token);\n    │                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:486:53\n    │\n486 │         if (!ok || word != uint256(uint160(token))) revert InvalidAsset(token);\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:493:31\n    │\n493 │         if (!ok || word != 8) revert InvalidFeed(feed);\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:495:59\n    │\n495 │         if (!ok || word == 0 || word > type(uint160).max) revert InvalidFeed(feed);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:498:67\n    │\n498 │             if (!a.retired && a.token != token && a.feed == feed) revert InvalidFeed(feed);\n    │                                                                   ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:502:33\n    │\n502 │         if (!ok || answer <= 0) revert InvalidFeed(feed);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:512:45\n    │\n512 │         if (answer > type(uint256).max / 4) revert InvalidAmount();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:389:17\n    │\n389 │             if (block.timestamp < nextAssetChangeAt) revert ChangeTooSoon();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:402:39\n    │\n402 │             if (!ok || answer <= 0 || updated > block.timestamp || block.timestamp - updated >= PRICE_AGE) {\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:402:68\n    │\n402 │             if (!ok || answer <= 0 || updated > block.timestamp || block.timestamp - updated >= PRICE_AGE) {\n    │                                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:398:13\n    │\n398 │             emit FeedChanged(p.token, p.target);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:406:13\n    │\n406 │             emit BandChanged(p.token, a.minAnswer, a.maxAnswer);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:424:9\n    │\n424 │         emit ProposalExecuted(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:405:48\n    │\n405 │             (a.minAnswer, a.maxAnswer) = _band(uint256(answer));\n    │                                                ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:436:13\n    │\n436 │         if (block.timestamp < p.createdAt + PROPOSAL_DELAY) return ProposalState.Waiting;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:437:13\n    │\n437 │         if (block.timestamp >= p.createdAt + PROPOSAL_DELAY + PROPOSAL_LIFETIME) {\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/BaskVault.sol:453:85\n    │\n453 │             if (state == ProposalState.Waiting || state == ProposalState.Ready) ids[n++] = start + i;\n    │                                                                                     ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:503:16\n    │\n503 │         return uint256(answer);\n    │                ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:528:13\n    │\n528 │         if (block.timestamp > deadline) revert DeadlineExpired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:561:17\n    │\n561 │                 emit DeficitCleared(t);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:246:9\n    │\n246 │         emit Transfer(address(0), to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:567:9\n    │\n567 │         emit Deposit(msg.sender, receiver, token, amount, shares, fee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:588:13\n    │\n588 │         if (elapsed >= 1 days) return 0;\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:597:13\n    │\n597 │         if (block.timestamp > deadline) revert DeadlineExpired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:618:17\n    │\n618 │                 emit LegOwed(msg.sender, token, leg);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:621:9\n    │\n621 │         emit Redeem(msg.sender, shares, fee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/BaskMath.sol:19:29\n   │\n19 │                 if (d == 0) revert MathOverflow();\n   │                             ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/BaskMath.sol:22:28\n   │\n22 │             if (d <= high) revert MathOverflow();\n   │                            ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:612:69\n    │\n612 │             if (i < minAmountsOut.length && leg < minAmountsOut[i]) revert Slippage();\n    │                                                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:649:9\n    │\n649 │         emit LegPaid(token, to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `entered` is updated\n    ╭▸ src/BaskVault.sol:660:26\n    │\n660 │         if (amount != 0) this.payLeg(token, to, amount);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:661:9\n    │\n661 │         emit Claimed(msg.sender, token, to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:672:9\n    │\n672 │         emit DeficitFlagged(token, loss.amount, loss.since);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:678:33\n    │\n678 │         if (loss.amount == 0 || block.timestamp < loss.since + 7 days) revert InvalidState();\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:683:9\n    │\n683 │         emit LossRecognized(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/BaskVault.sol:781:95\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                                                                                               ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:760:13\n    │\n760 │         if (block.timestamp < depositsOpenAt) return _fail(s, Reason.WarmingUp, address(0));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:13\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │             ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:25\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:37\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                                     ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:61\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                                                             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:781:25\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:781:55\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:786:49\n    │\n786 │                 if (a.token == token) s.price = uint256(answer);\n    │                                                 ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:787:60\n    │\n787 │                 s.nav += BaskMath.mulDiv(managed[a.token], uint256(answer), 1e8);\n    │                                                            ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:805:13\n    │\n805 │         if (updated > block.timestamp) return Reason.FuturePrice;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:806:13\n    │\n806 │         if (block.timestamp - updated > PRICE_AGE) return Reason.StalePrice;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:804:13\n    │\n804 │         if (uint256(answer) < a.minAnswer || uint256(answer) > a.maxAnswer) return Reason.OutsideBand;\n    │             ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:804:46\n    │\n804 │         if (uint256(answer) < a.minAnswer || uint256(answer) > a.maxAnswer) return Reason.OutsideBand;\n    │                                              ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\n","passed":true},{"durationMs":155,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 5 tests for test/BaskAdversarial.t.sol:BaskAdversarialTest\n[PASS] testAllFailedTransfersAtomicIncludingReturnBombs() (gas: 3553828)\n[PASS] testAllUnreadableBalanceOutcomesDeferWithoutRevert() (gas: 2210690)\n[PASS] testDepositRedeemClaimAndAdminCallbacksBlocked() (gas: 7200388)\n[PASS] testNoReturnTransferAndSenderDebitSemantics() (gas: 787349)\n[PASS] testRolesCannotBlockRedeemOrClaim() (gas: 1332550)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 6.24ms (11.65ms CPU time)\n\nRan 3 tests for test/BaskMath.t.sol:BaskMathTest\n[PASS] testFullWidthRedemptionMathAndRounding() (gas: 4635)\n[PASS] testFuzzExactCancellation(uint256,uint256) (runs: 256, μ: 3618, ~: 3534)\n[PASS] testMathOverflowUsesCustomError() (gas: 10574)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 18.27ms (18.26ms CPU time)\n\nRan 18 tests for test/BaskVault.t.sol:BaskVaultTest\n[PASS] testAllPriceFailuresAndStatusParity() (gas: 2717865)\n[PASS] testBucketGlobalAndDecay() (gas: 1576380)\n[PASS] testDeploymentAndConstructorValidation() (gas: 71153)\n[PASS] testFeeRecipientCanRedeemOwnShares() (gas: 614341)\n[PASS] testFeeRecipientNeverCalledAndFeesAreFinal() (gas: 798881)\n[PASS] testFirstDepositAndDonationIgnored() (gas: 1126067)\n[PASS] testFuzzDepositRedeemConservation(uint96,bool) (runs: 256, μ: 679295, ~: 710141)\nLogs:\n  Bound result 280232424145582212325\n\n[PASS] testInclusiveBandAnd26HourPriceWithThreeOtherFreshFeeds() (gas: 3301923)\n[PASS] testManagedClosedAssetStillRequiresPriceAndEmptyAssetDoesNot() (gas: 1434338)\n[PASS] testMarketBoundariesAndFreshGate() (gas: 1614882)\n[PASS] testMinimumSharesDeadlineAndRecipient() (gas: 568441)\n[PASS] testNavCapAndValueBasedBucketLimit() (gas: 2572754)\n[PASS] testRedeemSlippageAndDeadlineAreAtomic() (gas: 770671)\n[PASS] testRejectsInexactAndFalseDepositTransfers() (gas: 1722788)\n[PASS] testRoundingUpFeesForSmallSubsequentDepositsAndRedemptions() (gas: 963196)\n[PASS] testRuntimeHasNoForbiddenOpcodes() (gas: 6486872)\n[PASS] testShareTransfersAndAllowance() (gas: 788939)\n[PASS] testUnsetRedeemFeeBurnsAllShares() (gas: 581154)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 26.29ms (47.85ms CPU time)\n\nRan 15 tests for test/BaskGovernance.t.sol:BaskGovernanceTest\n[PASS] testBandUsesExecutionAnswerAndStrictAge() (gas: 601779)\n[PASS] testCapRaisesDelayedLowerCancelsAllRaisesAndHasNoFloor() (gas: 618832)\n[PASS] testExpiredCancelledAndPendingEnumeration() (gas: 488016)\n[PASS] testFeedReplacementChecksBothTimesAndPreservesBand() (gas: 1345379)\n[PASS] testGenesisBatchAtomicAndFinalizedOnce() (gas: 1254870)\n[PASS] testGuardianCannotCancelItsReplacementAndOwnershipSeparation() (gas: 550785)\n[PASS] testGuardianRecheckedAgainstCurrentOwner() (gas: 368730)\n[PASS] testListingAndFeedShareDailyRateLimit() (gas: 3066858)\n[PASS] testListingChecksAtProposalAndExecution() (gas: 3604426)\n[PASS] testListingFeedCannotBeTakenByAnotherProposal() (gas: 2289767)\n[PASS] testProposalTimingJustBeforeAndAtBoundaries() (gas: 511432)\n[PASS] testReopenVoidedEvenByRepeatedClose() (gas: 652348)\n[PASS] testRetireClosedBothTimesVoidsAllProposals() (gas: 1607285)\n[PASS] testRetiredFeedMayBeReusedAndDoesNotCountInFreshQuorum() (gas: 3027028)\n[PASS] testUnauthorizedEntryPointsAndGuardianBoundaries() (gas: 1519030)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 26.31ms (11.04ms CPU time)\n\nRan 12 tests for test/BaskLosses.t.sol:BaskLossesTest\n[PASS] testClaimFailureRollsBackAndOnlyCallerCanClaim() (gas: 920745)\n[PASS] testDeferredClaimReservesBeforeOtherRedemptions() (gas: 1220060)\n[PASS] testDeficitBlocksDepositsButDoesNotAutomaticallyLowerManaged() (gas: 1348663)\n[PASS] testFuzzFailedLegConservation(uint96) (runs: 256, μ: 801296, ~: 801346)\nLogs:\n  Bound result 999999900000000000294\n\n[PASS] testLargerDeficitRestartsClockSmallerDoesNot() (gas: 870686)\n[PASS] testNonzeroSupplyWithZeroNAVRejectsDepositsButRedeems() (gas: 3393628)\n[PASS] testPartialClaimAndOwedUnderfundingCannotBlockRedeem() (gas: 1153837)\n[PASS] testRecognitionCannotExceedRecordedLoss() (gas: 738310)\n[PASS] testRecoveredDeficitClearedByDepositOrRecognition() (gas: 1130591)\n[PASS] testRedemptionOnDeficitUsesAvailableAndLeavesRemainingLoss() (gas: 724724)\n[PASS] testRetiredAssetsZeroNAVSkipChecksAndStillRedeemAndClaim() (gas: 4473897)\n[PASS] testUnreadableBalanceNeverAuthorizesLoss() (gas: 803295)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 26.40ms (32.67ms CPU time)\n\nRan 4 tests for test/BaskAdversarial.t.sol:Bask64AssetsTest\n[PASS] test64MixedPausedBlockedMalformedRetiredAndWorkingTokens() (gas: 24982544)\nLogs:\n  64-asset redemption gas (including call and result copy): 7991439\n\n[PASS] test64TransfersConsumeEntirePayoutGas() (gas: 37306036)\nLogs:\n  64-asset redemption gas (including call and result copy): 22674427\n\n[PASS] test64UpgradedUnreadableTokensDoNotBlockExit() (gas: 11661930)\nLogs:\n  64-asset redemption gas (including call and result copy): 10295260\n\n[PASS] testAsset65RejectedEvenAfterRetirement() (gas: 459515)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 79.87ms (21.90ms CPU time)\n\nRan 6 test suites in 80.69ms (183.39ms CPU time): 57 tests passed, 0 failed, 0 skipped (57 total tests)\n","passed":true},{"durationMs":49,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"BaskVault.acceptOwnership()\",\"BaskVault.approve(address,uint256)\",\"BaskVault.cancelProposal(uint256)\",\"BaskVault.claim(address,address)\",\"BaskVault.closeAsset(address)\",\"BaskVault.deposit(address,uint256,address,uint256,uint256)\",\"BaskVault.executeProposal(uint256)\",\"BaskVault.finalizeGenesis()\",\"BaskVault.flagDeficit(address)\",\"BaskVault.lowerNavCap(uint256)\",\"BaskVault.pauseDeposits()\",\"BaskVault.payLeg(address,address,uint256)\",\"BaskVault.proposeAsset(address,address)\",\"BaskVault.proposeAssets(address[],address[])\",\"BaskVault.proposeBand(address)\",\"BaskVault.proposeFeed(address,address)\",\"BaskVault.proposeGuardian(address)\",\"BaskVault.proposeNavCap(uint256)\",\"BaskVault.proposeReopen(address)\",\"BaskVault.proposeRetire(address)\",\"BaskVault.recognizeLoss(address)\",\"BaskVault.redeem(uint256,uint256[],uint256)\",\"BaskVault.setFeeRecipient(address)\",\"BaskVault.transfer(address,uint256)\",\"BaskVault.transferFrom(address,address,uint256)\",\"BaskVault.transferOwnership(address)\",\"BaskVault.unpauseDeposits()\"],\"files\":{\".gitignore\":3,\"README.md\":255,\"foundry.toml\":16,\"launch.json\":13,\"remappings.txt\":1,\"src/BaskMath.sol\":46,\"src/BaskVault.sol\":859,\"test/BaskAdversarial.t.sol\":228,\"test/BaskBase.t.sol\":98,\"test/BaskGovernance.t.sol\":379,\"test/BaskLosses.t.sol\":242,\"test/BaskMath.t.sol\":31,\"test/BaskVault.t.sol\":310,\"test/mocks/StockMocks.sol\":218},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"1f768736ab16479c3d0f727b0959958a92c25f94ec8002188b5e7641539ccff2","verifiedTreeHash":"97d8ebb77717be6e41d4555c59e90c1b6e47652e","verifierVersion":"0.1.0+be003835"},{"checks":[{"durationMs":28373,"exitCode":0,"name":"build","output":"Compiling 31 files with Solc 0.8.26\nSolc 0.8.26 finished in 27.98s\nCompiler run successful!\nwarning[boolean-cst]: misuse of a boolean constant\n    ╭▸ src/BaskVault.sol:815:32\n    │\n815 │         if (!readable) return (false, managed[token]);\n    │                                ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[boolean-cst]: misuse of a boolean constant\n    ╭▸ src/BaskVault.sol:851:26\n    │\n851 │         if (!ok) return (false, 0, 0);\n    │                          ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[weak-prng]: weak randomness derived from a predictable on-chain value\n    ╭▸ src/BaskVault.sol:771:23\n    │\n771 │         uint256 day = (block.timestamp / 1 days + 4) % 7;\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/weak-prng\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:520:9\n    │\n520 │         emit AssetListed(token, feed, low, high);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:372:9\n    │\n372 │         emit ProposalCreated(id, kind, token, target, value);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:478:44\n    │\n478 │         if (assetIndexPlusOne[token] != 0) revert InvalidAsset(token);\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:479:42\n    │\n479 │         if (assets.length == MAX_ASSETS) revert AssetLimit();\n    │                                          ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:481:32\n    │\n481 │         if (!ok || word != 18) revert InvalidAsset(token);\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:483:18\n    │\n483 │         if (!ok) revert InvalidAsset(token);\n    │                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:486:53\n    │\n486 │         if (!ok || word != uint256(uint160(token))) revert InvalidAsset(token);\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:493:31\n    │\n493 │         if (!ok || word != 8) revert InvalidFeed(feed);\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:495:59\n    │\n495 │         if (!ok || word == 0 || word > type(uint160).max) revert InvalidFeed(feed);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:498:67\n    │\n498 │             if (!a.retired && a.token != token && a.feed == feed) revert InvalidFeed(feed);\n    │                                                                   ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:502:33\n    │\n502 │         if (!ok || answer <= 0) revert InvalidFeed(feed);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:512:45\n    │\n512 │         if (answer > type(uint256).max / 4) revert InvalidAmount();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:389:17\n    │\n389 │             if (block.timestamp < nextAssetChangeAt) revert ChangeTooSoon();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:402:39\n    │\n402 │             if (!ok || answer <= 0 || updated > block.timestamp || block.timestamp - updated >= PRICE_AGE) {\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:402:68\n    │\n402 │             if (!ok || answer <= 0 || updated > block.timestamp || block.timestamp - updated >= PRICE_AGE) {\n    │                                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:398:13\n    │\n398 │             emit FeedChanged(p.token, p.target);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:406:13\n    │\n406 │             emit BandChanged(p.token, a.minAnswer, a.maxAnswer);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:424:9\n    │\n424 │         emit ProposalExecuted(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:405:48\n    │\n405 │             (a.minAnswer, a.maxAnswer) = _band(uint256(answer));\n    │                                                ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:436:13\n    │\n436 │         if (block.timestamp < p.createdAt + PROPOSAL_DELAY) return ProposalState.Waiting;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:437:13\n    │\n437 │         if (block.timestamp >= p.createdAt + PROPOSAL_DELAY + PROPOSAL_LIFETIME) {\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/BaskVault.sol:453:85\n    │\n453 │             if (state == ProposalState.Waiting || state == ProposalState.Ready) ids[n++] = start + i;\n    │                                                                                     ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:503:16\n    │\n503 │         return uint256(answer);\n    │                ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:528:13\n    │\n528 │         if (block.timestamp > deadline) revert DeadlineExpired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:561:17\n    │\n561 │                 emit DeficitCleared(t);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:246:9\n    │\n246 │         emit Transfer(address(0), to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:567:9\n    │\n567 │         emit Deposit(msg.sender, receiver, token, amount, shares, fee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:588:13\n    │\n588 │         if (elapsed >= 1 days) return 0;\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:597:13\n    │\n597 │         if (block.timestamp > deadline) revert DeadlineExpired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:618:17\n    │\n618 │                 emit LegOwed(msg.sender, token, leg);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:621:9\n    │\n621 │         emit Redeem(msg.sender, shares, fee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/BaskMath.sol:19:29\n   │\n19 │                 if (d == 0) revert MathOverflow();\n   │                             ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/BaskMath.sol:22:28\n   │\n22 │             if (d <= high) revert MathOverflow();\n   │                            ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:612:69\n    │\n612 │             if (i < minAmountsOut.length && leg < minAmountsOut[i]) revert Slippage();\n    │                                                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:649:9\n    │\n649 │         emit LegPaid(token, to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `entered` is updated\n    ╭▸ src/BaskVault.sol:660:26\n    │\n660 │         if (amount != 0) this.payLeg(token, to, amount);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:661:9\n    │\n661 │         emit Claimed(msg.sender, token, to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:672:9\n    │\n672 │         emit DeficitFlagged(token, loss.amount, loss.since);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:678:33\n    │\n678 │         if (loss.amount == 0 || block.timestamp < loss.since + 7 days) revert InvalidState();\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:683:9\n    │\n683 │         emit LossRecognized(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/BaskVault.sol:781:95\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                                                                                               ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:760:13\n    │\n760 │         if (block.timestamp < depositsOpenAt) return _fail(s, Reason.WarmingUp, address(0));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:13\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │             ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:25\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:37\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                                     ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:61\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                                                             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:781:25\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:781:55\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:786:49\n    │\n786 │                 if (a.token == token) s.price = uint256(answer);\n    │                                                 ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:787:60\n    │\n787 │                 s.nav += BaskMath.mulDiv(managed[a.token], uint256(answer), 1e8);\n    │                                                            ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:805:13\n    │\n805 │         if (updated > block.timestamp) return Reason.FuturePrice;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:806:13\n    │\n806 │         if (block.timestamp - updated > PRICE_AGE) return Reason.StalePrice;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:804:13\n    │\n804 │         if (uint256(answer) < a.minAnswer || uint256(answer) > a.maxAnswer) return Reason.OutsideBand;\n    │             ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:804:46\n    │\n804 │         if (uint256(answer) < a.minAnswer || uint256(answer) > a.maxAnswer) return Reason.OutsideBand;\n    │                                              ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\n","passed":true},{"durationMs":13728,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/BaskAdversarial.t.sol:Bask64AssetsTest\n[PASS] test64MixedPausedBlockedMalformedRetiredAndWorkingTokens() (gas: 26669912)\nLogs:\n  64-asset redemption gas (including call and result copy): 9677575\n\n[PASS] test64TransfersConsumeEntirePayoutGas() (gas: 37431604)\nLogs:\n  64-asset redemption gas (including call and result copy): 22795771\n\n[PASS] test64UpgradedUnreadableTokensDoNotBlockExit() (gas: 24112106)\nLogs:\n  64-asset redemption gas (including call and result copy): 22745436\n\n[PASS] testAsset65RejectedEvenAfterRetirement() (gas: 459515)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 177.68ms (24.04ms CPU time)\n\nRan 18 tests for test/BaskVault.t.sol:BaskVaultTest\n[PASS] testAllPriceFailuresAndStatusParity() (gas: 2773037)\n[PASS] testBucketGlobalAndDecay() (gas: 1602698)\n[PASS] testDeploymentAndConstructorValidation() (gas: 71153)\n[PASS] testFeeRecipientCanRedeemOwnShares() (gas: 627661)\n[PASS] testFeeRecipientNeverCalledAndFeesAreFinal() (gas: 812201)\n[PASS] testFirstDepositAndDonationIgnored() (gas: 1158851)\n[PASS] testFuzzDepositRedeemConservation(uint96,bool) (runs: 256, μ: 691605, ~: 723424)\nLogs:\n  Bound result 607398081601252373440\n\n[PASS] testInclusiveBandAnd26HourPriceWithThreeOtherFreshFeeds() (gas: 3371589)\n[PASS] testManagedClosedAssetStillRequiresPriceAndEmptyAssetDoesNot() (gas: 1464822)\n[PASS] testMarketBoundariesAndFreshGate() (gas: 1664298)\n[PASS] testMinimumSharesDeadlineAndRecipient() (gas: 581417)\n[PASS] testNavCapAndValueBasedBucketLimit() (gas: 2625490)\n[PASS] testRedeemSlippageAndDeadlineAreAtomic() (gas: 788579)\n[PASS] testRejectsInexactAndFalseDepositTransfers() (gas: 1762336)\n[PASS] testRoundingUpFeesForSmallSubsequentDepositsAndRedemptions() (gas: 982904)\n[PASS] testRuntimeHasNoForbiddenOpcodes() (gas: 6508877)\n[PASS] testShareTransfersAndAllowance() (gas: 795549)\n[PASS] testUnsetRedeemFeeBurnsAllShares() (gas: 594474)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 313.65ms (333.21ms CPU time)\n\nRan 3 tests for test/BaskMath.t.sol:BaskMathTest\n[PASS] testFullWidthRedemptionMathAndRounding() (gas: 4635)\n[PASS] testFuzzExactCancellation(uint256,uint256) (runs: 256, μ: 3615, ~: 3534)\n[PASS] testMathOverflowUsesCustomError() (gas: 10574)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 323.56ms (323.51ms CPU time)\n\nRan 12 tests for test/BaskLosses.t.sol:BaskLossesTest\n[PASS] testClaimFailureRollsBackAndOnlyCallerCanClaim() (gas: 940191)\n[PASS] testDeferredClaimReservesBeforeOtherRedemptions() (gas: 1248541)\n[PASS] testDeficitBlocksDepositsButDoesNotAutomaticallyLowerManaged() (gas: 1374191)\n[PASS] testFuzzFailedLegConservation(uint96) (runs: 256, μ: 816466, ~: 816504)\nLogs:\n  Bound result 999999900188344579777\n\n[PASS] testLargerDeficitRestartsClockSmallerDoesNot() (gas: 884511)\n[PASS] testNonzeroSupplyWithZeroNAVRejectsDepositsButRedeems() (gas: 3461516)\n[PASS] testPartialClaimAndOwedUnderfundingCannotBlockRedeem() (gas: 1182086)\n[PASS] testRecognitionCannotExceedRecordedLoss() (gas: 750861)\n[PASS] testRecoveredDeficitClearedByDepositOrRecognition() (gas: 1149753)\n[PASS] testRedemptionOnDeficitUsesAvailableAndLeavesRemainingLoss() (gas: 740166)\n[PASS] testRetiredAssetsZeroNAVSkipChecksAndStillRedeemAndClaim() (gas: 4745150)\n[PASS] testUnreadableBalanceNeverAuthorizesLoss() (gas: 812071)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 323.60ms (329.58ms CPU time)\n\nRan 16 tests for test/BaskGovernance.t.sol:BaskGovernanceTest\n[PASS] testBandUsesExecutionAnswerAndStrictAge() (gas: 608167)\n[PASS] testCapRaisesDelayedLowerCancelsAllRaisesAndHasNoFloor() (gas: 618854)\n[PASS] testExpiredCancelledAndPendingEnumeration() (gas: 488016)\n[PASS] testFeedReplacementChecksBothTimesAndPreservesBand() (gas: 1351745)\n[PASS] testGenesisBatchAtomicAndFinalizedOnce() (gas: 1255156)\n[PASS] testGuardianCannotCancelItsReplacementAndOwnershipSeparation() (gas: 550807)\n[PASS] testGuardianRecheckedAgainstCurrentOwner() (gas: 368730)\n[PASS] testListingAndFeedShareDailyRateLimit() (gas: 3114816)\n[PASS] testListingChecksAtProposalAndExecution() (gas: 3652670)\n[PASS] testListingFailurePreservesProposalAndDailySlotForAnotherChange() (gas: 3346286)\n[PASS] testListingFeedCannotBeTakenByAnotherProposal() (gas: 2329259)\n[PASS] testProposalTimingJustBeforeAndAtBoundaries() (gas: 511454)\n[PASS] testReopenVoidedEvenByRepeatedClose() (gas: 658714)\n[PASS] testRetireClosedBothTimesVoidsAllProposals() (gas: 1620039)\n[PASS] testRetiredFeedMayBeReusedAndDoesNotCountInFreshQuorum() (gas: 3081717)\n[PASS] testUnauthorizedEntryPointsAndGuardianBoundaries() (gas: 1525633)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 328.66ms (7.58ms CPU time)\n\nRan 9 tests for test/BaskAdversarial.t.sol:BaskAdversarialTest\n[PASS] testAllFailedTransfersAtomicIncludingReturnBombs() (gas: 3629258)\n[PASS] testAllUnreadableBalanceOutcomesDeferWithoutRevert() (gas: 2491543)\n[PASS] testBalanceReadExceedingPayoutBudgetDefersThenClaims() (gas: 1896481)\n[PASS] testClaimExpensiveBalanceReadsAndRedeemWithinPayoutBudget() (gas: 1545578)\n[PASS] testDepositRedeemClaimAndAdminCallbacksBlocked() (gas: 7376298)\n[PASS] testExpensiveClaimBalanceReadsStillEnforceExactDebit() (gas: 1066526)\n[PASS] testFuzzLateSlippageRollsBackPaidAndOwedLegs(uint96,bool) (runs: 1000, μ: 2340402, ~: 2376420)\nLogs:\n  Bound result 4747179000000000010406\n\n[PASS] testNoReturnTransferAndSenderDebitSemantics() (gas: 807526)\n[PASS] testRolesCannotBlockRedeemOrClaim() (gas: 1347763)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 349.57ms (365.10ms CPU time)\n\nRan 5 tests for test/BaskEconomicProperties.t.sol:BaskEconomicPropertiesTest\n[PASS] testDepositReceiverAndDeferredClaimEvents() (gas: 808347)\n[PASS] testFirstDepositMinimumAndZeroAmounts() (gas: 913153)\n[PASS] testFuzzMultiAssetPricingAndFeeRounding(uint96,uint64,uint64,uint64,uint8) (runs: 1000, μ: 2089968, ~: 2089948)\nLogs:\n  Bound result 37500210310\n  Bound result 37500001631\n  Bound result 2500000001\n  Bound result 6289899681893867561\n\n[PASS] testFuzzRepeatedMixedAssetRoundTripsCannotProfit(uint96,uint8,bool) (runs: 1000, μ: 5802489, ~: 5361316)\nLogs:\n  Bound result 3\n  Bound result 173470993\n\n[PASS] testZeroRedeemOnEmptyVaultAndOneWeiExitWithUnsetFee() (gas: 665533)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 349.69ms (698.61ms CPU time)\n\nRan 3 tests for test/BaskInvariant.t.sol:BaskInvariantTest\n[PASS] invariant_assetsSharesAndDebtsAreConserved() (runs: 256, calls: 24576, reverts: 0)\n\n╭-------------+----------------+-------+---------+----------╮\n| Contract    | Selector       | Calls | Reverts | Discards |\n+===========================================================+\n| BaskHandler | advanceTime    | 1892  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | claim          | 1869  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | configureToken | 1913  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | confiscate     | 1832  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | deposit        | 1928  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | donate         | 1868  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | flagLoss       | 1911  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | governance     | 1837  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | recognizeLoss  | 1887  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | redeem         | 1874  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | redeemAll      | 1863  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | refreshMarket  | 1963  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | transferShares | 1939  | 0       | 0        |\n╰-------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 20000000000\n  Bound result 4718811536556710635\n  Bound result 95\n  Bound result 14400\n  Bound result 40000000000000000000\n  Bound result 14400\n  Bound result 16525\n  Bound result 10978\n  Bound result 2500000000\n  Bound result 9999999999999999601\n  Bound result 9377\n  Bound result 16223\n  Bound result 899093983245164188\n  Bound result 0\n  Bound result 17754\n  Bound result 11046\n  Bound result 5566694981391677941\n  Bound result 140185\n  Bound result 100000000000\n  Bound result 9999900000000604801\n  Bound result 9999900000000019512\n  Bound result 15606\n  Bound result 4068983393755360481\n  Bound result 0\n  Bound result 3\n  Bound result 43000\n  Bound result 1\n  Bound result 9999900000000002197\n  Bound result 17695\n  Bound result 15\n  Bound result 2349988850898997111\n  Bound result 9999900000000014653\n  Bound result 274502990508440731459\n  Bound result 0\n  Bound result 17600\n  Bound result 86400\n  Bound result 0\n  Bound result 100\n  Bound result 570659\n  Bound result 3790436877\n  Bound result 14068883393755965281\n  Bound result 7970069993629808352\n\n[PASS] testHandlerDistinguishesIncomingCreditFromOutgoingDebit() (gas: 2676095)\nLogs:\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 7421\n  Bound result 100000000000000\n  Bound result 1000000000000000000\n\n[PASS] testHandlerExercisesFailuresRecoveryAndRetirement() (gas: 7939121)\nLogs:\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 497499500000000000000\n  Bound result 1000000000000000000\n  Bound result 604800\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 13.66s (13.66s CPU time)\n\nRan 8 test suites in 13.66s (15.82s CPU time): 70 tests passed, 0 failed, 0 skipped (70 total tests)\n","passed":true},{"durationMs":36,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"BaskVault.acceptOwnership()\",\"BaskVault.approve(address,uint256)\",\"BaskVault.cancelProposal(uint256)\",\"BaskVault.claim(address,address)\",\"BaskVault.closeAsset(address)\",\"BaskVault.deposit(address,uint256,address,uint256,uint256)\",\"BaskVault.executeProposal(uint256)\",\"BaskVault.finalizeGenesis()\",\"BaskVault.flagDeficit(address)\",\"BaskVault.lowerNavCap(uint256)\",\"BaskVault.pauseDeposits()\",\"BaskVault.payLeg(address,address,uint256)\",\"BaskVault.proposeAsset(address,address)\",\"BaskVault.proposeAssets(address[],address[])\",\"BaskVault.proposeBand(address)\",\"BaskVault.proposeFeed(address,address)\",\"BaskVault.proposeGuardian(address)\",\"BaskVault.proposeNavCap(uint256)\",\"BaskVault.proposeReopen(address)\",\"BaskVault.proposeRetire(address)\",\"BaskVault.recognizeLoss(address)\",\"BaskVault.redeem(uint256,uint256[],uint256)\",\"BaskVault.setFeeRecipient(address)\",\"BaskVault.transfer(address,uint256)\",\"BaskVault.transferFrom(address,address,uint256)\",\"BaskVault.transferOwnership(address)\",\"BaskVault.unpauseDeposits()\"],\"files\":{\".gitignore\":3,\"README.md\":308,\"foundry.toml\":16,\"launch.json\":13,\"remappings.txt\":1,\"src/BaskMath.sol\":46,\"src/BaskVault.sol\":864,\"test/BaskAdversarial.t.sol\":348,\"test/BaskBase.t.sol\":98,\"test/BaskEconomicProperties.t.sol\":174,\"test/BaskGovernance.t.sol\":419,\"test/BaskInvariant.t.sol\":145,\"test/BaskLosses.t.sol\":242,\"test/BaskMath.t.sol\":31,\"test/BaskVault.t.sol\":310,\"test/STATEFUL_TESTS.md\":55,\"test/handlers/BaskHandler.sol\":379,\"test/mocks/StockMocks.sol\":230},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"31115b1cf5176de25131e376ba645691578a862a302a9d44ce926c13181c8812","verifiedTreeHash":"d5b99f72b10d8d71140fa9ef94b5f531089006ed","verifierVersion":"0.1.0+a2d9a899"},{"checks":[{"durationMs":21041,"exitCode":0,"name":"build","output":"Compiling 28 files with Solc 0.8.26\nSolc 0.8.26 finished in 20.70s\nCompiler run successful!\nwarning[boolean-cst]: misuse of a boolean constant\n    ╭▸ src/BaskVault.sol:815:32\n    │\n815 │         if (!readable) return (false, managed[token]);\n    │                                ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[boolean-cst]: misuse of a boolean constant\n    ╭▸ src/BaskVault.sol:851:26\n    │\n851 │         if (!ok) return (false, 0, 0);\n    │                          ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[weak-prng]: weak randomness derived from a predictable on-chain value\n    ╭▸ src/BaskVault.sol:771:23\n    │\n771 │         uint256 day = (block.timestamp / 1 days + 4) % 7;\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/weak-prng\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:520:9\n    │\n520 │         emit AssetListed(token, feed, low, high);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:372:9\n    │\n372 │         emit ProposalCreated(id, kind, token, target, value);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:478:44\n    │\n478 │         if (assetIndexPlusOne[token] != 0) revert InvalidAsset(token);\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:479:42\n    │\n479 │         if (assets.length == MAX_ASSETS) revert AssetLimit();\n    │                                          ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:481:32\n    │\n481 │         if (!ok || word != 18) revert InvalidAsset(token);\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:483:18\n    │\n483 │         if (!ok) revert InvalidAsset(token);\n    │                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:486:53\n    │\n486 │         if (!ok || word != uint256(uint160(token))) revert InvalidAsset(token);\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:493:31\n    │\n493 │         if (!ok || word != 8) revert InvalidFeed(feed);\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:495:59\n    │\n495 │         if (!ok || word == 0 || word > type(uint160).max) revert InvalidFeed(feed);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:498:67\n    │\n498 │             if (!a.retired && a.token != token && a.feed == feed) revert InvalidFeed(feed);\n    │                                                                   ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:502:33\n    │\n502 │         if (!ok || answer <= 0) revert InvalidFeed(feed);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:512:45\n    │\n512 │         if (answer > type(uint256).max / 4) revert InvalidAmount();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:389:17\n    │\n389 │             if (block.timestamp < nextAssetChangeAt) revert ChangeTooSoon();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:402:39\n    │\n402 │             if (!ok || answer <= 0 || updated > block.timestamp || block.timestamp - updated >= PRICE_AGE) {\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:402:68\n    │\n402 │             if (!ok || answer <= 0 || updated > block.timestamp || block.timestamp - updated >= PRICE_AGE) {\n    │                                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:398:13\n    │\n398 │             emit FeedChanged(p.token, p.target);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:406:13\n    │\n406 │             emit BandChanged(p.token, a.minAnswer, a.maxAnswer);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:424:9\n    │\n424 │         emit ProposalExecuted(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:405:48\n    │\n405 │             (a.minAnswer, a.maxAnswer) = _band(uint256(answer));\n    │                                                ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:436:13\n    │\n436 │         if (block.timestamp < p.createdAt + PROPOSAL_DELAY) return ProposalState.Waiting;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:437:13\n    │\n437 │         if (block.timestamp >= p.createdAt + PROPOSAL_DELAY + PROPOSAL_LIFETIME) {\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/BaskVault.sol:453:85\n    │\n453 │             if (state == ProposalState.Waiting || state == ProposalState.Ready) ids[n++] = start + i;\n    │                                                                                     ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:503:16\n    │\n503 │         return uint256(answer);\n    │                ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:528:13\n    │\n528 │         if (block.timestamp > deadline) revert DeadlineExpired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:561:17\n    │\n561 │                 emit DeficitCleared(t);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:246:9\n    │\n246 │         emit Transfer(address(0), to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:567:9\n    │\n567 │         emit Deposit(msg.sender, receiver, token, amount, shares, fee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:588:13\n    │\n588 │         if (elapsed >= 1 days) return 0;\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:597:13\n    │\n597 │         if (block.timestamp > deadline) revert DeadlineExpired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:618:17\n    │\n618 │                 emit LegOwed(msg.sender, token, leg);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:621:9\n    │\n621 │         emit Redeem(msg.sender, shares, fee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/BaskMath.sol:19:29\n   │\n19 │                 if (d == 0) revert MathOverflow();\n   │                             ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/BaskMath.sol:22:28\n   │\n22 │             if (d <= high) revert MathOverflow();\n   │                            ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:612:69\n    │\n612 │             if (i < minAmountsOut.length && leg < minAmountsOut[i]) revert Slippage();\n    │                                                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:649:9\n    │\n649 │         emit LegPaid(token, to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `entered` is updated\n    ╭▸ src/BaskVault.sol:660:26\n    │\n660 │         if (amount != 0) this.payLeg(token, to, amount);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:661:9\n    │\n661 │         emit Claimed(msg.sender, token, to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:672:9\n    │\n672 │         emit DeficitFlagged(token, loss.amount, loss.since);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:678:33\n    │\n678 │         if (loss.amount == 0 || block.timestamp < loss.since + 7 days) revert InvalidState();\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:683:9\n    │\n683 │         emit LossRecognized(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/BaskVault.sol:781:95\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                                                                                               ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:760:13\n    │\n760 │         if (block.timestamp < depositsOpenAt) return _fail(s, Reason.WarmingUp, address(0));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:13\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │             ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:25\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:37\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                                     ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:61\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                                                             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:781:25\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:781:55\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:786:49\n    │\n786 │                 if (a.token == token) s.price = uint256(answer);\n    │                                                 ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:787:60\n    │\n787 │                 s.nav += BaskMath.mulDiv(managed[a.token], uint256(answer), 1e8);\n    │                                                            ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:805:13\n    │\n805 │         if (updated > block.timestamp) return Reason.FuturePrice;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:806:13\n    │\n806 │         if (block.timestamp - updated > PRICE_AGE) return Reason.StalePrice;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:804:13\n    │\n804 │         if (uint256(answer) < a.minAnswer || uint256(answer) > a.maxAnswer) return Reason.OutsideBand;\n    │             ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:804:46\n    │\n804 │         if (uint256(answer) < a.minAnswer || uint256(answer) > a.maxAnswer) return Reason.OutsideBand;\n    │                                              ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\n","passed":true},{"durationMs":160,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 3 tests for test/BaskMath.t.sol:BaskMathTest\n[PASS] testFullWidthRedemptionMathAndRounding() (gas: 4635)\n[PASS] testFuzzExactCancellation(uint256,uint256) (runs: 256, μ: 3632, ~: 3534)\n[PASS] testMathOverflowUsesCustomError() (gas: 10574)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 2.92ms (2.89ms CPU time)\n\nRan 15 tests for test/BaskGovernance.t.sol:BaskGovernanceTest\n[PASS] testBandUsesExecutionAnswerAndStrictAge() (gas: 608145)\n[PASS] testCapRaisesDelayedLowerCancelsAllRaisesAndHasNoFloor() (gas: 618832)\n[PASS] testExpiredCancelledAndPendingEnumeration() (gas: 488016)\n[PASS] testFeedReplacementChecksBothTimesAndPreservesBand() (gas: 1351745)\n[PASS] testGenesisBatchAtomicAndFinalizedOnce() (gas: 1255134)\n[PASS] testGuardianCannotCancelItsReplacementAndOwnershipSeparation() (gas: 550785)\n[PASS] testGuardianRecheckedAgainstCurrentOwner() (gas: 368730)\n[PASS] testListingAndFeedShareDailyRateLimit() (gas: 3114816)\n[PASS] testListingChecksAtProposalAndExecution() (gas: 3652648)\n[PASS] testListingFeedCannotBeTakenByAnotherProposal() (gas: 2329237)\n[PASS] testProposalTimingJustBeforeAndAtBoundaries() (gas: 511432)\n[PASS] testReopenVoidedEvenByRepeatedClose() (gas: 658714)\n[PASS] testRetireClosedBothTimesVoidsAllProposals() (gas: 1620017)\n[PASS] testRetiredFeedMayBeReusedAndDoesNotCountInFreshQuorum() (gas: 3081717)\n[PASS] testUnauthorizedEntryPointsAndGuardianBoundaries() (gas: 1525518)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 4.68ms (10.31ms CPU time)\n\nRan 8 tests for test/BaskAdversarial.t.sol:BaskAdversarialTest\n[PASS] testAllFailedTransfersAtomicIncludingReturnBombs() (gas: 3629254)\n[PASS] testAllUnreadableBalanceOutcomesDeferWithoutRevert() (gas: 2491506)\n[PASS] testBalanceReadExceedingPayoutBudgetDefersThenClaims() (gas: 1896478)\n[PASS] testClaimExpensiveBalanceReadsAndRedeemWithinPayoutBudget() (gas: 1545575)\n[PASS] testDepositRedeemClaimAndAdminCallbacksBlocked() (gas: 7376155)\n[PASS] testExpensiveClaimBalanceReadsStillEnforceExactDebit() (gas: 1066523)\n[PASS] testNoReturnTransferAndSenderDebitSemantics() (gas: 807523)\n[PASS] testRolesCannotBlockRedeemOrClaim() (gas: 1347760)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 5.27ms (20.00ms CPU time)\n\nRan 18 tests for test/BaskVault.t.sol:BaskVaultTest\n[PASS] testAllPriceFailuresAndStatusParity() (gas: 2773037)\n[PASS] testBucketGlobalAndDecay() (gas: 1602698)\n[PASS] testDeploymentAndConstructorValidation() (gas: 71153)\n[PASS] testFeeRecipientCanRedeemOwnShares() (gas: 627661)\n[PASS] testFeeRecipientNeverCalledAndFeesAreFinal() (gas: 812201)\n[PASS] testFirstDepositAndDonationIgnored() (gas: 1158851)\n[PASS] testFuzzDepositRedeemConservation(uint96,bool) (runs: 256, μ: 689526, ~: 657467)\nLogs:\n  Bound result 999999900000007247195\n\n[PASS] testInclusiveBandAnd26HourPriceWithThreeOtherFreshFeeds() (gas: 3371589)\n[PASS] testManagedClosedAssetStillRequiresPriceAndEmptyAssetDoesNot() (gas: 1464822)\n[PASS] testMarketBoundariesAndFreshGate() (gas: 1664298)\n[PASS] testMinimumSharesDeadlineAndRecipient() (gas: 581417)\n[PASS] testNavCapAndValueBasedBucketLimit() (gas: 2625490)\n[PASS] testRedeemSlippageAndDeadlineAreAtomic() (gas: 788579)\n[PASS] testRejectsInexactAndFalseDepositTransfers() (gas: 1762336)\n[PASS] testRoundingUpFeesForSmallSubsequentDepositsAndRedemptions() (gas: 982904)\n[PASS] testRuntimeHasNoForbiddenOpcodes() (gas: 6508877)\n[PASS] testShareTransfersAndAllowance() (gas: 795549)\n[PASS] testUnsetRedeemFeeBurnsAllShares() (gas: 594474)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 24.09ms (48.46ms CPU time)\n\nRan 12 tests for test/BaskLosses.t.sol:BaskLossesTest\n[PASS] testClaimFailureRollsBackAndOnlyCallerCanClaim() (gas: 940191)\n[PASS] testDeferredClaimReservesBeforeOtherRedemptions() (gas: 1248541)\n[PASS] testDeficitBlocksDepositsButDoesNotAutomaticallyLowerManaged() (gas: 1374191)\n[PASS] testFuzzFailedLegConservation(uint96) (runs: 256, μ: 816457, ~: 816500)\nLogs:\n  Bound result 34523380577314196624\n\n[PASS] testLargerDeficitRestartsClockSmallerDoesNot() (gas: 884511)\n[PASS] testNonzeroSupplyWithZeroNAVRejectsDepositsButRedeems() (gas: 3461516)\n[PASS] testPartialClaimAndOwedUnderfundingCannotBlockRedeem() (gas: 1182086)\n[PASS] testRecognitionCannotExceedRecordedLoss() (gas: 750861)\n[PASS] testRecoveredDeficitClearedByDepositOrRecognition() (gas: 1149753)\n[PASS] testRedemptionOnDeficitUsesAvailableAndLeavesRemainingLoss() (gas: 740166)\n[PASS] testRetiredAssetsZeroNAVSkipChecksAndStillRedeemAndClaim() (gas: 4745150)\n[PASS] testUnreadableBalanceNeverAuthorizesLoss() (gas: 812071)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 26.55ms (34.95ms CPU time)\n\nRan 4 tests for test/BaskAdversarial.t.sol:Bask64AssetsTest\n[PASS] test64MixedPausedBlockedMalformedRetiredAndWorkingTokens() (gas: 26669912)\nLogs:\n  64-asset redemption gas (including call and result copy): 9677575\n\n[PASS] test64TransfersConsumeEntirePayoutGas() (gas: 37431604)\nLogs:\n  64-asset redemption gas (including call and result copy): 22795771\n\n[PASS] test64UpgradedUnreadableTokensDoNotBlockExit() (gas: 24112106)\nLogs:\n  64-asset redemption gas (including call and result copy): 22745436\n\n[PASS] testAsset65RejectedEvenAfterRetirement() (gas: 459515)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 82.16ms (27.63ms CPU time)\n\nRan 6 test suites in 82.93ms (145.67ms CPU time): 60 tests passed, 0 failed, 0 skipped (60 total tests)\n","passed":true},{"durationMs":35,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"BaskVault.acceptOwnership()\",\"BaskVault.approve(address,uint256)\",\"BaskVault.cancelProposal(uint256)\",\"BaskVault.claim(address,address)\",\"BaskVault.closeAsset(address)\",\"BaskVault.deposit(address,uint256,address,uint256,uint256)\",\"BaskVault.executeProposal(uint256)\",\"BaskVault.finalizeGenesis()\",\"BaskVault.flagDeficit(address)\",\"BaskVault.lowerNavCap(uint256)\",\"BaskVault.pauseDeposits()\",\"BaskVault.payLeg(address,address,uint256)\",\"BaskVault.proposeAsset(address,address)\",\"BaskVault.proposeAssets(address[],address[])\",\"BaskVault.proposeBand(address)\",\"BaskVault.proposeFeed(address,address)\",\"BaskVault.proposeGuardian(address)\",\"BaskVault.proposeNavCap(uint256)\",\"BaskVault.proposeReopen(address)\",\"BaskVault.proposeRetire(address)\",\"BaskVault.recognizeLoss(address)\",\"BaskVault.redeem(uint256,uint256[],uint256)\",\"BaskVault.setFeeRecipient(address)\",\"BaskVault.transfer(address,uint256)\",\"BaskVault.transferFrom(address,address,uint256)\",\"BaskVault.transferOwnership(address)\",\"BaskVault.unpauseDeposits()\"],\"files\":{\".gitignore\":3,\"README.md\":308,\"foundry.toml\":16,\"launch.json\":13,\"remappings.txt\":1,\"src/BaskMath.sol\":46,\"src/BaskVault.sol\":864,\"test/BaskAdversarial.t.sol\":283,\"test/BaskBase.t.sol\":98,\"test/BaskGovernance.t.sol\":379,\"test/BaskLosses.t.sol\":242,\"test/BaskMath.t.sol\":31,\"test/BaskVault.t.sol\":310,\"test/mocks/StockMocks.sol\":230},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":2958,"exitCode":0,"name":"slither","output":"[high/medium] weak-prng at src/BaskVault.sol:758: BaskVault._snapshot(address) (src/BaskVault.sol#758-795) uses a weak PRNG: \"day = (block.timestamp / 86400 + 4) % 7 (src/BaskVault.sol#771)\"\n[high/medium] weak-prng at src/BaskVault.sol:758: BaskVault._snapshot(address) (src/BaskVault.sol#758-795) uses a weak PRNG: \"secondsToday = block.timestamp % 86400 (src/BaskVault.sol#772)\"\n[high/medium] incorrect-exp at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) has bitwise-xor operator ^ instead of the exponentiation operator **: \n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/high] incorrect-equality at src/BaskVault.sol:758: BaskVault._snapshot(address) (src/BaskVault.sol#758-795) uses a dangerous strict equality:\n[medium/medium] uninitialized-local at src/BaskVault.sol:776: BaskVault._snapshot(address).fresh (src/BaskVault.sol#776) is a local variable never initialized\n[low/medium] timestamp at src/BaskVault.sol:797: BaskVault._priceStatus(BaskVault.Asset,bool,int256,uint256) (src/BaskVault.sol#797-811) uses timestamp for comparisons\n[low/medium] timestamp at src/BaskVault.sol:384: BaskVault.executeProposal(uint256) (src/BaskVault.sol#384-425) uses timestamp for comparisons\n[low/medium] timestamp at src/BaskVault.sol:427: BaskVault.proposalState(uint256) (src/BaskVault.sol#427-441) uses timestamp for comparisons\n[low/medium] timestamp at src/BaskVault.sol:758: BaskVault._snapshot(address) (src/BaskVault.sol#758-795) uses timestamp for comparisons\n[low/medium] timestamp at src/BaskVault.sol:675: BaskVault.recognizeLoss(address) (src/BaskVault.sol#675-684) uses timestamp for comparisons\n[low/medium] timestamp at src/BaskVault.sol:523: BaskVault.deposit(address,uint256,address,uint256,uint256) (src/BaskVault.sol#523-568) uses timestamp for comparisons\n[low/medium] timestamp at src/BaskVault.sol:592: BaskVault.redeem(uint256,uint256[],uint256) (src/BaskVault.sol#592-622) uses timestamp for comparisons\n[low/medium] timestamp at src/BaskVault.sol:586: BaskVault.decayedBucket() (src/BaskVault.sol#586-590) uses timestamp for comparisons","passed":true},{"durationMs":364,"exitCode":0,"name":"aderyn","output":"[high] incorrect-caret-operator at src/BaskMath.sol:36: Incorrect use of caret operator\n[high] weak-randomness at src/BaskVault.sol:772: Weak Randomness\n[low] centralization-risk at src/BaskVault.sol:256: Centralization Risk (13 places)\n[low] costly-loop at src/BaskVault.sol:321: Costly operations inside loop (3 places)\n[low] large-numeric-literal at src/BaskVault.sol:807: Large Numeric Literal (2 places)\n[low] literal-instead-of-constant at src/BaskVault.sol:303: Literal Instead of Constant (17 places)\n[low] local-variable-shadowing at src/BaskVault.sol:94: Local Variable Shadows State Variable (2 places)\n[low] require-revert-in-loop at src/BaskVault.sol:321: Loop Contains `require`/`revert` (5 places)\n[low] storage-array-length-not-cached at src/BaskVault.sol:496: Storage Array Length not Cached (6 places)\n[low] unchecked-return at src/BaskVault.sol:342: Unchecked Return (5 places)\n[low] uninitialized-local-variable at src/BaskVault.sol:451: Uninitialized Local Variable (5 places)","passed":true},{"durationMs":3823,"exitCode":0,"name":"proof 464a69bafa73","output":"Compiling 23 files with Solc 0.8.26\nSolc 0.8.26 finished in 3.33s\nCompiler run successful!\n\nRan 1 test for test/imd-proof-90db174a/Proof_464a69bafa73.t.sol:ClaimBalanceGasTest\n[PASS] testOwedLegClaimableWhenBalanceOfNeedsMoreThan50kGas() (gas: 735177)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.07ms (396.46µs CPU time)\n\nRan 1 test suite in 2.47ms (1.07ms CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)\n","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"675a8fde125ed64e7ab8b94ea6dce55eec9e8cb7e6e9ef3616c7e1e39b860d59","verifiedTreeHash":"0b80e8fbfed981abb1d4daeb50c3923a6a69142c","verifierVersion":"0.1.0+be003835"},{"checks":[{"durationMs":36392,"exitCode":0,"name":"build","output":"Compiling 31 files with Solc 0.8.26\nSolc 0.8.26 finished in 35.91s\nCompiler run successful!\nwarning[boolean-cst]: misuse of a boolean constant\n    ╭▸ src/BaskVault.sol:815:32\n    │\n815 │         if (!readable) return (false, managed[token]);\n    │                                ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[boolean-cst]: misuse of a boolean constant\n    ╭▸ src/BaskVault.sol:846:26\n    │\n846 │         if (!ok) return (false, 0, 0);\n    │                          ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[weak-prng]: weak randomness derived from a predictable on-chain value\n    ╭▸ src/BaskVault.sol:771:23\n    │\n771 │         uint256 day = (block.timestamp / 1 days + 4) % 7;\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/weak-prng\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:520:9\n    │\n520 │         emit AssetListed(token, feed, low, high);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:372:9\n    │\n372 │         emit ProposalCreated(id, kind, token, target, value);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:478:44\n    │\n478 │         if (assetIndexPlusOne[token] != 0) revert InvalidAsset(token);\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:479:42\n    │\n479 │         if (assets.length == MAX_ASSETS) revert AssetLimit();\n    │                                          ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:481:32\n    │\n481 │         if (!ok || word != 18) revert InvalidAsset(token);\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:483:18\n    │\n483 │         if (!ok) revert InvalidAsset(token);\n    │                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:486:53\n    │\n486 │         if (!ok || word != uint256(uint160(token))) revert InvalidAsset(token);\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:493:31\n    │\n493 │         if (!ok || word != 8) revert InvalidFeed(feed);\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:495:59\n    │\n495 │         if (!ok || word == 0 || word > type(uint160).max) revert InvalidFeed(feed);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:498:67\n    │\n498 │             if (!a.retired && a.token != token && a.feed == feed) revert InvalidFeed(feed);\n    │                                                                   ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:502:33\n    │\n502 │         if (!ok || answer <= 0) revert InvalidFeed(feed);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:512:45\n    │\n512 │         if (answer > type(uint256).max / 4) revert InvalidAmount();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:389:17\n    │\n389 │             if (block.timestamp < nextAssetChangeAt) revert ChangeTooSoon();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:402:39\n    │\n402 │             if (!ok || answer <= 0 || updated > block.timestamp || block.timestamp - updated >= PRICE_AGE) {\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:402:68\n    │\n402 │             if (!ok || answer <= 0 || updated > block.timestamp || block.timestamp - updated >= PRICE_AGE) {\n    │                                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:398:13\n    │\n398 │             emit FeedChanged(p.token, p.target);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:406:13\n    │\n406 │             emit BandChanged(p.token, a.minAnswer, a.maxAnswer);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:424:9\n    │\n424 │         emit ProposalExecuted(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:405:48\n    │\n405 │             (a.minAnswer, a.maxAnswer) = _band(uint256(answer));\n    │                                                ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:436:13\n    │\n436 │         if (block.timestamp < p.createdAt + PROPOSAL_DELAY) return ProposalState.Waiting;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:437:13\n    │\n437 │         if (block.timestamp >= p.createdAt + PROPOSAL_DELAY + PROPOSAL_LIFETIME) {\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/BaskVault.sol:453:85\n    │\n453 │             if (state == ProposalState.Waiting || state == ProposalState.Ready) ids[n++] = start + i;\n    │                                                                                     ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:503:16\n    │\n503 │         return uint256(answer);\n    │                ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:528:13\n    │\n528 │         if (block.timestamp > deadline) revert DeadlineExpired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:561:17\n    │\n561 │                 emit DeficitCleared(t);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:246:9\n    │\n246 │         emit Transfer(address(0), to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:567:9\n    │\n567 │         emit Deposit(msg.sender, receiver, token, amount, shares, fee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:588:13\n    │\n588 │         if (elapsed >= 1 days) return 0;\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:597:13\n    │\n597 │         if (block.timestamp > deadline) revert DeadlineExpired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:618:17\n    │\n618 │                 emit LegOwed(msg.sender, token, leg);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:621:9\n    │\n621 │         emit Redeem(msg.sender, shares, fee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/BaskMath.sol:19:29\n   │\n19 │                 if (d == 0) revert MathOverflow();\n   │                             ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/BaskMath.sol:22:28\n   │\n22 │             if (d <= high) revert MathOverflow();\n   │                            ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:612:69\n    │\n612 │             if (i < minAmountsOut.length && leg < minAmountsOut[i]) revert Slippage();\n    │                                                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:649:9\n    │\n649 │         emit LegPaid(token, to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `entered` is updated\n    ╭▸ src/BaskVault.sol:660:26\n    │\n660 │         if (amount != 0) this.payLeg(token, to, amount);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:661:9\n    │\n661 │         emit Claimed(msg.sender, token, to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:672:9\n    │\n672 │         emit DeficitFlagged(token, loss.amount, loss.since);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:678:33\n    │\n678 │         if (loss.amount == 0 || block.timestamp < loss.since + 7 days) revert InvalidState();\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:683:9\n    │\n683 │         emit LossRecognized(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/BaskVault.sol:781:95\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                                                                                               ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:760:13\n    │\n760 │         if (block.timestamp < depositsOpenAt) return _fail(s, Reason.WarmingUp, address(0));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:13\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │             ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:25\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:37\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                                     ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:61\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                                                             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:781:25\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:781:55\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:786:49\n    │\n786 │                 if (a.token == token) s.price = uint256(answer);\n    │                                                 ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:787:60\n    │\n787 │                 s.nav += BaskMath.mulDiv(managed[a.token], uint256(answer), 1e8);\n    │                                                            ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:805:13\n    │\n805 │         if (updated > block.timestamp) return Reason.FuturePrice;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:806:13\n    │\n806 │         if (block.timestamp - updated > PRICE_AGE) return Reason.StalePrice;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:804:13\n    │\n804 │         if (uint256(answer) < a.minAnswer || uint256(answer) > a.maxAnswer) return Reason.OutsideBand;\n    │             ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:804:46\n    │\n804 │         if (uint256(answer) < a.minAnswer || uint256(answer) > a.maxAnswer) return Reason.OutsideBand;\n    │                                              ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\n","passed":true},{"durationMs":16878,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 3 tests for test/BaskMath.t.sol:BaskMathTest\n[PASS] testFullWidthRedemptionMathAndRounding() (gas: 4635)\n[PASS] testFuzzExactCancellation(uint256,uint256) (runs: 256, μ: 3600, ~: 3534)\n[PASS] testMathOverflowUsesCustomError() (gas: 10574)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 3.47ms (3.44ms CPU time)\n\nRan 4 tests for test/BaskAdversarial.t.sol:Bask64AssetsTest\n[PASS] test64MixedPausedBlockedMalformedRetiredAndWorkingTokens() (gas: 24982544)\nLogs:\n  64-asset redemption gas (including call and result copy): 7991439\n\n[PASS] test64TransfersConsumeEntirePayoutGas() (gas: 37306036)\nLogs:\n  64-asset redemption gas (including call and result copy): 22674427\n\n[PASS] test64UpgradedUnreadableTokensDoNotBlockExit() (gas: 11661930)\nLogs:\n  64-asset redemption gas (including call and result copy): 10295260\n\n[PASS] testAsset65RejectedEvenAfterRetirement() (gas: 459515)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 135.60ms (38.42ms CPU time)\n\nRan 12 tests for test/BaskLosses.t.sol:BaskLossesTest\n[PASS] testClaimFailureRollsBackAndOnlyCallerCanClaim() (gas: 920745)\n[PASS] testDeferredClaimReservesBeforeOtherRedemptions() (gas: 1220060)\n[PASS] testDeficitBlocksDepositsButDoesNotAutomaticallyLowerManaged() (gas: 1348663)\n[PASS] testFuzzFailedLegConservation(uint96) (runs: 256, μ: 801285, ~: 801339)\nLogs:\n  Bound result 437081337593464722164\n\n[PASS] testLargerDeficitRestartsClockSmallerDoesNot() (gas: 870686)\n[PASS] testNonzeroSupplyWithZeroNAVRejectsDepositsButRedeems() (gas: 3393628)\n[PASS] testPartialClaimAndOwedUnderfundingCannotBlockRedeem() (gas: 1153837)\n[PASS] testRecognitionCannotExceedRecordedLoss() (gas: 738310)\n[PASS] testRecoveredDeficitClearedByDepositOrRecognition() (gas: 1130591)\n[PASS] testRedemptionOnDeficitUsesAvailableAndLeavesRemainingLoss() (gas: 724724)\n[PASS] testRetiredAssetsZeroNAVSkipChecksAndStillRedeemAndClaim() (gas: 4473897)\n[PASS] testUnreadableBalanceNeverAuthorizesLoss() (gas: 803295)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 331.60ms (183.16ms CPU time)\n\nRan 5 tests for test/BaskAdversarial.t.sol:BaskAdversarialTest\n[PASS] testAllFailedTransfersAtomicIncludingReturnBombs() (gas: 3553828)\n[PASS] testAllUnreadableBalanceOutcomesDeferWithoutRevert() (gas: 2210690)\n[PASS] testDepositRedeemClaimAndAdminCallbacksBlocked() (gas: 7200388)\n[PASS] testNoReturnTransferAndSenderDebitSemantics() (gas: 787349)\n[PASS] testRolesCannotBlockRedeemOrClaim() (gas: 1332550)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 349.53ms (18.40ms CPU time)\n\nRan 15 tests for test/BaskGovernance.t.sol:BaskGovernanceTest\n[PASS] testBandUsesExecutionAnswerAndStrictAge() (gas: 601779)\n[PASS] testCapRaisesDelayedLowerCancelsAllRaisesAndHasNoFloor() (gas: 618832)\n[PASS] testExpiredCancelledAndPendingEnumeration() (gas: 488016)\n[PASS] testFeedReplacementChecksBothTimesAndPreservesBand() (gas: 1345379)\n[PASS] testGenesisBatchAtomicAndFinalizedOnce() (gas: 1254870)\n[PASS] testGuardianCannotCancelItsReplacementAndOwnershipSeparation() (gas: 550785)\n[PASS] testGuardianRecheckedAgainstCurrentOwner() (gas: 368730)\n[PASS] testListingAndFeedShareDailyRateLimit() (gas: 3066858)\n[PASS] testListingChecksAtProposalAndExecution() (gas: 3604426)\n[PASS] testListingFeedCannotBeTakenByAnotherProposal() (gas: 2289767)\n[PASS] testProposalTimingJustBeforeAndAtBoundaries() (gas: 511432)\n[PASS] testReopenVoidedEvenByRepeatedClose() (gas: 652348)\n[PASS] testRetireClosedBothTimesVoidsAllProposals() (gas: 1607285)\n[PASS] testRetiredFeedMayBeReusedAndDoesNotCountInFreshQuorum() (gas: 3027028)\n[PASS] testUnauthorizedEntryPointsAndGuardianBoundaries() (gas: 1519030)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 395.83ms (14.81ms CPU time)\n\nRan 18 tests for test/BaskVault.t.sol:BaskVaultTest\n[PASS] testAllPriceFailuresAndStatusParity() (gas: 2717865)\n[PASS] testBucketGlobalAndDecay() (gas: 1576380)\n[PASS] testDeploymentAndConstructorValidation() (gas: 71153)\n[PASS] testFeeRecipientCanRedeemOwnShares() (gas: 614341)\n[PASS] testFeeRecipientNeverCalledAndFeesAreFinal() (gas: 798881)\n[PASS] testFirstDepositAndDonationIgnored() (gas: 1126067)\n[PASS] testFuzzDepositRedeemConservation(uint96,bool) (runs: 256, μ: 670756, ~: 644128)\nLogs:\n  Bound result 67206605416414685184\n\n[PASS] testInclusiveBandAnd26HourPriceWithThreeOtherFreshFeeds() (gas: 3301923)\n[PASS] testManagedClosedAssetStillRequiresPriceAndEmptyAssetDoesNot() (gas: 1434338)\n[PASS] testMarketBoundariesAndFreshGate() (gas: 1614882)\n[PASS] testMinimumSharesDeadlineAndRecipient() (gas: 568441)\n[PASS] testNavCapAndValueBasedBucketLimit() (gas: 2572754)\n[PASS] testRedeemSlippageAndDeadlineAreAtomic() (gas: 770671)\n[PASS] testRejectsInexactAndFalseDepositTransfers() (gas: 1722788)\n[PASS] testRoundingUpFeesForSmallSubsequentDepositsAndRedemptions() (gas: 963196)\n[PASS] testRuntimeHasNoForbiddenOpcodes() (gas: 6486872)\n[PASS] testShareTransfersAndAllowance() (gas: 788939)\n[PASS] testUnsetRedeemFeeBurnsAllShares() (gas: 581154)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 395.70ms (195.38ms CPU time)\n\nRan 5 tests for test/BaskEconomicProperties.t.sol:BaskEconomicPropertiesTest\n[PASS] testDepositReceiverAndDeferredClaimEvents() (gas: 793187)\n[PASS] testFirstDepositMinimumAndZeroAmounts() (gas: 887079)\n[PASS] testFuzzMultiAssetPricingAndFeeRounding(uint96,uint64,uint64,uint64,uint8) (runs: 1000, μ: 2049660, ~: 2049622)\nLogs:\n  Bound result 37505604781\n  Bound result 18875777425\n  Bound result 24274499472\n  Bound result 7733168271296186796\n\n[PASS] testFuzzRepeatedMixedAssetRoundTripsCannotProfit(uint96,uint8,bool) (runs: 1000, μ: 5644691, ~: 4541045)\nLogs:\n  Bound result 2\n  Bound result 4264337593543950332\n\n[PASS] testZeroRedeemOnEmptyVaultAndOneWeiExitWithUnsetFee() (gas: 658923)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 396.11ms (607.14ms CPU time)\n\nRan 3 tests for test/BaskInvariant.t.sol:BaskInvariantTest\n[PASS] invariant_assetsSharesAndDebtsAreConserved() (runs: 256, calls: 24576, reverts: 0)\n\n╭-------------+----------------+-------+---------+----------╮\n| Contract    | Selector       | Calls | Reverts | Discards |\n+===========================================================+\n| BaskHandler | advanceTime    | 1869  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | claim          | 1834  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | configureToken | 1936  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | confiscate     | 1922  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | deposit        | 1778  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | donate         | 1904  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | flagLoss       | 1807  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | governance     | 1909  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | recognizeLoss  | 1905  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | redeem         | 1915  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | redeemAll      | 1909  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | refreshMarket  | 1977  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| BaskHandler | transferShares | 1911  | 0       | 0        |\n╰-------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 100000000\n  Bound result 6510005578180799106\n  Bound result 8584\n  Bound result 244\n  Bound result 684825676888130473\n  Bound result 1000000000000000\n  Bound result 29787\n  Bound result 0\n  Bound result 197274\n  Bound result 11478\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 322001\n  Bound result 1000000000000059\n  Bound result 1728315000\n  Bound result 108095726113419035\n  Bound result 5619724123588972100\n  Bound result 0\n  Bound result 13\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 552751\n  Bound result 296\n  Bound result 9999900000000022950\n  Bound result 568033\n  Bound result 23811\n  Bound result 199999999799998\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 5\n  Bound result 395133\n  Bound result 502059793033550157\n  Bound result 312050\n  Bound result 0\n  Bound result 463234\n\n[PASS] testHandlerDistinguishesIncomingCreditFromOutgoingDebit() (gas: 2646349)\nLogs:\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 7421\n  Bound result 100000000000000\n  Bound result 1000000000000000000\n\n[PASS] testHandlerExercisesFailuresRecoveryAndRetirement() (gas: 7845087)\nLogs:\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 10000000000000000000\n  Bound result 497499500000000000000\n  Bound result 1000000000000000000\n  Bound result 604800\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 16.75s (16.76s CPU time)\n\nRan 8 test suites in 16.75s (18.76s CPU time): 65 tests passed, 0 failed, 0 skipped (65 total tests)\n","passed":true},{"durationMs":38,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"BaskVault.acceptOwnership()\",\"BaskVault.approve(address,uint256)\",\"BaskVault.cancelProposal(uint256)\",\"BaskVault.claim(address,address)\",\"BaskVault.closeAsset(address)\",\"BaskVault.deposit(address,uint256,address,uint256,uint256)\",\"BaskVault.executeProposal(uint256)\",\"BaskVault.finalizeGenesis()\",\"BaskVault.flagDeficit(address)\",\"BaskVault.lowerNavCap(uint256)\",\"BaskVault.pauseDeposits()\",\"BaskVault.payLeg(address,address,uint256)\",\"BaskVault.proposeAsset(address,address)\",\"BaskVault.proposeAssets(address[],address[])\",\"BaskVault.proposeBand(address)\",\"BaskVault.proposeFeed(address,address)\",\"BaskVault.proposeGuardian(address)\",\"BaskVault.proposeNavCap(uint256)\",\"BaskVault.proposeReopen(address)\",\"BaskVault.proposeRetire(address)\",\"BaskVault.recognizeLoss(address)\",\"BaskVault.redeem(uint256,uint256[],uint256)\",\"BaskVault.setFeeRecipient(address)\",\"BaskVault.transfer(address,uint256)\",\"BaskVault.transferFrom(address,address,uint256)\",\"BaskVault.transferOwnership(address)\",\"BaskVault.unpauseDeposits()\"],\"files\":{\".gitignore\":3,\"README.md\":255,\"foundry.toml\":16,\"launch.json\":13,\"remappings.txt\":1,\"src/BaskMath.sol\":46,\"src/BaskVault.sol\":859,\"test/BaskAdversarial.t.sol\":228,\"test/BaskBase.t.sol\":98,\"test/BaskEconomicProperties.t.sol\":174,\"test/BaskGovernance.t.sol\":379,\"test/BaskInvariant.t.sol\":145,\"test/BaskLosses.t.sol\":242,\"test/BaskMath.t.sol\":31,\"test/BaskVault.t.sol\":310,\"test/STATEFUL_TESTS.md\":48,\"test/handlers/BaskHandler.sol\":379,\"test/mocks/StockMocks.sol\":218},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"75e9ed1897b2cb8c075d190941d7b8ddba8bf1d65c0efcb892ecec63b20a02e1","verifiedTreeHash":"4631baf71fe229fdf655035cbc2f1a5394b5d065","verifierVersion":"0.1.0+be003835"},{"checks":[{"durationMs":20144,"exitCode":0,"name":"build","output":"Compiling 28 files with Solc 0.8.26\nSolc 0.8.26 finished in 19.80s\nCompiler run successful!\nwarning[boolean-cst]: misuse of a boolean constant\n    ╭▸ src/BaskVault.sol:815:32\n    │\n815 │         if (!readable) return (false, managed[token]);\n    │                                ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[boolean-cst]: misuse of a boolean constant\n    ╭▸ src/BaskVault.sol:846:26\n    │\n846 │         if (!ok) return (false, 0, 0);\n    │                          ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[weak-prng]: weak randomness derived from a predictable on-chain value\n    ╭▸ src/BaskVault.sol:771:23\n    │\n771 │         uint256 day = (block.timestamp / 1 days + 4) % 7;\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/weak-prng\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:520:9\n    │\n520 │         emit AssetListed(token, feed, low, high);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:372:9\n    │\n372 │         emit ProposalCreated(id, kind, token, target, value);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:478:44\n    │\n478 │         if (assetIndexPlusOne[token] != 0) revert InvalidAsset(token);\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:479:42\n    │\n479 │         if (assets.length == MAX_ASSETS) revert AssetLimit();\n    │                                          ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:481:32\n    │\n481 │         if (!ok || word != 18) revert InvalidAsset(token);\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:483:18\n    │\n483 │         if (!ok) revert InvalidAsset(token);\n    │                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:486:53\n    │\n486 │         if (!ok || word != uint256(uint160(token))) revert InvalidAsset(token);\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:493:31\n    │\n493 │         if (!ok || word != 8) revert InvalidFeed(feed);\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:495:59\n    │\n495 │         if (!ok || word == 0 || word > type(uint160).max) revert InvalidFeed(feed);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:498:67\n    │\n498 │             if (!a.retired && a.token != token && a.feed == feed) revert InvalidFeed(feed);\n    │                                                                   ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:502:33\n    │\n502 │         if (!ok || answer <= 0) revert InvalidFeed(feed);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:512:45\n    │\n512 │         if (answer > type(uint256).max / 4) revert InvalidAmount();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:389:17\n    │\n389 │             if (block.timestamp < nextAssetChangeAt) revert ChangeTooSoon();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:402:39\n    │\n402 │             if (!ok || answer <= 0 || updated > block.timestamp || block.timestamp - updated >= PRICE_AGE) {\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:402:68\n    │\n402 │             if (!ok || answer <= 0 || updated > block.timestamp || block.timestamp - updated >= PRICE_AGE) {\n    │                                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:398:13\n    │\n398 │             emit FeedChanged(p.token, p.target);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:406:13\n    │\n406 │             emit BandChanged(p.token, a.minAnswer, a.maxAnswer);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:424:9\n    │\n424 │         emit ProposalExecuted(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:405:48\n    │\n405 │             (a.minAnswer, a.maxAnswer) = _band(uint256(answer));\n    │                                                ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:436:13\n    │\n436 │         if (block.timestamp < p.createdAt + PROPOSAL_DELAY) return ProposalState.Waiting;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:437:13\n    │\n437 │         if (block.timestamp >= p.createdAt + PROPOSAL_DELAY + PROPOSAL_LIFETIME) {\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/BaskVault.sol:453:85\n    │\n453 │             if (state == ProposalState.Waiting || state == ProposalState.Ready) ids[n++] = start + i;\n    │                                                                                     ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:503:16\n    │\n503 │         return uint256(answer);\n    │                ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:528:13\n    │\n528 │         if (block.timestamp > deadline) revert DeadlineExpired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:561:17\n    │\n561 │                 emit DeficitCleared(t);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:246:9\n    │\n246 │         emit Transfer(address(0), to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:567:9\n    │\n567 │         emit Deposit(msg.sender, receiver, token, amount, shares, fee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:588:13\n    │\n588 │         if (elapsed >= 1 days) return 0;\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:597:13\n    │\n597 │         if (block.timestamp > deadline) revert DeadlineExpired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:618:17\n    │\n618 │                 emit LegOwed(msg.sender, token, leg);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:621:9\n    │\n621 │         emit Redeem(msg.sender, shares, fee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/BaskMath.sol:19:29\n   │\n19 │                 if (d == 0) revert MathOverflow();\n   │                             ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/BaskMath.sol:22:28\n   │\n22 │             if (d <= high) revert MathOverflow();\n   │                            ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:612:69\n    │\n612 │             if (i < minAmountsOut.length && leg < minAmountsOut[i]) revert Slippage();\n    │                                                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:649:9\n    │\n649 │         emit LegPaid(token, to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `entered` is updated\n    ╭▸ src/BaskVault.sol:660:26\n    │\n660 │         if (amount != 0) this.payLeg(token, to, amount);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:661:9\n    │\n661 │         emit Claimed(msg.sender, token, to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:672:9\n    │\n672 │         emit DeficitFlagged(token, loss.amount, loss.since);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:678:33\n    │\n678 │         if (loss.amount == 0 || block.timestamp < loss.since + 7 days) revert InvalidState();\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:683:9\n    │\n683 │         emit LossRecognized(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/BaskVault.sol:781:95\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                                                                                               ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:760:13\n    │\n760 │         if (block.timestamp < depositsOpenAt) return _fail(s, Reason.WarmingUp, address(0));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:13\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │             ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:25\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:37\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                                     ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:61\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                                                             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:781:25\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:781:55\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:786:49\n    │\n786 │                 if (a.token == token) s.price = uint256(answer);\n    │                                                 ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:787:60\n    │\n787 │                 s.nav += BaskMath.mulDiv(managed[a.token], uint256(answer), 1e8);\n    │                                                            ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:805:13\n    │\n805 │         if (updated > block.timestamp) return Reason.FuturePrice;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:806:13\n    │\n806 │         if (block.timestamp - updated > PRICE_AGE) return Reason.StalePrice;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:804:13\n    │\n804 │         if (uint256(answer) < a.minAnswer || uint256(answer) > a.maxAnswer) return Reason.OutsideBand;\n    │             ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:804:46\n    │\n804 │         if (uint256(answer) < a.minAnswer || uint256(answer) > a.maxAnswer) return Reason.OutsideBand;\n    │                                              ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\n","passed":true},{"durationMs":179,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 5 tests for test/BaskAdversarial.t.sol:BaskAdversarialTest\n[PASS] testAllFailedTransfersAtomicIncludingReturnBombs() (gas: 3553828)\n[PASS] testAllUnreadableBalanceOutcomesDeferWithoutRevert() (gas: 2210690)\n[PASS] testDepositRedeemClaimAndAdminCallbacksBlocked() (gas: 7200388)\n[PASS] testNoReturnTransferAndSenderDebitSemantics() (gas: 787349)\n[PASS] testRolesCannotBlockRedeemOrClaim() (gas: 1332550)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 4.61ms (8.16ms CPU time)\n\nRan 15 tests for test/BaskGovernance.t.sol:BaskGovernanceTest\n[PASS] testBandUsesExecutionAnswerAndStrictAge() (gas: 601779)\n[PASS] testCapRaisesDelayedLowerCancelsAllRaisesAndHasNoFloor() (gas: 618832)\n[PASS] testExpiredCancelledAndPendingEnumeration() (gas: 488016)\n[PASS] testFeedReplacementChecksBothTimesAndPreservesBand() (gas: 1345379)\n[PASS] testGenesisBatchAtomicAndFinalizedOnce() (gas: 1254870)\n[PASS] testGuardianCannotCancelItsReplacementAndOwnershipSeparation() (gas: 550785)\n[PASS] testGuardianRecheckedAgainstCurrentOwner() (gas: 368730)\n[PASS] testListingAndFeedShareDailyRateLimit() (gas: 3066858)\n[PASS] testListingChecksAtProposalAndExecution() (gas: 3604426)\n[PASS] testListingFeedCannotBeTakenByAnotherProposal() (gas: 2289767)\n[PASS] testProposalTimingJustBeforeAndAtBoundaries() (gas: 511432)\n[PASS] testReopenVoidedEvenByRepeatedClose() (gas: 652348)\n[PASS] testRetireClosedBothTimesVoidsAllProposals() (gas: 1607285)\n[PASS] testRetiredFeedMayBeReusedAndDoesNotCountInFreshQuorum() (gas: 3027028)\n[PASS] testUnauthorizedEntryPointsAndGuardianBoundaries() (gas: 1519030)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 18.65ms (10.61ms CPU time)\n\nRan 3 tests for test/BaskMath.t.sol:BaskMathTest\n[PASS] testFullWidthRedemptionMathAndRounding() (gas: 4635)\n[PASS] testFuzzExactCancellation(uint256,uint256) (runs: 256, μ: 3625, ~: 3534)\n[PASS] testMathOverflowUsesCustomError() (gas: 10574)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 20.55ms (20.53ms CPU time)\n\nRan 18 tests for test/BaskVault.t.sol:BaskVaultTest\n[PASS] testAllPriceFailuresAndStatusParity() (gas: 2717865)\n[PASS] testBucketGlobalAndDecay() (gas: 1576380)\n[PASS] testDeploymentAndConstructorValidation() (gas: 71153)\n[PASS] testFeeRecipientCanRedeemOwnShares() (gas: 614341)\n[PASS] testFeeRecipientNeverCalledAndFeesAreFinal() (gas: 798881)\n[PASS] testFirstDepositAndDonationIgnored() (gas: 1126067)\n[PASS] testFuzzDepositRedeemConservation(uint96,bool) (runs: 256, μ: 677235, ~: 677127)\nLogs:\n  Bound result 429279558816266\n\n[PASS] testInclusiveBandAnd26HourPriceWithThreeOtherFreshFeeds() (gas: 3301923)\n[PASS] testManagedClosedAssetStillRequiresPriceAndEmptyAssetDoesNot() (gas: 1434338)\n[PASS] testMarketBoundariesAndFreshGate() (gas: 1614882)\n[PASS] testMinimumSharesDeadlineAndRecipient() (gas: 568441)\n[PASS] testNavCapAndValueBasedBucketLimit() (gas: 2572754)\n[PASS] testRedeemSlippageAndDeadlineAreAtomic() (gas: 770671)\n[PASS] testRejectsInexactAndFalseDepositTransfers() (gas: 1722788)\n[PASS] testRoundingUpFeesForSmallSubsequentDepositsAndRedemptions() (gas: 963196)\n[PASS] testRuntimeHasNoForbiddenOpcodes() (gas: 6486872)\n[PASS] testShareTransfersAndAllowance() (gas: 788939)\n[PASS] testUnsetRedeemFeeBurnsAllShares() (gas: 581154)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 21.32ms (48.06ms CPU time)\n\nRan 12 tests for test/BaskLosses.t.sol:BaskLossesTest\n[PASS] testClaimFailureRollsBackAndOnlyCallerCanClaim() (gas: 920745)\n[PASS] testDeferredClaimReservesBeforeOtherRedemptions() (gas: 1220060)\n[PASS] testDeficitBlocksDepositsButDoesNotAutomaticallyLowerManaged() (gas: 1348663)\n[PASS] testFuzzFailedLegConservation(uint96) (runs: 256, μ: 801290, ~: 801339)\nLogs:\n  Bound result 999999900000008252063\n\n[PASS] testLargerDeficitRestartsClockSmallerDoesNot() (gas: 870686)\n[PASS] testNonzeroSupplyWithZeroNAVRejectsDepositsButRedeems() (gas: 3393628)\n[PASS] testPartialClaimAndOwedUnderfundingCannotBlockRedeem() (gas: 1153837)\n[PASS] testRecognitionCannotExceedRecordedLoss() (gas: 738310)\n[PASS] testRecoveredDeficitClearedByDepositOrRecognition() (gas: 1130591)\n[PASS] testRedemptionOnDeficitUsesAvailableAndLeavesRemainingLoss() (gas: 724724)\n[PASS] testRetiredAssetsZeroNAVSkipChecksAndStillRedeemAndClaim() (gas: 4473897)\n[PASS] testUnreadableBalanceNeverAuthorizesLoss() (gas: 803295)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 25.47ms (33.00ms CPU time)\n\nRan 4 tests for test/BaskAdversarial.t.sol:Bask64AssetsTest\n[PASS] test64MixedPausedBlockedMalformedRetiredAndWorkingTokens() (gas: 24982544)\nLogs:\n  64-asset redemption gas (including call and result copy): 7991439\n\n[PASS] test64TransfersConsumeEntirePayoutGas() (gas: 37306036)\nLogs:\n  64-asset redemption gas (including call and result copy): 22674427\n\n[PASS] test64UpgradedUnreadableTokensDoNotBlockExit() (gas: 11661930)\nLogs:\n  64-asset redemption gas (including call and result copy): 10295260\n\n[PASS] testAsset65RejectedEvenAfterRetirement() (gas: 459515)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 103.97ms (28.07ms CPU time)\n\nRan 6 test suites in 104.85ms (194.57ms CPU time): 57 tests passed, 0 failed, 0 skipped (57 total tests)\n","passed":true},{"durationMs":48,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"BaskVault.acceptOwnership()\",\"BaskVault.approve(address,uint256)\",\"BaskVault.cancelProposal(uint256)\",\"BaskVault.claim(address,address)\",\"BaskVault.closeAsset(address)\",\"BaskVault.deposit(address,uint256,address,uint256,uint256)\",\"BaskVault.executeProposal(uint256)\",\"BaskVault.finalizeGenesis()\",\"BaskVault.flagDeficit(address)\",\"BaskVault.lowerNavCap(uint256)\",\"BaskVault.pauseDeposits()\",\"BaskVault.payLeg(address,address,uint256)\",\"BaskVault.proposeAsset(address,address)\",\"BaskVault.proposeAssets(address[],address[])\",\"BaskVault.proposeBand(address)\",\"BaskVault.proposeFeed(address,address)\",\"BaskVault.proposeGuardian(address)\",\"BaskVault.proposeNavCap(uint256)\",\"BaskVault.proposeReopen(address)\",\"BaskVault.proposeRetire(address)\",\"BaskVault.recognizeLoss(address)\",\"BaskVault.redeem(uint256,uint256[],uint256)\",\"BaskVault.setFeeRecipient(address)\",\"BaskVault.transfer(address,uint256)\",\"BaskVault.transferFrom(address,address,uint256)\",\"BaskVault.transferOwnership(address)\",\"BaskVault.unpauseDeposits()\"],\"files\":{\".gitignore\":3,\"README.md\":255,\"foundry.toml\":16,\"launch.json\":13,\"remappings.txt\":1,\"src/BaskMath.sol\":46,\"src/BaskVault.sol\":859,\"test/BaskAdversarial.t.sol\":228,\"test/BaskBase.t.sol\":98,\"test/BaskGovernance.t.sol\":379,\"test/BaskLosses.t.sol\":242,\"test/BaskMath.t.sol\":31,\"test/BaskVault.t.sol\":310,\"test/mocks/StockMocks.sol\":218},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":3012,"exitCode":0,"name":"slither","output":"[high/medium] weak-prng at src/BaskVault.sol:758: BaskVault._snapshot(address) (src/BaskVault.sol#758-795) uses a weak PRNG: \"day = (block.timestamp / 86400 + 4) % 7 (src/BaskVault.sol#771)\"\n[high/medium] weak-prng at src/BaskVault.sol:758: BaskVault._snapshot(address) (src/BaskVault.sol#758-795) uses a weak PRNG: \"secondsToday = block.timestamp % 86400 (src/BaskVault.sol#772)\"\n[high/medium] incorrect-exp at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) has bitwise-xor operator ^ instead of the exponentiation operator **: \n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/BaskMath.sol:9: BaskMath.mulDiv(uint256,uint256,uint256) (src/BaskMath.sol#9-45) performs a multiplication on the result of a division:\n[medium/high] incorrect-equality at src/BaskVault.sol:758: BaskVault._snapshot(address) (src/BaskVault.sol#758-795) uses a dangerous strict equality:\n[medium/medium] uninitialized-local at src/BaskVault.sol:776: BaskVault._snapshot(address).fresh (src/BaskVault.sol#776) is a local variable never initialized\n[low/medium] timestamp at src/BaskVault.sol:797: BaskVault._priceStatus(BaskVault.Asset,bool,int256,uint256) (src/BaskVault.sol#797-811) uses timestamp for comparisons\n[low/medium] timestamp at src/BaskVault.sol:384: BaskVault.executeProposal(uint256) (src/BaskVault.sol#384-425) uses timestamp for comparisons\n[low/medium] timestamp at src/BaskVault.sol:427: BaskVault.proposalState(uint256) (src/BaskVault.sol#427-441) uses timestamp for comparisons\n[low/medium] timestamp at src/BaskVault.sol:758: BaskVault._snapshot(address) (src/BaskVault.sol#758-795) uses timestamp for comparisons\n[low/medium] timestamp at src/BaskVault.sol:675: BaskVault.recognizeLoss(address) (src/BaskVault.sol#675-684) uses timestamp for comparisons\n[low/medium] timestamp at src/BaskVault.sol:523: BaskVault.deposit(address,uint256,address,uint256,uint256) (src/BaskVault.sol#523-568) uses timestamp for comparisons\n[low/medium] timestamp at src/BaskVault.sol:592: BaskVault.redeem(uint256,uint256[],uint256) (src/BaskVault.sol#592-622) uses timestamp for comparisons\n[low/medium] timestamp at src/BaskVault.sol:586: BaskVault.decayedBucket() (src/BaskVault.sol#586-590) uses timestamp for comparisons","passed":true},{"durationMs":234,"exitCode":0,"name":"aderyn","output":"[high] incorrect-caret-operator at src/BaskMath.sol:36: Incorrect use of caret operator\n[high] weak-randomness at src/BaskVault.sol:772: Weak Randomness\n[low] centralization-risk at src/BaskVault.sol:256: Centralization Risk (13 places)\n[low] costly-loop at src/BaskVault.sol:321: Costly operations inside loop (3 places)\n[low] large-numeric-literal at src/BaskVault.sol:807: Large Numeric Literal (2 places)\n[low] literal-instead-of-constant at src/BaskVault.sol:303: Literal Instead of Constant (17 places)\n[low] local-variable-shadowing at src/BaskVault.sol:94: Local Variable Shadows State Variable (2 places)\n[low] require-revert-in-loop at src/BaskVault.sol:321: Loop Contains `require`/`revert` (5 places)\n[low] storage-array-length-not-cached at src/BaskVault.sol:496: Storage Array Length not Cached (6 places)\n[low] unchecked-return at src/BaskVault.sol:342: Unchecked Return (5 places)\n[low] uninitialized-local-variable at src/BaskVault.sol:451: Uninitialized Local Variable (5 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"94786519427eb45010402184c91c1013a22c82cf55375623c14ef322a819c58b","verifiedTreeHash":"42b2c74ec6bce1eeffd90ffe54d8120e31ef5589","verifierVersion":"0.1.0+be003835"},{"checks":[{"durationMs":21981,"exitCode":0,"name":"build","output":"Compiling 28 files with Solc 0.8.26\nSolc 0.8.26 finished in 21.62s\nCompiler run successful!\nwarning[boolean-cst]: misuse of a boolean constant\n    ╭▸ src/BaskVault.sol:815:32\n    │\n815 │         if (!readable) return (false, managed[token]);\n    │                                ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[boolean-cst]: misuse of a boolean constant\n    ╭▸ src/BaskVault.sol:851:26\n    │\n851 │         if (!ok) return (false, 0, 0);\n    │                          ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[weak-prng]: weak randomness derived from a predictable on-chain value\n    ╭▸ src/BaskVault.sol:771:23\n    │\n771 │         uint256 day = (block.timestamp / 1 days + 4) % 7;\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/weak-prng\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:520:9\n    │\n520 │         emit AssetListed(token, feed, low, high);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:372:9\n    │\n372 │         emit ProposalCreated(id, kind, token, target, value);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:478:44\n    │\n478 │         if (assetIndexPlusOne[token] != 0) revert InvalidAsset(token);\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:479:42\n    │\n479 │         if (assets.length == MAX_ASSETS) revert AssetLimit();\n    │                                          ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:481:32\n    │\n481 │         if (!ok || word != 18) revert InvalidAsset(token);\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:483:18\n    │\n483 │         if (!ok) revert InvalidAsset(token);\n    │                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:486:53\n    │\n486 │         if (!ok || word != uint256(uint160(token))) revert InvalidAsset(token);\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:493:31\n    │\n493 │         if (!ok || word != 8) revert InvalidFeed(feed);\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:495:59\n    │\n495 │         if (!ok || word == 0 || word > type(uint160).max) revert InvalidFeed(feed);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:498:67\n    │\n498 │             if (!a.retired && a.token != token && a.feed == feed) revert InvalidFeed(feed);\n    │                                                                   ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:502:33\n    │\n502 │         if (!ok || answer <= 0) revert InvalidFeed(feed);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:512:45\n    │\n512 │         if (answer > type(uint256).max / 4) revert InvalidAmount();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:389:17\n    │\n389 │             if (block.timestamp < nextAssetChangeAt) revert ChangeTooSoon();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:402:39\n    │\n402 │             if (!ok || answer <= 0 || updated > block.timestamp || block.timestamp - updated >= PRICE_AGE) {\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:402:68\n    │\n402 │             if (!ok || answer <= 0 || updated > block.timestamp || block.timestamp - updated >= PRICE_AGE) {\n    │                                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:398:13\n    │\n398 │             emit FeedChanged(p.token, p.target);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:406:13\n    │\n406 │             emit BandChanged(p.token, a.minAnswer, a.maxAnswer);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:424:9\n    │\n424 │         emit ProposalExecuted(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:405:48\n    │\n405 │             (a.minAnswer, a.maxAnswer) = _band(uint256(answer));\n    │                                                ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:436:13\n    │\n436 │         if (block.timestamp < p.createdAt + PROPOSAL_DELAY) return ProposalState.Waiting;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:437:13\n    │\n437 │         if (block.timestamp >= p.createdAt + PROPOSAL_DELAY + PROPOSAL_LIFETIME) {\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/BaskVault.sol:453:85\n    │\n453 │             if (state == ProposalState.Waiting || state == ProposalState.Ready) ids[n++] = start + i;\n    │                                                                                     ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:503:16\n    │\n503 │         return uint256(answer);\n    │                ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:528:13\n    │\n528 │         if (block.timestamp > deadline) revert DeadlineExpired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:561:17\n    │\n561 │                 emit DeficitCleared(t);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:246:9\n    │\n246 │         emit Transfer(address(0), to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:567:9\n    │\n567 │         emit Deposit(msg.sender, receiver, token, amount, shares, fee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:588:13\n    │\n588 │         if (elapsed >= 1 days) return 0;\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:597:13\n    │\n597 │         if (block.timestamp > deadline) revert DeadlineExpired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:618:17\n    │\n618 │                 emit LegOwed(msg.sender, token, leg);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:621:9\n    │\n621 │         emit Redeem(msg.sender, shares, fee);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/BaskMath.sol:19:29\n   │\n19 │                 if (d == 0) revert MathOverflow();\n   │                             ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/BaskMath.sol:22:28\n   │\n22 │             if (d <= high) revert MathOverflow();\n   │                            ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/BaskVault.sol:612:69\n    │\n612 │             if (i < minAmountsOut.length && leg < minAmountsOut[i]) revert Slippage();\n    │                                                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:649:9\n    │\n649 │         emit LegPaid(token, to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `entered` is updated\n    ╭▸ src/BaskVault.sol:660:26\n    │\n660 │         if (amount != 0) this.payLeg(token, to, amount);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:661:9\n    │\n661 │         emit Claimed(msg.sender, token, to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:672:9\n    │\n672 │         emit DeficitFlagged(token, loss.amount, loss.since);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:678:33\n    │\n678 │         if (loss.amount == 0 || block.timestamp < loss.since + 7 days) revert InvalidState();\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/BaskVault.sol:683:9\n    │\n683 │         emit LossRecognized(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/BaskVault.sol:781:95\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                                                                                               ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:760:13\n    │\n760 │         if (block.timestamp < depositsOpenAt) return _fail(s, Reason.WarmingUp, address(0));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:13\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │             ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:25\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:37\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                                     ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:773:61\n    │\n773 │         if (day == 0 || day == 6 || secondsToday < 55800 || secondsToday >= 70200) {\n    │                                                             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:781:25\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:781:55\n    │\n781 │             if (read && updated <= block.timestamp && block.timestamp - updated <= 4 hours) ++fresh;\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:786:49\n    │\n786 │                 if (a.token == token) s.price = uint256(answer);\n    │                                                 ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:787:60\n    │\n787 │                 s.nav += BaskMath.mulDiv(managed[a.token], uint256(answer), 1e8);\n    │                                                            ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:805:13\n    │\n805 │         if (updated > block.timestamp) return Reason.FuturePrice;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/BaskVault.sol:806:13\n    │\n806 │         if (block.timestamp - updated > PRICE_AGE) return Reason.StalePrice;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:804:13\n    │\n804 │         if (uint256(answer) < a.minAnswer || uint256(answer) > a.maxAnswer) return Reason.OutsideBand;\n    │             ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/BaskVault.sol:804:46\n    │\n804 │         if (uint256(answer) < a.minAnswer || uint256(answer) > a.maxAnswer) return Reason.OutsideBand;\n    │                                              ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\n","passed":true},{"durationMs":167,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 3 tests for test/BaskMath.t.sol:BaskMathTest\n[PASS] testFullWidthRedemptionMathAndRounding() (gas: 4635)\n[PASS] testFuzzExactCancellation(uint256,uint256) (runs: 256, μ: 3622, ~: 3534)\n[PASS] testMathOverflowUsesCustomError() (gas: 10574)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 3.34ms (3.08ms CPU time)\n\nRan 8 tests for test/BaskAdversarial.t.sol:BaskAdversarialTest\n[PASS] testAllFailedTransfersAtomicIncludingReturnBombs() (gas: 3629254)\n[PASS] testAllUnreadableBalanceOutcomesDeferWithoutRevert() (gas: 2491506)\n[PASS] testBalanceReadExceedingPayoutBudgetDefersThenClaims() (gas: 1896478)\n[PASS] testClaimExpensiveBalanceReadsAndRedeemWithinPayoutBudget() (gas: 1545575)\n[PASS] testDepositRedeemClaimAndAdminCallbacksBlocked() (gas: 7376155)\n[PASS] testExpensiveClaimBalanceReadsStillEnforceExactDebit() (gas: 1066523)\n[PASS] testNoReturnTransferAndSenderDebitSemantics() (gas: 807523)\n[PASS] testRolesCannotBlockRedeemOrClaim() (gas: 1347760)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 6.35ms (17.22ms CPU time)\n\nRan 15 tests for test/BaskGovernance.t.sol:BaskGovernanceTest\n[PASS] testBandUsesExecutionAnswerAndStrictAge() (gas: 608145)\n[PASS] testCapRaisesDelayedLowerCancelsAllRaisesAndHasNoFloor() (gas: 618832)\n[PASS] testExpiredCancelledAndPendingEnumeration() (gas: 488016)\n[PASS] testFeedReplacementChecksBothTimesAndPreservesBand() (gas: 1351745)\n[PASS] testGenesisBatchAtomicAndFinalizedOnce() (gas: 1255134)\n[PASS] testGuardianCannotCancelItsReplacementAndOwnershipSeparation() (gas: 550785)\n[PASS] testGuardianRecheckedAgainstCurrentOwner() (gas: 368730)\n[PASS] testListingAndFeedShareDailyRateLimit() (gas: 3114816)\n[PASS] testListingChecksAtProposalAndExecution() (gas: 3652648)\n[PASS] testListingFeedCannotBeTakenByAnotherProposal() (gas: 2329237)\n[PASS] testProposalTimingJustBeforeAndAtBoundaries() (gas: 511432)\n[PASS] testReopenVoidedEvenByRepeatedClose() (gas: 658714)\n[PASS] testRetireClosedBothTimesVoidsAllProposals() (gas: 1620017)\n[PASS] testRetiredFeedMayBeReusedAndDoesNotCountInFreshQuorum() (gas: 3081717)\n[PASS] testUnauthorizedEntryPointsAndGuardianBoundaries() (gas: 1525518)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 20.67ms (10.68ms CPU time)\n\nRan 18 tests for test/BaskVault.t.sol:BaskVaultTest\n[PASS] testAllPriceFailuresAndStatusParity() (gas: 2773037)\n[PASS] testBucketGlobalAndDecay() (gas: 1602698)\n[PASS] testDeploymentAndConstructorValidation() (gas: 71153)\n[PASS] testFeeRecipientCanRedeemOwnShares() (gas: 627661)\n[PASS] testFeeRecipientNeverCalledAndFeesAreFinal() (gas: 812201)\n[PASS] testFirstDepositAndDonationIgnored() (gas: 1158851)\n[PASS] testFuzzDepositRedeemConservation(uint96,bool) (runs: 256, μ: 687444, ~: 657455)\nLogs:\n  Bound result 610275874373965069556\n\n[PASS] testInclusiveBandAnd26HourPriceWithThreeOtherFreshFeeds() (gas: 3371589)\n[PASS] testManagedClosedAssetStillRequiresPriceAndEmptyAssetDoesNot() (gas: 1464822)\n[PASS] testMarketBoundariesAndFreshGate() (gas: 1664298)\n[PASS] testMinimumSharesDeadlineAndRecipient() (gas: 581417)\n[PASS] testNavCapAndValueBasedBucketLimit() (gas: 2625490)\n[PASS] testRedeemSlippageAndDeadlineAreAtomic() (gas: 788579)\n[PASS] testRejectsInexactAndFalseDepositTransfers() (gas: 1762336)\n[PASS] testRoundingUpFeesForSmallSubsequentDepositsAndRedemptions() (gas: 982904)\n[PASS] testRuntimeHasNoForbiddenOpcodes() (gas: 6508877)\n[PASS] testShareTransfersAndAllowance() (gas: 795549)\n[PASS] testUnsetRedeemFeeBurnsAllShares() (gas: 594474)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 21.48ms (47.32ms CPU time)\n\nRan 12 tests for test/BaskLosses.t.sol:BaskLossesTest\n[PASS] testClaimFailureRollsBackAndOnlyCallerCanClaim() (gas: 940191)\n[PASS] testDeferredClaimReservesBeforeOtherRedemptions() (gas: 1248541)\n[PASS] testDeficitBlocksDepositsButDoesNotAutomaticallyLowerManaged() (gas: 1374191)\n[PASS] testFuzzFailedLegConservation(uint96) (runs: 256, μ: 816449, ~: 816500)\nLogs:\n  Bound result 9855323578165346\n\n[PASS] testLargerDeficitRestartsClockSmallerDoesNot() (gas: 884511)\n[PASS] testNonzeroSupplyWithZeroNAVRejectsDepositsButRedeems() (gas: 3461516)\n[PASS] testPartialClaimAndOwedUnderfundingCannotBlockRedeem() (gas: 1182086)\n[PASS] testRecognitionCannotExceedRecordedLoss() (gas: 750861)\n[PASS] testRecoveredDeficitClearedByDepositOrRecognition() (gas: 1149753)\n[PASS] testRedemptionOnDeficitUsesAvailableAndLeavesRemainingLoss() (gas: 740166)\n[PASS] testRetiredAssetsZeroNAVSkipChecksAndStillRedeemAndClaim() (gas: 4745150)\n[PASS] testUnreadableBalanceNeverAuthorizesLoss() (gas: 812071)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 22.59ms (31.20ms CPU time)\n\nRan 4 tests for test/BaskAdversarial.t.sol:Bask64AssetsTest\n[PASS] test64MixedPausedBlockedMalformedRetiredAndWorkingTokens() (gas: 26669912)\nLogs:\n  64-asset redemption gas (including call and result copy): 9677575\n\n[PASS] test64TransfersConsumeEntirePayoutGas() (gas: 37431604)\nLogs:\n  64-asset redemption gas (including call and result copy): 22795771\n\n[PASS] test64UpgradedUnreadableTokensDoNotBlockExit() (gas: 24112106)\nLogs:\n  64-asset redemption gas (including call and result copy): 22745436\n\n[PASS] testAsset65RejectedEvenAfterRetirement() (gas: 459515)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 91.06ms (31.62ms CPU time)\n\nRan 6 test suites in 91.79ms (165.50ms CPU time): 60 tests passed, 0 failed, 0 skipped (60 total tests)\n","passed":true},{"durationMs":45,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"BaskVault.acceptOwnership()\",\"BaskVault.approve(address,uint256)\",\"BaskVault.cancelProposal(uint256)\",\"BaskVault.claim(address,address)\",\"BaskVault.closeAsset(address)\",\"BaskVault.deposit(address,uint256,address,uint256,uint256)\",\"BaskVault.executeProposal(uint256)\",\"BaskVault.finalizeGenesis()\",\"BaskVault.flagDeficit(address)\",\"BaskVault.lowerNavCap(uint256)\",\"BaskVault.pauseDeposits()\",\"BaskVault.payLeg(address,address,uint256)\",\"BaskVault.proposeAsset(address,address)\",\"BaskVault.proposeAssets(address[],address[])\",\"BaskVault.proposeBand(address)\",\"BaskVault.proposeFeed(address,address)\",\"BaskVault.proposeGuardian(address)\",\"BaskVault.proposeNavCap(uint256)\",\"BaskVault.proposeReopen(address)\",\"BaskVault.proposeRetire(address)\",\"BaskVault.recognizeLoss(address)\",\"BaskVault.redeem(uint256,uint256[],uint256)\",\"BaskVault.setFeeRecipient(address)\",\"BaskVault.transfer(address,uint256)\",\"BaskVault.transferFrom(address,address,uint256)\",\"BaskVault.transferOwnership(address)\",\"BaskVault.unpauseDeposits()\"],\"files\":{\".gitignore\":3,\"README.md\":308,\"foundry.toml\":16,\"launch.json\":13,\"remappings.txt\":1,\"src/BaskMath.sol\":46,\"src/BaskVault.sol\":864,\"test/BaskAdversarial.t.sol\":283,\"test/BaskBase.t.sol\":98,\"test/BaskGovernance.t.sol\":379,\"test/BaskLosses.t.sol\":242,\"test/BaskMath.t.sol\":31,\"test/BaskVault.t.sol\":310,\"test/mocks/StockMocks.sol\":230},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"c000c4a4cae6aa3eae572a9c17e26903c9a0528f7d11b27a3546352433cd40d5","verifiedTreeHash":"1f02d71317d4760052a6f0195579e0c02072b8cc","verifierVersion":"0.1.0+a2d9a899"}]}