Upgradeable contract
upgradeable compiles the contract as a UUPS implementation for an ERC-1967 proxy. deploy initializes the proxy as it is created. The upgrade guard authorizes upgradeToAndCall, and a migrate runs once, inside the upgrade that installs this version.
upgradeable.lithe
(* `upgradeable` compiles to a UUPS implementation (ERC-1967). `deploy` is the proxy's
initializer: the proxy's constructor calls it. The upgrade guard authorizes
`upgradeToAndCall`; a `migrate` runs once, inside the upgrade that installs this
version, and is never callable on its own. *)
import "std/evm";
upgradeable
error NotOwner;
storage is record {
owner : address;
}
storage settings at "vault.settings" is record {
fee : uint;
treasury : address;
}
upgrade guard is {
assert(Evm.sender() = storage.owner, NotOwner);
}
migrate initSettings(const fee : uint; const treasury : address) is {
settings.fee := fee;
settings.treasury := treasury;
}
deploy(const owner : address) is {
storage.owner := owner;
}
external view function fee() : uint is
settings.feeDeploy the implementation, then a proxy whose constructor calls deploy:
new ERC1967Proxy(implementation, abi.encodeCall(Vault.deploy, (owner)));Build the upgrade transaction:
lithe upgrade 0xProxy upgradeable.lithe --migrate initSettings --impl 0xNewImpl --args 30 0xTreasuryCheck storage compatibility against the previous version:
lithe upgrade-check v1.lithe upgradeable.lithe
