@@ -51,6 +51,10 @@ library LibTransient {
5151    /// `bytes4(keccak256("_LIB_TRANSIENT_COMPAT_SLOT_SEED"))`. 
5252    uint256  private constant  _LIB_TRANSIENT_COMPAT_SLOT_SEED =  0x5a0b45f2 ;
5353
54+     /// @dev The canonical address of the transient registry. 
55+     /// See: https://gist.github.com/Vectorized/4ab665d7a234ef5aaaff2e5091ec261f 
56+     address  internal constant  REGISTRY =  0x000000000000297f64C7F8d9595e43257908F170 ;
57+ 
5458    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ 
5559    /*                     UINT256 OPERATIONS                     */ 
5660    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ 
@@ -690,6 +694,101 @@ library LibTransient {
690694        _compat (ptr)._spacer =  0 ;
691695    }
692696
697+     /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ 
698+     /*               TRANSIENT REGISTRY OPERATIONS                */ 
699+     /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ 
700+ 
701+     /// @dev Sets the value for the key. 
702+     /// If the key does not exist, its admin will be set to the caller. 
703+     /// If the key already exist, its value will be overwritten, 
704+     /// and the caller must be the current admin for the key. 
705+     /// Reverts with empty data if the registry has not been deployed. 
706+     function registrySet  (bytes32  key , bytes  memory  value ) internal  {
707+         /// @solidity memory-safe-assembly 
708+         assembly  {
709+             let  m :=  mload (0x40 )
710+             mstore (m, 0xaac438c0 ) // `set(bytes32,bytes)`. 
711+             mstore (add (m, 0x20 ), key)
712+             mstore (add (m, 0x40 ), 0x40 )
713+             let  n :=  mload (value)
714+             mstore (add (m, 0x60 ), n)
715+             for  { let  i :=  0  } lt (i, n) { i :=  add (i, 0x20 ) } {
716+                 mstore (add (add (m, 0x80 ), i), mload (add (add (value, 0x20 ), i)))
717+             }
718+             if  iszero (
719+                 mul (
720+                     returndatasize (),
721+                     call (gas (), REGISTRY, 0 , add (m, 0x1c ), add (n, 0x64 ), 0x00 , 0x20 )
722+                 )
723+             ) { revert (0x00 , returndatasize ()) }
724+         }
725+     }
726+ 
727+     /// @dev Returns the value for the key. 
728+     /// Reverts if the key does not exist. 
729+     /// Reverts with empty data if the registry has not been deployed. 
730+     function registryGet  (bytes32  key ) internal  view  returns  (bytes  memory  result ) {
731+         /// @solidity memory-safe-assembly 
732+         assembly  {
733+             result :=  mload (0x40 )
734+             mstore (0x00 , 0x8eaa6ac0 ) // `get(bytes32)`. 
735+             mstore (0x20 , key)
736+             if  iszero (mul (returndatasize (), staticcall (gas (), REGISTRY, 0x1c , 0x24 , 0x00 , 0x20 ))) {
737+                 revert (0x00 , returndatasize ())
738+             }
739+             // We can safely assume that the bytes will be containing the 0x20 offset. 
740+             returndatacopy (result, 0x20 , sub (returndatasize (), 0x20 ))
741+             mstore (0x40 , add (result, returndatasize ())) // Allocate memory. 
742+         }
743+     }
744+ 
745+     /// @dev Clears the admin and the value for the key. 
746+     /// The caller must be the current admin of the key. 
747+     /// Reverts with empty data if the registry has not been deployed. 
748+     function registryClear  (bytes32  key ) internal  {
749+         /// @solidity memory-safe-assembly 
750+         assembly  {
751+             mstore (0x00 , 0x97040a45 ) // `clear(bytes32)`. 
752+             mstore (0x20 , key)
753+             if  iszero (mul (returndatasize (), call (gas (), REGISTRY, 0 , 0x1c , 0x24 , 0x00 , 0x20 ))) {
754+                 revert (0x00 , returndatasize ())
755+             }
756+         }
757+     }
758+ 
759+     /// @dev Returns the admin of the key. 
760+     /// Returns `address(0)` if the key does not exist. 
761+     /// Reverts with empty data if the registry has not been deployed. 
762+     function registryAdminOf  (bytes32  key ) internal  view  returns  (address  result ) {
763+         /// @solidity memory-safe-assembly 
764+         assembly  {
765+             mstore (0x00 , 0xc5344411 ) // `adminOf(bytes32)`. 
766+             mstore (0x20 , key)
767+             if  iszero (mul (returndatasize (), staticcall (gas (), REGISTRY, 0x1c , 0x24 , 0x00 , 0x20 ))) {
768+                 revert (0x00 , returndatasize ())
769+             }
770+             result :=  mload (0x00 )
771+         }
772+     }
773+ 
774+     /// @dev Changes the admin of the key. 
775+     /// The caller must be the current admin of the key. 
776+     /// The new admin must not be `address(0)`. 
777+     /// Reverts with empty data if the registry has not been deployed. 
778+     function registryChangeAdmin  (bytes32  key , address  newAdmin ) internal  {
779+         /// @solidity memory-safe-assembly 
780+         assembly  {
781+             let  m :=  mload (0x40 ) // Cache the free memory pointer. 
782+             mstore (0x00 , 0x053b1ca3 ) // `changeAdmin(bytes32,address)`. 
783+             mstore (0x20 , key)
784+             mstore (0x40 , shr (96 , shl (96 , newAdmin)))
785+             if  iszero (mul (returndatasize (), call (gas (), REGISTRY, 0 , 0x1c , 0x44 , 0x00 , 0x20 ))) {
786+                 revert (0x00 , returndatasize ())
787+             }
788+             mstore (0x40 , m) // Restore the free memory pointer. 
789+         }
790+     }
791+ 
693792    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ 
694793    /*                      PRIVATE HELPERS                       */ 
695794    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ 
0 commit comments