Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions contracts/src/access/AccessControl.compact
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,29 @@ pragma language_version >= 0.21.0;
* @notice The unsafe circuits are planned to become deprecated once contract-to-contract calls
* are supported.
*
* @dev Migration plan (safe -> C2C-capable role grants)
*
* The account type is the final `Either<Bytes<32>, ContractAddress>` from day one, in both circuit
* signatures and the roles ledger map. This is deliberate. Midnight's upgrade mechanism, the
* Contract Maintenance Authority (CMA), can rotate a circuit's verifier key but cannot migrate
* ledger state (there is no state-rewrite primitive; see the `updatability` tutorial). Fixing the
* type now makes the future migration a pure verifier-key rotation with zero ledger-state change,
* which is the only kind of upgrade the CMA supports. Widening the type later would instead force
* a ledger-layout rewrite, which the CMA cannot perform.
*
* When C2C lands, an already-deployed contract migrates without changing its address or ledger
* state:
*
* - Minor release: mark `_unsafeGrantRole` deprecated (and emit a warning if possible); keep its
* implementation intact so existing callers continue to work.
* - Major release: ship `grantRole` / `_grantRole` with the `isContract` guard removed and drop
* `_unsafeGrantRole`. Operators adopt the new logic by signing a CMA `MaintenanceUpdate` that
* rotates the affected verifier keys (`VerifierKeyRemove` + `VerifierKeyInsert` for each guarded
* circuit, and a `VerifierKeyRemove` for `_unsafeGrantRole`). The contract address and all ledger
* state are preserved. Because the CMA allows multiple active VK versions per operation, old and
* new keys can coexist during a transition window so in-flight proofs still verify. By this
* point, anyone using `_unsafeGrantRole` should have migrated to the now C2C-capable circuits.
*
* @dev Security Considerations:
* - The `secretKey` must be kept private. Loss of the key prevents role holders
* from proving access. Key exposure allows impersonation.
Expand Down
25 changes: 25 additions & 0 deletions contracts/src/access/Ownable.compact
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,31 @@ pragma language_version >= 0.21.0;
* @notice The unsafe circuits are planned to become deprecated once contract-to-contract calls
* are supported.
*
* @dev Migration plan (safe -> C2C-capable ownership transfers)
*
* The owner type is the final `Either<Bytes<32>, ContractAddress>` from day one, in both circuit
* signatures and the `_owner` ledger field. This is deliberate. Midnight's upgrade mechanism, the
* Contract Maintenance Authority (CMA), can rotate a circuit's verifier key but cannot migrate
* ledger state (there is no state-rewrite primitive; see the `updatability` tutorial). Fixing the
* type now makes the future migration a pure verifier-key rotation with zero ledger-state change,
* which is the only kind of upgrade the CMA supports. Widening the type later would instead force
* a ledger-layout rewrite, which the CMA cannot perform.
*
* When C2C lands, an already-deployed contract migrates without changing its address or ledger
* state:
*
* - Minor release: mark `_unsafeTransferOwnership` (and `_unsafeUncheckedTransferOwnership`)
* deprecated (and emit a warning if possible); keep their implementation intact so existing
* callers continue to work.
* - Major release: ship `transferOwnership` / `_transferOwnership` with the `isContract` guard
* removed and drop the `_unsafe` variants. Operators adopt the new logic by signing a CMA
* `MaintenanceUpdate` that rotates the affected verifier keys (`VerifierKeyRemove` +
* `VerifierKeyInsert` for each guarded circuit, and a `VerifierKeyRemove` for each `_unsafe`
* variant). The contract address and all ledger state are preserved. Because the CMA allows
* multiple active VK versions per operation, old and new keys can coexist during a transition
* window so in-flight proofs still verify. By this point, anyone using the `_unsafe` variants
* should have migrated to the now C2C-capable circuits.
*
* @dev Canonicalization
* All `Either<Bytes<32>, ContractAddress>` values are canonicalized before being written
* to the `_owner` ledger field. Canonicalization zeroes out the inactive branch of the Either,
Expand Down
36 changes: 25 additions & 11 deletions contracts/src/token/FungibleToken.compact
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,36 @@ pragma language_version >= 0.21.0;
* canonicalized in `balanceOf` and `allowance`. `_spendAllowance` canonicalizes
* independently to ensure consistent lookups before delegating to `_approve`.
*
* @notice At the moment Midnight does not support contract-to-contract communication, but
* @notice At the moment Midnight does not support contract-to-contract (C2C) communication, but
* there are ongoing efforts to enable this in the future. Thus, the main circuits of this module
* restrict developers from sending tokens to contracts; however, we provide developers
* the ability to experiment with sending tokens to contracts using the `_unsafe`
* transfer methods. Once contract-to-contract communication is available we will follow the
* deprecation plan outlined below:
* (`transfer`, `transferFrom`, `_transfer`, `_mint`) reject `ContractAddress` recipients via an
* `isContract` guard, because a contract that receives tokens currently cannot move them back out.
* Developers who need to experiment with contract recipients can use the `_unsafe` variants, which
* skip the guard (the caller accepts that such tokens are stranded until C2C lands).
*
* Initial Minor Version Change:
* @dev Migration plan (safe -> C2C-capable transfers)
*
* - Mark _unsafeFN as deprecated and emit a warning if possible.
* - Keep its implementation intact so existing callers continue to work.
* The recipient type is the final `Either<Bytes<32>, ContractAddress>` from day one, in both
* circuit signatures and ledger maps. This is deliberate. Midnight's upgrade mechanism, the
* Contract Maintenance Authority (CMA), can rotate a circuit's verifier key but cannot migrate
* ledger state (there is no state-rewrite primitive; see the `updatability` tutorial). Fixing the
* types now makes the future migration a pure verifier-key rotation with zero ledger-state change,
* which is the only kind of upgrade the CMA supports. Widening the types later would instead force
* a ledger-layout rewrite, which the CMA cannot perform.
*
* Later Major Version Change:
* When C2C lands, an already-deployed token migrates without changing its address or ledger state.
* Below, `FN` stands for each guarded circuit (`transfer`, `transferFrom`, `_transfer`, `_mint`)
* and `_unsafeFN` for its unsafe counterpart:
*
* - Drop _unsafeFN and remove `isContract` guard from `FN`.
* - By this point, anyone using _unsafeFN should have migrated to the now C2C-capable `FN`.
* - Minor release: mark `_unsafeFN` deprecated (and emit a warning if possible); keep its
* implementation intact so existing callers continue to work.
* - Major release: ship `FN` with the `isContract` guard removed and drop `_unsafeFN`. Operators
* adopt the new logic by signing a CMA `MaintenanceUpdate` that rotates the affected verifier
* keys (`VerifierKeyRemove` + `VerifierKeyInsert` for each `FN`, and a `VerifierKeyRemove` for
* each `_unsafeFN`). The contract address and all ledger state are preserved. Because the CMA
* allows multiple active VK versions per operation, old and new `FN` keys can coexist during a
* transition window so in-flight proofs still verify. By this point, anyone using `_unsafeFN`
* should have migrated to the now C2C-capable `FN`.
*
* Due to the vast incompatibilities with the EIP20 spec, it is our
* opinion that this implementation should not be called ERC20 at this time
Expand Down
29 changes: 29 additions & 0 deletions contracts/src/token/MultiToken.compact
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,35 @@ pragma language_version >= 0.21.0;
* Any DApp may provide any implementation. The ZK proof system constrains what values
* can produce valid proofs.
*
* @dev Migration plan (safe -> C2C-capable transfers)
*
* The main circuits (`transferFrom`, `_transfer`, `_mint`) reject `ContractAddress` recipients via
* an `isContract` guard, because a contract that receives tokens currently cannot move them back
* out. The `_unsafe` variants (`_unsafeTransferFrom`, `_unsafeTransfer`, `_unsafeMint`) skip the
* guard for callers who need contract recipients (accepting that such tokens are stranded until
* C2C lands).
*
* The recipient type is the final `Either<Bytes<32>, ContractAddress>` from day one, in both
* circuit signatures and ledger maps. This is deliberate. Midnight's upgrade mechanism, the
* Contract Maintenance Authority (CMA), can rotate a circuit's verifier key but cannot migrate
* ledger state (there is no state-rewrite primitive; see the `updatability` tutorial). Fixing the
* types now makes the future migration a pure verifier-key rotation with zero ledger-state change,
* which is the only kind of upgrade the CMA supports. Widening the types later would instead force
* a ledger-layout rewrite, which the CMA cannot perform.
*
* When C2C lands, an already-deployed token migrates without changing its address or ledger state:
*
* - Minor release: mark the `_unsafe` variants deprecated (and emit a warning if possible); keep
* their implementation intact so existing callers continue to work.
* - Major release: ship the main circuits with the `isContract` guard removed and drop the
* `_unsafe` variants. Operators adopt the new logic by signing a CMA `MaintenanceUpdate` that
* rotates the affected verifier keys (`VerifierKeyRemove` + `VerifierKeyInsert` for each guarded
* circuit, and a `VerifierKeyRemove` for each `_unsafe` variant). The contract address and all
* ledger state are preserved. Because the CMA allows multiple active VK versions per operation,
* old and new keys can coexist during a transition window so in-flight proofs still verify. By
* this point, anyone using the `_unsafe` variants should have migrated to the now C2C-capable
* circuits.
*
* @notice Further discussion and consideration required:
*
* - Consider changing the underscore in the internal methods to `unsafe` or
Expand Down
34 changes: 23 additions & 11 deletions contracts/src/token/NonFungibleToken.compact
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,34 @@ pragma language_version >= 0.21.0;
* This is due to encoding limits on the midnight circuit backend:
* https://github.com/midnightntwrk/compactc/issues/929
*
* @notice At the moment Midnight does not support contract-to-contract communication, but
* @notice At the moment Midnight does not support contract-to-contract (C2C) communication, but
* there are ongoing efforts to enable this in the future. Thus, the main circuits of this module
* restrict developers from sending tokens to contracts; however, we provide developers
* the ability to experiment with sending tokens to contracts using the `_unsafe`
* transfer methods. Once contract-to-contract communication is available we will follow the
* deprecation plan outlined below:
* (`transfer`, `transferFrom`, `_transfer`, `_mint`) reject `ContractAddress` recipients via an
* `isContract` guard, because a contract that receives a token currently cannot move it back out.
* Developers who need to experiment with contract recipients can use the `_unsafe` variants, which
* skip the guard (the caller accepts that such tokens are stranded until C2C lands).
*
* Initial Minor Version Change:
* @dev Migration plan (safe -> C2C-capable `transfer`)
*
* - Mark _unsafeTransfer as deprecated and emit a warning if possible.
* - Keep its implementation intact so existing callers continue to work.
* The recipient type is the final `Either<Bytes<32>, ContractAddress>` from day one, in both
* circuit signatures and ledger maps. This is deliberate. Midnight's upgrade mechanism, the
* Contract Maintenance Authority (CMA), can rotate a circuit's verifier key but cannot migrate
* ledger state (there is no state-rewrite primitive; see the `updatability` tutorial). Fixing the
* types now makes the future migration a pure verifier-key rotation with zero ledger-state change,
* which is the only kind of upgrade the CMA supports. Widening the types later would instead force
* a ledger-layout rewrite, which the CMA cannot perform.
*
* Later Major Version Change:
* When C2C lands, an already-deployed token migrates without changing its address or ledger state:
*
* - Drop _unsafeTransfer and remove `isContract` guard from `transfer`.
* - By this point, anyone using _unsafeTransfer should have migrated to the now C2C-capable `transfer`.
* - Minor release: mark `_unsafeTransfer` deprecated (and emit a warning if possible); keep its
* implementation intact so existing callers continue to work.
* - Major release: ship `transfer` with the `isContract` guard removed and drop `_unsafeTransfer`.
* Operators adopt the new logic by signing a CMA `MaintenanceUpdate` that rotates the affected
* verifier keys (`VerifierKeyRemove` + `VerifierKeyInsert` for `transfer`, and a `VerifierKeyRemove`
* for `_unsafeTransfer`). The contract address and all ledger state are preserved. Because the CMA
* allows multiple active VK versions per operation, the old and new `transfer` keys can coexist
* during a transition window so in-flight proofs still verify. By this point, anyone using
* `_unsafeTransfer` should have migrated to the now C2C-capable `transfer`.
*
* @dev Canonicalization
* All `Either<Bytes<32>, ContractAddress>` values are canonicalized before use as map keys
Expand Down
Loading