@@ -5,11 +5,11 @@ import {
55} from "./network.config" ;
66import { TypedDataDomain , AbiCoder , toNumber , dataSlice , getAddress , parseEther } from "ethers" ;
77import {
8- LiquidityPoolAave , Rebalancer , Repayer , StashDex ,
8+ LiquidityPoolAave , PaxosOracle , Rebalancer , Repayer , StashDex ,
99} from "./typechain-types" ;
1010import {
1111 assert , isSet , ProviderSolidity , DomainSolidity , CCTPDomain , SolidityDomain , SolidityProvider ,
12- DEFAULT_ADMIN_ROLE , assertAddress ,
12+ DEFAULT_ADMIN_ROLE , assertAddress , addressToBytes32 ,
1313 sameAddress ,
1414} from "./scripts/common" ;
1515import "hardhat-ignore-warnings" ;
@@ -550,7 +550,7 @@ task("update-tokens-repayer", "Update input output tokens based on current netwo
550550} ) ;
551551
552552task ( "update-stashdex-routes" , "Update StashDex routes to match current network config" )
553- . addOptionalParam ( "stashdex" , "StashDex address or id" , "StashDex " , types . string )
553+ . addOptionalParam ( "stashdex" , "StashDex address or id" , "StashStablecoinDex " , types . string )
554554. addOptionalParam ( "action" , "Action to perform: add, disable, or both (default)" , "both" , types . string )
555555. setAction ( async ( args : { stashdex : string , action : string } , hre ) => {
556556 const { resolveProxyXAddress, resolveXAddress} = await loadTestHelpers ( ) ;
@@ -693,7 +693,7 @@ task("update-stashdex-routes", "Update StashDex routes to match current network
693693} ) ;
694694
695695task ( "update-stashdex-pools" , "Update StashDex pools to match current network config" )
696- . addOptionalParam ( "stashdex" , "StashDex address or id" , "StashDex " , types . string )
696+ . addOptionalParam ( "stashdex" , "StashDex address or id" , "StashStablecoinDex " , types . string )
697697. setAction ( async ( args : { stashdex : string } , hre ) => {
698698 const { resolveProxyXAddress, resolveXAddress} = await loadTestHelpers ( ) ;
699699 const { getNetworkConfig} = await loadScriptHelpers ( ) ;
@@ -761,6 +761,106 @@ task("update-stashdex-pools", "Update StashDex pools to match current network co
761761 }
762762} ) ;
763763
764+ // Does not verify if decimals are correct on-chain.
765+ task ( "update-paxos-oracle-assets" , "Synchronize PaxosOracle assets with tokens in StashDex.Pools config" )
766+ . addOptionalParam ( "oracle" , "PaxosOracle address or id" , "PaxosOracle" , types . string )
767+ . setAction ( async ( args : { oracle : string } , hre ) => {
768+ const { resolveXAddress} = await loadTestHelpers ( ) ;
769+ const { getNetworkConfig} = await loadScriptHelpers ( ) ;
770+ const { config} = await getNetworkConfig ( ) ;
771+
772+ assert ( config . StashDex , "StashDex not configured for this network" ) ;
773+
774+ const [ sender ] = await hre . ethers . getSigners ( ) ;
775+ const admin = await createSender ( hre , sender ) ;
776+
777+ const targetAddress = await resolveXAddress ( args . oracle ) ;
778+ const target = ( await hre . ethers . getContractAt ( "PaxosOracle" , targetAddress , admin ) ) as PaxosOracle ;
779+
780+ // Desired: tokens present in StashDex.Pools.
781+ const desiredTokens = ( Object . keys ( config . StashDex . Pools ) as Token [ ] )
782+ . map ( tokenName => {
783+ const tokenInfo = config . Tokens [ tokenName ] ;
784+ assert ( tokenInfo , `Token ${ tokenName } not found in config` ) ;
785+ return { TokenName : tokenName , Address : getAddress ( tokenInfo . Address ) , Decimals : tokenInfo . Decimals } ;
786+ } ) ;
787+
788+ // All known tokens — used to detect on-chain assets that should be removed.
789+ const allKnownTokens = ( Object . entries ( config . Tokens ) as [ Token , { Address : string , Decimals : number } | undefined ] [ ] )
790+ . filter ( ( [ , info ] ) => info )
791+ . map ( ( [ tokenName , info ] ) => ( { TokenName : tokenName , Address : getAddress ( info ! . Address ) , Decimals : info ! . Decimals } ) ) ;
792+
793+ const desiredAddresses = new Set ( desiredTokens . map ( t => t . Address ) ) ;
794+
795+ // Check onchain support for all known tokens.
796+ const toAdd : typeof desiredTokens = [ ] ;
797+ const toRemove : typeof allKnownTokens = [ ] ;
798+ const onchainAssets : { TokenName : string , Address : string , Decimals : number } [ ] = [ ] ;
799+
800+ for ( const token of desiredTokens ) {
801+ const assetId = addressToBytes32 ( token . Address ) ;
802+ const supported = await target . isSupported ( assetId ) ;
803+ if ( ! supported ) toAdd . push ( token ) ;
804+ else onchainAssets . push ( token ) ;
805+ }
806+
807+ for ( const token of allKnownTokens ) {
808+ if ( desiredAddresses . has ( token . Address ) ) continue ;
809+ const assetId = addressToBytes32 ( token . Address ) ;
810+ const supported = await target . isSupported ( assetId ) ;
811+ if ( supported ) {
812+ toRemove . push ( token ) ;
813+ onchainAssets . push ( token ) ;
814+ }
815+ }
816+
817+ console . log ( "Desired assets (StashDex.Pools tokens):" ) ;
818+ console . table ( desiredTokens ) ;
819+ console . log ( "On-chain assets:" ) ;
820+ console . table ( onchainAssets ) ;
821+
822+ if ( toAdd . length === 0 && toRemove . length === 0 ) {
823+ console . log ( "PaxosOracle assets are up to date." ) ;
824+ return ;
825+ }
826+
827+ const hasRole = await target . hasRole ( DEFAULT_ADMIN_ROLE , admin ) ;
828+
829+ if ( toAdd . length > 0 ) {
830+ if ( hasRole ) {
831+ for ( const { TokenName, Address, Decimals} of toAdd ) {
832+ await ( await target . addAsset ( addressToBytes32 ( Address ) , Decimals ) ) . wait ( ) ;
833+ console . log ( `Added asset: ${ TokenName } (${ Address } ) ${ Decimals } decimals` ) ;
834+ }
835+ } else {
836+ console . log ( "Assets to add — execute the following transactions:" ) ;
837+ console . log ( `To: ${ targetAddress } ` ) ;
838+ console . log ( "Function: addAsset" ) ;
839+ for ( const { TokenName, Address, Decimals} of toAdd ) {
840+ const tx = await target . addAsset . populateTransaction ( addressToBytes32 ( Address ) , Decimals ) ;
841+ console . log ( ` ${ TokenName } (${ Address } ): ${ tx . data } ` ) ;
842+ }
843+ }
844+ }
845+
846+ if ( toRemove . length > 0 ) {
847+ if ( hasRole ) {
848+ for ( const { TokenName, Address} of toRemove ) {
849+ await ( await target . removeAsset ( addressToBytes32 ( Address ) ) ) . wait ( ) ;
850+ console . log ( `Removed asset: ${ TokenName } (${ Address } )` ) ;
851+ }
852+ } else {
853+ console . log ( "Assets to remove — execute the following transactions:" ) ;
854+ console . log ( `To: ${ targetAddress } ` ) ;
855+ console . log ( "Function: removeAsset" ) ;
856+ for ( const { TokenName, Address} of toRemove ) {
857+ const tx = await target . removeAsset . populateTransaction ( addressToBytes32 ( Address ) ) ;
858+ console . log ( ` ${ TokenName } (${ Address } ): ${ tx . data } ` ) ;
859+ }
860+ }
861+ }
862+ } ) ;
863+
764864task ( "sign-borrow" , "Sign a Liquidity Pool borrow request for testing purposes" )
765865. addParam ( "caller" , "Address that will call borrow or borrowAndSwap" )
766866. addOptionalParam ( "token" , "Token to borrow" )
0 commit comments