BW-185: production DeployAll — yield-strategy gate and a UUPS NFTMetadataGenerator - #103
Conversation
deployYieldStrategies() and deployNFTMetadataGenerator() deploy test mocks and revert when IS_TEST and IS_TESTNET are both false, so DeployAll could not complete a mainnet run. Gate both calls on the mock modes instead: production SubConsols launch without a yield strategy and the LoanManager with a zero metadata generator, matching the live 999 stack.
|
| // Deploy NFTMetadataGenerator (mock; production LoanManager launches with none) | ||
| if (isTest || isTestnet) { | ||
| deployNFTMetadataGenerator(); | ||
| } |
There was a problem hiding this comment.
No. Prod should launch with an upgradeable NFTMetadataGenerator.
| // Deploy YieldStrategies (mocks; production SubConsols launch without one) | ||
| if (isTest || isTestnet) { | ||
| deployYieldStrategies(); | ||
| } |
There was a problem hiding this comment.
As long as this is mutable by governance, this is fine.
|
On the two review notes:
|
Renders a MortgagePosition as a data:application/json;base64 URI with the position's fields as ERC-721 attributes. UUPS + AccessControl behind ERC-7201 namespaced storage, with upgrades gated by DEFAULT_ADMIN_ROLE.
DeployAll calls deployNFTMetadataGenerator() unconditionally again: production deploys the implementation, an ERC1967Proxy and the initializer, then hands the admin role to the configured admins. Test and testnet keep the mock. The deploy mode is settable so the production script test can run without writing IS_TEST / IS_TESTNET, which forge shares across parallel suites, and the addresses file is chosen by the test-only suffix so that suite writes its own.
|
Pushed |
SocksNFlops
left a comment
There was a problem hiding this comment.
Please fix the deploy script
| // Deploy NFTMetadataGenerator | ||
| deployNFTMetadataGenerator(); // Disabled for production | ||
| // Deploy NFTMetadataGenerator (the UUPS proxy in production, the settable mock in test/testnet) | ||
| deployNFTMetadataGenerator(); |
There was a problem hiding this comment.
It's cleaner to just use the UUPS proxy in both
There was a problem hiding this comment.
Done in a9f863a: deployNFTMetadataGenerator() always deploys the implementation + ERC1967 proxy now; the mock branch is gone from the script (the mock stays a test-only fixture), and DeployAll audits the proxy's roles in every mode. 510 tests pass.
Changes
Found by the BW-185 deploy rehearsal on a 4663 fork:
DeployAllcannot complete a production run, becausedeployYieldStrategies()anddeployNFTMetadataGenerator()only knew how to deploy test mocks and reverted whenIS_TESTandIS_TESTNETwere both false. The 999 deploy got past this by hand-commenting the calls, which is why 999'sMortgageNFTpoints at a zero generator andtokenURIreverts there.DeployAll.run(). Production SubConsols launch without a yield strategy; the strategy pointer is admin-settable onSubConsol, so one can be attached later by governance.NFTMetadataGeneratoris now a real contract,src/NFTMetadataGenerator.sol: UUPS +AccessControlUpgradeable, ERC-7201 namespaced storage,DEFAULT_ADMIN_ROLEgates upgrades.generateMetadatais pure and renders the position as adata:application/json;base64,…URI with name, description, and 21 attributes (collateral, term, balances, status).MortgageNFT.nftMetadataGeneratoris immutable, so production deploys the ERC-1967 proxy and hands the NFT the proxy address; the renderer can be upgraded later without a LoanManager migration.DeployNFTMetadataGeneratordeploys implementation + proxy +initialize(deployer)in production, grantsDEFAULT_ADMIN_ROLEto every configured admin, and renounces the deployer's viarenounceUnlessAdmin. Test and testnet keepMockNFTMetadataGenerator.DeployAllcalls it unconditionally and audits the proxy's roles in production.BaseScript.setDeployMode(isTest, isTestnet)lets tests pick a deploy mode without touching process-global env vars;DeployAll.getPath()writes the test addresses file whenever a suffix is set, so a production-mode test run never overwrites a chain file.Testing
forge test: 510 passed, 0 failed, 2 skipped.test/NFTMetadataGenerator.t.sol: 11 tests — initializer locked on the implementation, admin-only upgrade (AccessControlUnauthorizedAccountfor non-admins), storage survives upgrade throughMockNFTMetadataGeneratorUpgraded, metadata prefix/name/description/attribute rendering,tokenURIend-to-end throughMortgageNFT.test/script/DeployAllProduction.t.sol: production-modeDeployAllcompletes, deploys the proxy (not the mock), theMortgageNFTpoints at it, admins holdDEFAULT_ADMIN_ROLEand the deployer does not.forge fmt --checkclean on touched files;lintspec srcclean.DeployAllon Robinhood mainnet (anvil fork at block 64296698) completes with the yield gate: 260 transactions, role audit clean, positional arrays verified, all 12 Chainlink oracles reading live prices. Rehearsal feat(general-manager): adding return token-id to request-creation #2 with the generator proxy is queued after this merges.Reviewers:
@SocksNFlops