@@ -3,14 +3,15 @@ name: Emergency Role Transfer
33on :
44 workflow_dispatch :
55 inputs :
6- step :
7- description : ' Transfer step to execute '
6+ execution_mode :
7+ description : ' Execution mode '
88 required : true
99 type : choice
1010 options :
11- - grant-roles-begin-transfer
12- - accept-admin-revoke-old
13- default : grant-roles-begin-transfer
11+ - full-transfer-with-delay
12+ - step-1-only
13+ - step-2-only
14+ default : full-transfer-with-delay
1415 network_type :
1516 description : ' Network type to transfer roles on'
1617 required : true
2021 - sepolia-only
2122 - arbitrum_sepolia-only
2223 default : testnets
23- old_address :
24- description : ' Old/compromised address (for both steps)'
25- required : true
26- type : string
27- default : ' 0x9990cfb1Feb7f47297F54bef4d4EbeDf6c5463a3'
28- new_address :
29- description : ' New secure address (only needed for step 1)'
30- required : false
31- type : string
3224
3325jobs :
3426 setup-matrix :
@@ -74,47 +66,169 @@ jobs:
7466
7567 - name : Validate inputs
7668 run : |
77- if [ "${{ inputs.step }}" = "grant-roles-begin-transfer" ] && [ -z "${{ inputs.new_address }}" ]; then
78- echo "Error: new_address is required for grant-roles-begin-transfer step"
69+ echo "Using addresses from GitHub Variables:"
70+ echo " OLD_ADDRESS: ${{ vars.OLD_ADDRESS }}"
71+ echo " NEW_ADDRESS: ${{ vars.NEW_ADDRESS }}"
72+ echo ""
73+
74+ if [ "${{ inputs.execution_mode }}" = "step-1-only" ] || [ "${{ inputs.execution_mode }}" = "full-transfer-with-delay" ]; then
75+ if [ -z "${{ vars.NEW_ADDRESS }}" ]; then
76+ echo "Error: NEW_ADDRESS variable is not set in GitHub Variables"
77+ echo "Please configure NEW_ADDRESS in repository settings -> Variables"
78+ exit 1
79+ fi
80+ fi
81+
82+ if [ -z "${{ vars.OLD_ADDRESS }}" ]; then
83+ echo "Error: OLD_ADDRESS variable is not set in GitHub Variables"
84+ echo "Please configure OLD_ADDRESS in repository settings -> Variables"
7985 exit 1
8086 fi
8187
8288 - name : Execute Step 1 - Grant Roles and Begin Transfer
83- if : inputs.step == 'grant-roles-begin -transfer'
89+ if : inputs.execution_mode == 'step-1-only' || inputs.execution_mode == 'full -transfer-with-delay '
8490 env :
8591 ADMIN_PRIVATE_KEY : ${{ secrets.ADMIN_PRIVATE_KEY }}
8692 CHAIN : ${{ matrix.network }}
8793 RPC_URL : ${{ secrets.RPC_URL }}
88- OLD_ADDRESS : ${{ inputs.old_address }}
89- NEW_ADDRESS : ${{ inputs.new_address }}
94+ OLD_ADDRESS : ${{ vars.OLD_ADDRESS }}
95+ NEW_ADDRESS : ${{ vars.NEW_ADDRESS }}
9096 run : |
91- echo "Executing Step 1: Grant roles and begin admin transfer"
97+ echo "========================================="
98+ echo "STEP 1: Grant Roles and Begin Transfer"
99+ echo "========================================="
92100 echo "Chain: $CHAIN"
93101 echo "Old address: $OLD_ADDRESS"
94102 echo "New address: $NEW_ADDRESS"
103+ echo ""
95104 make grant-roles-begin-transfer
96105
106+ - name : Wait for Delay Period
107+ if : inputs.execution_mode == 'full-transfer-with-delay'
108+ env :
109+ CHAIN : ${{ matrix.network }}
110+ RPC_URL : ${{ secrets.RPC_URL }}
111+ run : |
112+ echo "========================================="
113+ echo "WAITING FOR DELAY PERIOD"
114+ echo "========================================="
115+ echo "Querying contract for delay schedule..."
116+
117+ # Get the scheduled timestamp from the contract
118+ # This script will query the pendingDefaultAdmin and calculate wait time
119+ cat > get_delay.sh << 'EOF'
120+ #!/bin/bash
121+
122+ # Query RLCCrosschainToken or RLCLiquidityUnifier
123+ if [ "$CHAIN" = "sepolia" ]; then
124+ CONTRACT_ADDRESS="0x7198CA5eAeFE7416d4f3900b58Ff1bEA33771A65"
125+ CONTRACT_NAME="RLCLiquidityUnifier"
126+ else
127+ CONTRACT_ADDRESS="0x9923eD3cbd90CD78b910c475f9A731A6e0b8C963"
128+ CONTRACT_NAME="RLCCrosschainToken"
129+ fi
130+
131+ echo "Contract: $CONTRACT_NAME at $CONTRACT_ADDRESS"
132+
133+ # Get pending admin info (returns address and uint48 schedule)
134+ RESULT=$(cast call $CONTRACT_ADDRESS "pendingDefaultAdmin()(address,uint48)" --rpc-url $RPC_URL)
135+
136+ # Extract the timestamp (second value)
137+ SCHEDULED_TIME=$(echo $RESULT | awk '{print $2}')
138+ CURRENT_TIME=$(date +%s)
139+
140+ echo "Current timestamp: $CURRENT_TIME"
141+ echo "Scheduled timestamp: $SCHEDULED_TIME"
142+
143+ # Calculate wait time (minimum required by contract)
144+ WAIT_SECONDS=$((SCHEDULED_TIME - CURRENT_TIME))
145+
146+ # Add 1 second to ensure we're past the scheduled time
147+ TOTAL_WAIT=$((WAIT_SECONDS + 1))
148+
149+ if [ $TOTAL_WAIT -le 0 ]; then
150+ echo "✅ Delay period has already passed!"
151+ echo "Proceeding immediately with Step 2..."
152+ exit 0
153+ fi
154+
155+ echo ""
156+ echo "⏰ Delay period:"
157+ echo " - Required wait: $WAIT_SECONDS seconds ($((WAIT_SECONDS / 60)) minutes)"
158+ echo " - Safety buffer: 1 second"
159+ echo " - Total wait: $TOTAL_WAIT seconds ($((TOTAL_WAIT / 60)) minutes)"
160+ echo ""
161+ echo "Waiting until: $(date -u -r $((SCHEDULED_TIME + 1)) '+%Y-%m-%d %H:%M:%S UTC')"
162+ echo ""
163+
164+ # Sleep in chunks to show progress
165+ INTERVAL=60 # Show progress every minute
166+ ELAPSED=0
167+
168+ while [ $ELAPSED -lt $TOTAL_WAIT ]; do
169+ REMAINING=$((TOTAL_WAIT - ELAPSED))
170+ if [ $REMAINING -lt $INTERVAL ]; then
171+ sleep $REMAINING
172+ ELAPSED=$TOTAL_WAIT
173+ else
174+ sleep $INTERVAL
175+ ELAPSED=$((ELAPSED + INTERVAL))
176+ echo "⏳ Progress: $((ELAPSED / 60))/$((TOTAL_WAIT / 60)) minutes elapsed..."
177+ fi
178+ done
179+
180+ echo ""
181+ echo "✅ Delay period complete! Proceeding to Step 2..."
182+ EOF
183+
184+ chmod +x get_delay.sh
185+ ./get_delay.sh
186+
97187 - name : Execute Step 2 - Accept Admin and Revoke Old Roles
98- if : inputs.step == 'accept-admin-revoke-old '
188+ if : inputs.execution_mode == ' step-2-only' || inputs.execution_mode == 'full-transfer-with-delay '
99189 env :
100190 NEW_ADMIN_PRIVATE_KEY : ${{ secrets.NEW_ADMIN_PRIVATE_KEY }}
101191 CHAIN : ${{ matrix.network }}
102192 RPC_URL : ${{ secrets.RPC_URL }}
103- OLD_ADDRESS : ${{ inputs.old_address }}
193+ OLD_ADDRESS : ${{ vars.OLD_ADDRESS }}
104194 run : |
105- echo "Executing Step 2: Accept admin role and revoke old roles"
195+ echo "========================================="
196+ echo "STEP 2: Accept Admin and Revoke Old Roles"
197+ echo "========================================="
106198 echo "Chain: $CHAIN"
107199 echo "Old address to revoke: $OLD_ADDRESS"
200+ echo ""
108201 make accept-admin-revoke-old
109202
110203 - name : Summary
111204 run : |
112- if [ "${{ inputs.step }}" = "grant-roles-begin-transfer" ]; then
113- echo "✅ Step 1 Complete on ${{ matrix.network }}"
205+ echo ""
206+ echo "========================================="
207+ echo "SUMMARY"
208+ echo "========================================="
209+
210+ if [ "${{ inputs.execution_mode }}" = "full-transfer-with-delay" ]; then
211+ echo "✅ FULL TRANSFER COMPLETE on ${{ matrix.network }}"
212+ echo ""
213+ echo "Steps completed:"
214+ echo " 1. ✅ Granted operational roles to new address"
215+ echo " 2. ✅ Began admin transfer with delay period"
216+ echo " 3. ✅ Waited for minimum contract delay period"
217+ echo " 4. ✅ Accepted admin role with new address"
218+ echo " 5. ✅ Revoked all roles from old address"
219+ echo ""
220+ echo "🎉 All roles have been transferred!"
221+ echo "🔒 Old address has been completely removed from all contracts"
222+
223+ elif [ "${{ inputs.execution_mode }}" = "step-1-only" ]; then
224+ echo "✅ STEP 1 COMPLETE on ${{ matrix.network }}"
225+ echo ""
114226 echo "⏰ Wait for the delay period to pass before running Step 2"
115- echo "📝 Next: Run this workflow again with step=accept-admin-revoke-old"
227+ echo "📝 Next: Run this workflow again with execution_mode=step-2-only"
228+
116229 else
117- echo "✅ Step 2 Complete on ${{ matrix.network }}"
230+ echo "✅ STEP 2 COMPLETE on ${{ matrix.network }}"
231+ echo ""
118232 echo "🎉 All roles have been transferred!"
119233 echo "🔒 Old address has been completely removed from all contracts"
120234 fi
0 commit comments