@@ -167,7 +167,7 @@ contract SubnetActorManagerFacet is SubnetActorModifiers, ReentrancyGuard, Pausa
167167 LibPower.setMetadataWithConfirm (msg .sender , publicKey);
168168 LibPower.depositWithConfirm (msg .sender , amount);
169169
170- _patchGenesisValidators (msg .sender );
170+ _increaseGenesisValidatorCollateral (msg .sender , amount );
171171
172172 LibSubnetActor.bootstrapSubnetIfNeeded ();
173173 } else {
@@ -177,31 +177,57 @@ contract SubnetActorManagerFacet is SubnetActorModifiers, ReentrancyGuard, Pausa
177177 }
178178 }
179179
180- function _patchGenesisValidators (address validator ) internal {
180+ function _increaseGenesisValidatorCollateral (address validator , uint256 amount ) internal {
181181 // add to initial validators avoiding duplicates if it
182182 // is a genesis validator.
183- bool alreadyValidator;
184183 uint256 length = s.genesisValidators.length ;
185- for (uint256 i; i < length; ) {
184+ uint256 i;
185+ for (; i < length; ) {
186186 if (s.genesisValidators[i].addr == validator) {
187- alreadyValidator = true ;
188187 break ;
189188 }
190189 unchecked {
191190 ++ i;
192191 }
193192 }
194- if (! alreadyValidator) {
195- uint256 collateral = s.validatorSet.validators[validator].currentPower;
193+ // if we iterate through all of them, and found one
194+ // condition must hold
195+ if (i < length) {
196+ // nth-call to `_increaseGenesisValidatorCollateral`
197+ s.genesisValidators[i].weight += amount;
198+ } else {
199+ // otherwise we need to add new validator with given amount
196200 Validator memory val = Validator ({
197201 addr: validator,
198- weight: collateral ,
202+ weight: amount ,
199203 metadata: s.validatorSet.validators[validator].metadata
200204 });
201205 s.genesisValidators.push (val);
202206 }
203207 }
204208
209+ function _decreaseGenesisValidatorCollateral (address validator , uint256 amount ) internal {
210+ uint256 length = s.genesisValidators.length ;
211+ uint256 i;
212+ for (; i < length; ) {
213+ if (s.genesisValidators[i].addr == validator) {
214+ break ;
215+ }
216+ unchecked {
217+ ++ i;
218+ }
219+ }
220+ if (i < length) {
221+ uint256 bound = s.genesisValidators[i].weight;
222+ if (bound < amount) {
223+ revert NotEnoughCollateral ();
224+ }
225+ s.genesisValidators[i].weight -= amount;
226+ } else {
227+ revert NotValidator (validator);
228+ }
229+ }
230+
205231 /// @notice method that allows a validator to increase its stake.
206232 /// If the total confirmed collateral of the subnet is greater
207233 /// or equal to minimum activation collateral as a result of this operation,
@@ -226,7 +252,7 @@ contract SubnetActorManagerFacet is SubnetActorModifiers, ReentrancyGuard, Pausa
226252
227253 if (! s.bootstrapped) {
228254 LibPower.depositWithConfirm (msg .sender , amount);
229- _patchGenesisValidators (msg .sender );
255+ _increaseGenesisValidatorCollateral (msg .sender , amount );
230256 LibSubnetActor.bootstrapSubnetIfNeeded ();
231257 } else {
232258 LibPower.deposit (msg .sender , amount);
@@ -258,6 +284,7 @@ contract SubnetActorManagerFacet is SubnetActorModifiers, ReentrancyGuard, Pausa
258284
259285 if (! s.bootstrapped) {
260286 LibPower.withdrawWithConfirm (msg .sender , amount);
287+ _decreaseGenesisValidatorCollateral (msg .sender , amount);
261288 s.collateralSource.transferFunds (payable (msg .sender ), amount);
262289 } else {
263290 LibPower.withdraw (msg .sender , amount);
@@ -302,6 +329,7 @@ contract SubnetActorManagerFacet is SubnetActorModifiers, ReentrancyGuard, Pausa
302329 // interaction must be performed after checks and changes
303330 // we do check bootstrapping again, deliberately to avoid a complex exploit scenario
304331 if (! s.bootstrapped) {
332+ _decreaseGenesisValidatorCollateral (msg .sender , amount);
305333 LibPower.withdrawWithConfirm (msg .sender , amount);
306334 s.collateralSource.transferFunds (payable (msg .sender ), amount);
307335 } else {
0 commit comments