Burrowsource, exactly what is deployedall files

test/BurrowValuer.t.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {Test} from "forge-std/Test.sol";
import {BurrowValuer} from "../src/BurrowValuer.sol";

contract MockNFT {
    mapping(uint256 => address) public owners; mapping(uint256 => uint8) public levels;
    function mint(address to, uint256 id, uint8 l) external { owners[id] = to; levels[id] = l; }
    function ownerOf(uint256 id) external view returns (address) { require(owners[id] != address(0), "nope"); return owners[id]; }
    function level(uint256 id) external view returns (uint8) { return levels[id]; }
}
/// Mirrors Sepolia: basePower(level) = 1000 * 2.2^(level-1), zero past the configured top.
contract MockStaking {
    address public immutable collection; uint256 public top = 10; uint256 public huge;
    constructor(address c) { collection = c; }
    function setTop(uint256 t) external { top = t; }
    function setHuge(uint256 h) external { huge = h; }
    function basePower(address c, uint8 l) external view returns (uint256 p) {
        if (c != collection || l == 0 || l > top) return 0;
        if (huge != 0) return huge;
        p = 1000; for (uint256 i = 1; i < l; ++i) p = p * 22 / 10;
    }
}

contract BurrowValuerTest is Test {
    MockNFT nft; MockStaking stk; BurrowValuer valuer;
    function setUp() public {
        nft = new MockNFT(); stk = new MockStaking(address(nft));
        valuer = new BurrowValuer(address(this), address(nft), address(stk), 1e18, 0.5e18, 2e18, 6000);
        nft.mint(address(0xB0B), 1, 1); nft.mint(address(0xB0B), 2, 2); nft.mint(address(0xB0B), 3, 3);
    }
    function test_PowerComesFromStakingNotATable() public view {
        assertEq(valuer.powerForLevel(1), 1000);
        assertEq(valuer.powerForLevel(2), 2200);
        assertEq(valuer.powerForLevel(3), 4840);
        assertEq(valuer.powerForLevel(4), 10648);
    }
    function test_CreditLineSumsPowerThenAppliesLtvOnce() public view {
        uint256[] memory ids = new uint256[](3); ids[0]=1; ids[1]=2; ids[2]=3;
        assertEq(valuer.totalPower(ids), 1000 + 2200 + 4840);
        assertEq(valuer.collateralValue(ids), 8040e18);
        assertEq(valuer.creditLine(ids), 8040e18 * 6000 / 10000);
    }
    function test_EmptyAndUnorderedIds() public {
        uint256[] memory none = new uint256[](0);
        assertEq(valuer.creditLine(none), 0);
        uint256[] memory bad = new uint256[](2); bad[0]=2; bad[1]=1;
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.TokenIdsNotStrictlyAscending.selector, 2, 1));
        valuer.creditLine(bad);
        uint256[] memory many = new uint256[](33);
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.TooManyTokenIds.selector, 33));
        valuer.creditLine(many);
    }
    function test_BurnedOrUnknownTokenIsWorthless() public {
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.InvalidToken.selector, 99));
        valuer.powerOf(99);
    }
    function test_UnpricedLevelFailsClosed() public {
        nft.mint(address(0xB0B), 4, 11);         // chain prices up to level 10 in the mock
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.UnsupportedLevel.selector, 11));
        valuer.powerOf(4);
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.UnsupportedLevel.selector, 0));
        valuer.powerForLevel(0);
        stk.setHuge(1e24 + 1);
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.PowerTooLarge.selector, 1, 1e24 + 1));
        valuer.powerForLevel(1);
    }
    function test_ValuationFollowsChainWhenLevelChanges() public {
        uint256[] memory ids = new uint256[](1); ids[0]=1;
        uint256 before = valuer.creditLine(ids);
        nft.mint(address(0xB0B), 1, 2);          // merged up a level
        assertEq(valuer.creditLine(ids), before * 2200 / 1000);
    }
    function test_ConstructorGuards() public {
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.InvalidCollection.selector, address(0xdead)));
        new BurrowValuer(address(this), address(0xdead), address(stk), 1, 1, 2, 6000);
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.InvalidStaking.selector, address(0xdead)));
        new BurrowValuer(address(this), address(nft), address(0xdead), 1, 1, 2, 6000);
        MockStaking other = new MockStaking(address(0x1234));   // prices a different collection
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.InvalidStaking.selector, address(other)));
        new BurrowValuer(address(this), address(nft), address(other), 1, 1, 2, 6000);
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.InvalidLtvBps.selector, 6001));
        new BurrowValuer(address(this), address(nft), address(stk), 1, 1, 2, 6001);
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.InvalidPriceBand.selector, 0, 2));
        new BurrowValuer(address(this), address(nft), address(stk), 1, 0, 2, 6000);
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.PriceOutsideBand.selector, 3));
        new BurrowValuer(address(this), address(nft), address(stk), 3, 1, 2, 6000);
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.InvalidPriceBand.selector, 1, type(uint256).max));
        new BurrowValuer(address(this), address(nft), address(stk), 1, 1, type(uint256).max, 6000);
    }
    function test_PriceGovernanceTimelockBandAndStep() public {
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.PriceChangeTooLarge.selector, 1e18, 1.3e18));
        valuer.proposePricePerPower(1.3e18);
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.PriceOutsideBand.selector, 0.4e18));
        valuer.proposePricePerPower(0.4e18);
        valuer.proposePricePerPower(1.2e18);
        vm.expectRevert(abi.encodeWithSelector(BurrowValuer.PriceChangeNotReady.selector, block.timestamp + 2 days));
        valuer.executePricePerPower();
        vm.warp(block.timestamp + 2 days);
        valuer.executePricePerPower();
        assertEq(valuer.pricePerPower(), 1.2e18);
        assertEq(valuer.lastPriceChange(), block.timestamp);
        vm.prank(address(0xBAD));
        vm.expectRevert();
        valuer.proposePricePerPower(1.1e18);
    }
    function test_MaxPowerNeverOverflows() public {
        BurrowValuer v = new BurrowValuer(address(this), address(nft), address(stk), 1, 1, type(uint256).max / (1e24 * 32), 6000);
        stk.setHuge(1e24);
        uint256[] memory ids = new uint256[](32); for (uint256 i; i < 32; ++i) { ids[i] = 100 + i; nft.mint(address(1), 100 + i, 1); }
        v.collateralValue(ids);     // must not panic
    }
}