@inco/lightning 0.8.0-devnet → 0.8.0-devnet-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/IncoLightning.sol +4 -0
- package/src/Lib.alphanet.sol +62 -6
- package/src/Lib.demonet.sol +62 -6
- package/src/Lib.devnet.sol +62 -6
- package/src/Lib.sol +62 -6
- package/src/Lib.template.sol +65 -9
- package/src/Lib.testnet.sol +62 -6
- package/src/interfaces/IIncoLightning.sol +2 -0
- package/src/libs/incoLightning_alphanet_v0_297966649.sol +62 -6
- package/src/libs/incoLightning_alphanet_v1_725458969.sol +62 -6
- package/src/libs/incoLightning_alphanet_v2_976644394.sol +62 -6
- package/src/libs/incoLightning_demonet_v0_863421733.sol +62 -6
- package/src/libs/incoLightning_demonet_v2_467437523.sol +62 -6
- package/src/libs/incoLightning_devnet_v0_340846814.sol +62 -6
- package/src/libs/incoLightning_devnet_v1_904635675.sol +62 -6
- package/src/libs/incoLightning_devnet_v2_295237520.sol +62 -6
- package/src/libs/incoLightning_devnet_v3_976859633.sol +62 -6
- package/src/libs/incoLightning_testnet_v0_183408998.sol +62 -6
- package/src/libs/incoLightning_testnet_v2_889158349.sol +62 -6
- package/src/lightning-parts/Fee.sol +9 -13
- package/src/periphery/IncoUtils.sol +42 -0
- package/src/test/AddTwo.sol +3 -3
- package/src/test/TestFakeInfra.t.sol +263 -0
- package/src/test/TestFeeWithdrawal.t.sol +60 -0
- package/src/test/TestIncoUtils.t.sol +242 -0
- package/src/IIncoLightning.sol +0 -22
package/package.json
CHANGED
package/src/IncoLightning.sol
CHANGED
package/src/Lib.alphanet.sol
CHANGED
|
@@ -16,6 +16,11 @@ function typeOf(bytes32 handle) pure returns (ETypes) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
library e {
|
|
19
|
+
error CallFailedAfterFeeRefresh();
|
|
20
|
+
|
|
21
|
+
/// @dev slot to store the fee for inco operations
|
|
22
|
+
bytes32 private constant FEE_SLOT = keccak256("inco.fee");
|
|
23
|
+
|
|
19
24
|
function sanitize(euint256 a) internal returns (euint256) {
|
|
20
25
|
if (euint256.unwrap(a) == bytes32(0)) {
|
|
21
26
|
return asEuint256(0);
|
|
@@ -355,17 +360,22 @@ library e {
|
|
|
355
360
|
|
|
356
361
|
/// @dev costs the inco fee
|
|
357
362
|
function rand() internal returns (euint256) {
|
|
358
|
-
|
|
363
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRand.selector, ETypes.Uint256));
|
|
364
|
+
return euint256.wrap(result);
|
|
359
365
|
}
|
|
360
366
|
|
|
361
367
|
/// @dev costs the inco fee
|
|
362
368
|
function randBounded(uint256 upperBound) internal returns (euint256) {
|
|
363
|
-
|
|
369
|
+
bytes32 boundHandle = euint256.unwrap(asEuint256(upperBound));
|
|
370
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRandBounded.selector, boundHandle, ETypes.Uint256));
|
|
371
|
+
return euint256.wrap(result);
|
|
364
372
|
}
|
|
365
373
|
|
|
366
374
|
/// @dev costs the inco fee
|
|
367
375
|
function randBounded(euint256 upperBound) internal returns (euint256) {
|
|
368
|
-
|
|
376
|
+
bytes32 boundHandle = euint256.unwrap(s(upperBound));
|
|
377
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRandBounded.selector, boundHandle, ETypes.Uint256));
|
|
378
|
+
return euint256.wrap(result);
|
|
369
379
|
}
|
|
370
380
|
|
|
371
381
|
function asEuint256(uint256 a) internal returns (euint256) {
|
|
@@ -397,7 +407,8 @@ library e {
|
|
|
397
407
|
/// @notice Creates a new encrypted uint256 for the given user.
|
|
398
408
|
/// @dev costs the inco fee
|
|
399
409
|
function newEuint256(bytes memory ciphertext, address user) internal returns (euint256) {
|
|
400
|
-
|
|
410
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.newEuint256.selector, ciphertext, user));
|
|
411
|
+
return euint256.wrap(result);
|
|
401
412
|
}
|
|
402
413
|
|
|
403
414
|
/// @notice Creates a new encrypted bool assuming msg.sender is the user
|
|
@@ -409,7 +420,8 @@ library e {
|
|
|
409
420
|
/// @notice Creates a new encrypted bool for the given user.
|
|
410
421
|
/// @dev costs the inco fee
|
|
411
422
|
function newEbool(bytes memory ciphertext, address user) internal returns (ebool) {
|
|
412
|
-
|
|
423
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.newEbool.selector, ciphertext, user));
|
|
424
|
+
return ebool.wrap(result);
|
|
413
425
|
}
|
|
414
426
|
|
|
415
427
|
/// @notice Creates a new encrypted address assuming msg.sender is the user
|
|
@@ -421,7 +433,8 @@ library e {
|
|
|
421
433
|
/// @notice Creates a new encrypted address for the given user.
|
|
422
434
|
/// @dev costs the inco fee
|
|
423
435
|
function newEaddress(bytes memory ciphertext, address user) internal returns (eaddress) {
|
|
424
|
-
|
|
436
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.newEaddress.selector, ciphertext, user));
|
|
437
|
+
return eaddress.wrap(result);
|
|
425
438
|
}
|
|
426
439
|
|
|
427
440
|
function allow(euint256 a, address to) internal {
|
|
@@ -475,4 +488,47 @@ library e {
|
|
|
475
488
|
function select(ebool control, eaddress ifTrue, eaddress ifFalse) internal returns (eaddress) {
|
|
476
489
|
return eaddress.wrap(inco.eIfThenElse(s(control), eaddress.unwrap(s(ifTrue)), eaddress.unwrap(s(ifFalse))));
|
|
477
490
|
}
|
|
491
|
+
|
|
492
|
+
/// @dev Store fee in the custom slot
|
|
493
|
+
/// @param _fee The fee to store
|
|
494
|
+
function _setFee(uint256 _fee) private {
|
|
495
|
+
bytes32 slot = FEE_SLOT;
|
|
496
|
+
assembly {
|
|
497
|
+
sstore(slot, _fee)
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/// @dev Retrieve fee from the custom slot
|
|
502
|
+
/// @return fee The stored fee
|
|
503
|
+
function _getFee() private view returns (uint256 fee) {
|
|
504
|
+
bytes32 slot = FEE_SLOT;
|
|
505
|
+
assembly {
|
|
506
|
+
fee := sload(slot)
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/// @dev Get current fee with fallback to inco.getFee() if not cached
|
|
511
|
+
function getCurrentFee() private returns (uint256) {
|
|
512
|
+
uint256 cachedFee = _getFee();
|
|
513
|
+
if (cachedFee == 0) {
|
|
514
|
+
cachedFee = inco.getFee();
|
|
515
|
+
_setFee(cachedFee);
|
|
516
|
+
}
|
|
517
|
+
return cachedFee;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/// @dev Execute a call to inco with fee, retrying with fresh fee if it fails
|
|
521
|
+
/// @param callData The encoded function call (use abi.encodeWithSelector)
|
|
522
|
+
/// @return result The bytes32 result from the call
|
|
523
|
+
function _callWithFeeRetry(bytes memory callData) private returns (bytes32) {
|
|
524
|
+
uint256 fee = getCurrentFee();
|
|
525
|
+
(bool success, bytes memory result) = address(inco).call{value: fee}(callData);
|
|
526
|
+
if (!success) {
|
|
527
|
+
fee = inco.getFee();
|
|
528
|
+
_setFee(fee);
|
|
529
|
+
(success, result) = address(inco).call{value: fee}(callData);
|
|
530
|
+
require(success, CallFailedAfterFeeRefresh());
|
|
531
|
+
}
|
|
532
|
+
return abi.decode(result, (bytes32));
|
|
533
|
+
}
|
|
478
534
|
}
|
package/src/Lib.demonet.sol
CHANGED
|
@@ -16,6 +16,11 @@ function typeOf(bytes32 handle) pure returns (ETypes) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
library e {
|
|
19
|
+
error CallFailedAfterFeeRefresh();
|
|
20
|
+
|
|
21
|
+
/// @dev slot to store the fee for inco operations
|
|
22
|
+
bytes32 private constant FEE_SLOT = keccak256("inco.fee");
|
|
23
|
+
|
|
19
24
|
function sanitize(euint256 a) internal returns (euint256) {
|
|
20
25
|
if (euint256.unwrap(a) == bytes32(0)) {
|
|
21
26
|
return asEuint256(0);
|
|
@@ -355,17 +360,22 @@ library e {
|
|
|
355
360
|
|
|
356
361
|
/// @dev costs the inco fee
|
|
357
362
|
function rand() internal returns (euint256) {
|
|
358
|
-
|
|
363
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRand.selector, ETypes.Uint256));
|
|
364
|
+
return euint256.wrap(result);
|
|
359
365
|
}
|
|
360
366
|
|
|
361
367
|
/// @dev costs the inco fee
|
|
362
368
|
function randBounded(uint256 upperBound) internal returns (euint256) {
|
|
363
|
-
|
|
369
|
+
bytes32 boundHandle = euint256.unwrap(asEuint256(upperBound));
|
|
370
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRandBounded.selector, boundHandle, ETypes.Uint256));
|
|
371
|
+
return euint256.wrap(result);
|
|
364
372
|
}
|
|
365
373
|
|
|
366
374
|
/// @dev costs the inco fee
|
|
367
375
|
function randBounded(euint256 upperBound) internal returns (euint256) {
|
|
368
|
-
|
|
376
|
+
bytes32 boundHandle = euint256.unwrap(s(upperBound));
|
|
377
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRandBounded.selector, boundHandle, ETypes.Uint256));
|
|
378
|
+
return euint256.wrap(result);
|
|
369
379
|
}
|
|
370
380
|
|
|
371
381
|
function asEuint256(uint256 a) internal returns (euint256) {
|
|
@@ -397,7 +407,8 @@ library e {
|
|
|
397
407
|
/// @notice Creates a new encrypted uint256 for the given user.
|
|
398
408
|
/// @dev costs the inco fee
|
|
399
409
|
function newEuint256(bytes memory ciphertext, address user) internal returns (euint256) {
|
|
400
|
-
|
|
410
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.newEuint256.selector, ciphertext, user));
|
|
411
|
+
return euint256.wrap(result);
|
|
401
412
|
}
|
|
402
413
|
|
|
403
414
|
/// @notice Creates a new encrypted bool assuming msg.sender is the user
|
|
@@ -409,7 +420,8 @@ library e {
|
|
|
409
420
|
/// @notice Creates a new encrypted bool for the given user.
|
|
410
421
|
/// @dev costs the inco fee
|
|
411
422
|
function newEbool(bytes memory ciphertext, address user) internal returns (ebool) {
|
|
412
|
-
|
|
423
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.newEbool.selector, ciphertext, user));
|
|
424
|
+
return ebool.wrap(result);
|
|
413
425
|
}
|
|
414
426
|
|
|
415
427
|
/// @notice Creates a new encrypted address assuming msg.sender is the user
|
|
@@ -421,7 +433,8 @@ library e {
|
|
|
421
433
|
/// @notice Creates a new encrypted address for the given user.
|
|
422
434
|
/// @dev costs the inco fee
|
|
423
435
|
function newEaddress(bytes memory ciphertext, address user) internal returns (eaddress) {
|
|
424
|
-
|
|
436
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.newEaddress.selector, ciphertext, user));
|
|
437
|
+
return eaddress.wrap(result);
|
|
425
438
|
}
|
|
426
439
|
|
|
427
440
|
function allow(euint256 a, address to) internal {
|
|
@@ -475,4 +488,47 @@ library e {
|
|
|
475
488
|
function select(ebool control, eaddress ifTrue, eaddress ifFalse) internal returns (eaddress) {
|
|
476
489
|
return eaddress.wrap(inco.eIfThenElse(s(control), eaddress.unwrap(s(ifTrue)), eaddress.unwrap(s(ifFalse))));
|
|
477
490
|
}
|
|
491
|
+
|
|
492
|
+
/// @dev Store fee in the custom slot
|
|
493
|
+
/// @param _fee The fee to store
|
|
494
|
+
function _setFee(uint256 _fee) private {
|
|
495
|
+
bytes32 slot = FEE_SLOT;
|
|
496
|
+
assembly {
|
|
497
|
+
sstore(slot, _fee)
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/// @dev Retrieve fee from the custom slot
|
|
502
|
+
/// @return fee The stored fee
|
|
503
|
+
function _getFee() private view returns (uint256 fee) {
|
|
504
|
+
bytes32 slot = FEE_SLOT;
|
|
505
|
+
assembly {
|
|
506
|
+
fee := sload(slot)
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/// @dev Get current fee with fallback to inco.getFee() if not cached
|
|
511
|
+
function getCurrentFee() private returns (uint256) {
|
|
512
|
+
uint256 cachedFee = _getFee();
|
|
513
|
+
if (cachedFee == 0) {
|
|
514
|
+
cachedFee = inco.getFee();
|
|
515
|
+
_setFee(cachedFee);
|
|
516
|
+
}
|
|
517
|
+
return cachedFee;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/// @dev Execute a call to inco with fee, retrying with fresh fee if it fails
|
|
521
|
+
/// @param callData The encoded function call (use abi.encodeWithSelector)
|
|
522
|
+
/// @return result The bytes32 result from the call
|
|
523
|
+
function _callWithFeeRetry(bytes memory callData) private returns (bytes32) {
|
|
524
|
+
uint256 fee = getCurrentFee();
|
|
525
|
+
(bool success, bytes memory result) = address(inco).call{value: fee}(callData);
|
|
526
|
+
if (!success) {
|
|
527
|
+
fee = inco.getFee();
|
|
528
|
+
_setFee(fee);
|
|
529
|
+
(success, result) = address(inco).call{value: fee}(callData);
|
|
530
|
+
require(success, CallFailedAfterFeeRefresh());
|
|
531
|
+
}
|
|
532
|
+
return abi.decode(result, (bytes32));
|
|
533
|
+
}
|
|
478
534
|
}
|
package/src/Lib.devnet.sol
CHANGED
|
@@ -16,6 +16,11 @@ function typeOf(bytes32 handle) pure returns (ETypes) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
library e {
|
|
19
|
+
error CallFailedAfterFeeRefresh();
|
|
20
|
+
|
|
21
|
+
/// @dev slot to store the fee for inco operations
|
|
22
|
+
bytes32 private constant FEE_SLOT = keccak256("inco.fee");
|
|
23
|
+
|
|
19
24
|
function sanitize(euint256 a) internal returns (euint256) {
|
|
20
25
|
if (euint256.unwrap(a) == bytes32(0)) {
|
|
21
26
|
return asEuint256(0);
|
|
@@ -355,17 +360,22 @@ library e {
|
|
|
355
360
|
|
|
356
361
|
/// @dev costs the inco fee
|
|
357
362
|
function rand() internal returns (euint256) {
|
|
358
|
-
|
|
363
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRand.selector, ETypes.Uint256));
|
|
364
|
+
return euint256.wrap(result);
|
|
359
365
|
}
|
|
360
366
|
|
|
361
367
|
/// @dev costs the inco fee
|
|
362
368
|
function randBounded(uint256 upperBound) internal returns (euint256) {
|
|
363
|
-
|
|
369
|
+
bytes32 boundHandle = euint256.unwrap(asEuint256(upperBound));
|
|
370
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRandBounded.selector, boundHandle, ETypes.Uint256));
|
|
371
|
+
return euint256.wrap(result);
|
|
364
372
|
}
|
|
365
373
|
|
|
366
374
|
/// @dev costs the inco fee
|
|
367
375
|
function randBounded(euint256 upperBound) internal returns (euint256) {
|
|
368
|
-
|
|
376
|
+
bytes32 boundHandle = euint256.unwrap(s(upperBound));
|
|
377
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRandBounded.selector, boundHandle, ETypes.Uint256));
|
|
378
|
+
return euint256.wrap(result);
|
|
369
379
|
}
|
|
370
380
|
|
|
371
381
|
function asEuint256(uint256 a) internal returns (euint256) {
|
|
@@ -397,7 +407,8 @@ library e {
|
|
|
397
407
|
/// @notice Creates a new encrypted uint256 for the given user.
|
|
398
408
|
/// @dev costs the inco fee
|
|
399
409
|
function newEuint256(bytes memory ciphertext, address user) internal returns (euint256) {
|
|
400
|
-
|
|
410
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.newEuint256.selector, ciphertext, user));
|
|
411
|
+
return euint256.wrap(result);
|
|
401
412
|
}
|
|
402
413
|
|
|
403
414
|
/// @notice Creates a new encrypted bool assuming msg.sender is the user
|
|
@@ -409,7 +420,8 @@ library e {
|
|
|
409
420
|
/// @notice Creates a new encrypted bool for the given user.
|
|
410
421
|
/// @dev costs the inco fee
|
|
411
422
|
function newEbool(bytes memory ciphertext, address user) internal returns (ebool) {
|
|
412
|
-
|
|
423
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.newEbool.selector, ciphertext, user));
|
|
424
|
+
return ebool.wrap(result);
|
|
413
425
|
}
|
|
414
426
|
|
|
415
427
|
/// @notice Creates a new encrypted address assuming msg.sender is the user
|
|
@@ -421,7 +433,8 @@ library e {
|
|
|
421
433
|
/// @notice Creates a new encrypted address for the given user.
|
|
422
434
|
/// @dev costs the inco fee
|
|
423
435
|
function newEaddress(bytes memory ciphertext, address user) internal returns (eaddress) {
|
|
424
|
-
|
|
436
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.newEaddress.selector, ciphertext, user));
|
|
437
|
+
return eaddress.wrap(result);
|
|
425
438
|
}
|
|
426
439
|
|
|
427
440
|
function allow(euint256 a, address to) internal {
|
|
@@ -475,4 +488,47 @@ library e {
|
|
|
475
488
|
function select(ebool control, eaddress ifTrue, eaddress ifFalse) internal returns (eaddress) {
|
|
476
489
|
return eaddress.wrap(inco.eIfThenElse(s(control), eaddress.unwrap(s(ifTrue)), eaddress.unwrap(s(ifFalse))));
|
|
477
490
|
}
|
|
491
|
+
|
|
492
|
+
/// @dev Store fee in the custom slot
|
|
493
|
+
/// @param _fee The fee to store
|
|
494
|
+
function _setFee(uint256 _fee) private {
|
|
495
|
+
bytes32 slot = FEE_SLOT;
|
|
496
|
+
assembly {
|
|
497
|
+
sstore(slot, _fee)
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/// @dev Retrieve fee from the custom slot
|
|
502
|
+
/// @return fee The stored fee
|
|
503
|
+
function _getFee() private view returns (uint256 fee) {
|
|
504
|
+
bytes32 slot = FEE_SLOT;
|
|
505
|
+
assembly {
|
|
506
|
+
fee := sload(slot)
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/// @dev Get current fee with fallback to inco.getFee() if not cached
|
|
511
|
+
function getCurrentFee() private returns (uint256) {
|
|
512
|
+
uint256 cachedFee = _getFee();
|
|
513
|
+
if (cachedFee == 0) {
|
|
514
|
+
cachedFee = inco.getFee();
|
|
515
|
+
_setFee(cachedFee);
|
|
516
|
+
}
|
|
517
|
+
return cachedFee;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/// @dev Execute a call to inco with fee, retrying with fresh fee if it fails
|
|
521
|
+
/// @param callData The encoded function call (use abi.encodeWithSelector)
|
|
522
|
+
/// @return result The bytes32 result from the call
|
|
523
|
+
function _callWithFeeRetry(bytes memory callData) private returns (bytes32) {
|
|
524
|
+
uint256 fee = getCurrentFee();
|
|
525
|
+
(bool success, bytes memory result) = address(inco).call{value: fee}(callData);
|
|
526
|
+
if (!success) {
|
|
527
|
+
fee = inco.getFee();
|
|
528
|
+
_setFee(fee);
|
|
529
|
+
(success, result) = address(inco).call{value: fee}(callData);
|
|
530
|
+
require(success, CallFailedAfterFeeRefresh());
|
|
531
|
+
}
|
|
532
|
+
return abi.decode(result, (bytes32));
|
|
533
|
+
}
|
|
478
534
|
}
|
package/src/Lib.sol
CHANGED
|
@@ -16,6 +16,11 @@ function typeOf(bytes32 handle) pure returns (ETypes) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
library e {
|
|
19
|
+
error CallFailedAfterFeeRefresh();
|
|
20
|
+
|
|
21
|
+
/// @dev slot to store the fee for inco operations
|
|
22
|
+
bytes32 private constant FEE_SLOT = keccak256("inco.fee");
|
|
23
|
+
|
|
19
24
|
function sanitize(euint256 a) internal returns (euint256) {
|
|
20
25
|
if (euint256.unwrap(a) == bytes32(0)) {
|
|
21
26
|
return asEuint256(0);
|
|
@@ -355,17 +360,22 @@ library e {
|
|
|
355
360
|
|
|
356
361
|
/// @dev costs the inco fee
|
|
357
362
|
function rand() internal returns (euint256) {
|
|
358
|
-
|
|
363
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRand.selector, ETypes.Uint256));
|
|
364
|
+
return euint256.wrap(result);
|
|
359
365
|
}
|
|
360
366
|
|
|
361
367
|
/// @dev costs the inco fee
|
|
362
368
|
function randBounded(uint256 upperBound) internal returns (euint256) {
|
|
363
|
-
|
|
369
|
+
bytes32 boundHandle = euint256.unwrap(asEuint256(upperBound));
|
|
370
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRandBounded.selector, boundHandle, ETypes.Uint256));
|
|
371
|
+
return euint256.wrap(result);
|
|
364
372
|
}
|
|
365
373
|
|
|
366
374
|
/// @dev costs the inco fee
|
|
367
375
|
function randBounded(euint256 upperBound) internal returns (euint256) {
|
|
368
|
-
|
|
376
|
+
bytes32 boundHandle = euint256.unwrap(s(upperBound));
|
|
377
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRandBounded.selector, boundHandle, ETypes.Uint256));
|
|
378
|
+
return euint256.wrap(result);
|
|
369
379
|
}
|
|
370
380
|
|
|
371
381
|
function asEuint256(uint256 a) internal returns (euint256) {
|
|
@@ -397,7 +407,8 @@ library e {
|
|
|
397
407
|
/// @notice Creates a new encrypted uint256 for the given user.
|
|
398
408
|
/// @dev costs the inco fee
|
|
399
409
|
function newEuint256(bytes memory ciphertext, address user) internal returns (euint256) {
|
|
400
|
-
|
|
410
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.newEuint256.selector, ciphertext, user));
|
|
411
|
+
return euint256.wrap(result);
|
|
401
412
|
}
|
|
402
413
|
|
|
403
414
|
/// @notice Creates a new encrypted bool assuming msg.sender is the user
|
|
@@ -409,7 +420,8 @@ library e {
|
|
|
409
420
|
/// @notice Creates a new encrypted bool for the given user.
|
|
410
421
|
/// @dev costs the inco fee
|
|
411
422
|
function newEbool(bytes memory ciphertext, address user) internal returns (ebool) {
|
|
412
|
-
|
|
423
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.newEbool.selector, ciphertext, user));
|
|
424
|
+
return ebool.wrap(result);
|
|
413
425
|
}
|
|
414
426
|
|
|
415
427
|
/// @notice Creates a new encrypted address assuming msg.sender is the user
|
|
@@ -421,7 +433,8 @@ library e {
|
|
|
421
433
|
/// @notice Creates a new encrypted address for the given user.
|
|
422
434
|
/// @dev costs the inco fee
|
|
423
435
|
function newEaddress(bytes memory ciphertext, address user) internal returns (eaddress) {
|
|
424
|
-
|
|
436
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.newEaddress.selector, ciphertext, user));
|
|
437
|
+
return eaddress.wrap(result);
|
|
425
438
|
}
|
|
426
439
|
|
|
427
440
|
function allow(euint256 a, address to) internal {
|
|
@@ -475,4 +488,47 @@ library e {
|
|
|
475
488
|
function select(ebool control, eaddress ifTrue, eaddress ifFalse) internal returns (eaddress) {
|
|
476
489
|
return eaddress.wrap(inco.eIfThenElse(s(control), eaddress.unwrap(s(ifTrue)), eaddress.unwrap(s(ifFalse))));
|
|
477
490
|
}
|
|
491
|
+
|
|
492
|
+
/// @dev Store fee in the custom slot
|
|
493
|
+
/// @param _fee The fee to store
|
|
494
|
+
function _setFee(uint256 _fee) private {
|
|
495
|
+
bytes32 slot = FEE_SLOT;
|
|
496
|
+
assembly {
|
|
497
|
+
sstore(slot, _fee)
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/// @dev Retrieve fee from the custom slot
|
|
502
|
+
/// @return fee The stored fee
|
|
503
|
+
function _getFee() private view returns (uint256 fee) {
|
|
504
|
+
bytes32 slot = FEE_SLOT;
|
|
505
|
+
assembly {
|
|
506
|
+
fee := sload(slot)
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/// @dev Get current fee with fallback to inco.getFee() if not cached
|
|
511
|
+
function getCurrentFee() private returns (uint256) {
|
|
512
|
+
uint256 cachedFee = _getFee();
|
|
513
|
+
if (cachedFee == 0) {
|
|
514
|
+
cachedFee = inco.getFee();
|
|
515
|
+
_setFee(cachedFee);
|
|
516
|
+
}
|
|
517
|
+
return cachedFee;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/// @dev Execute a call to inco with fee, retrying with fresh fee if it fails
|
|
521
|
+
/// @param callData The encoded function call (use abi.encodeWithSelector)
|
|
522
|
+
/// @return result The bytes32 result from the call
|
|
523
|
+
function _callWithFeeRetry(bytes memory callData) private returns (bytes32) {
|
|
524
|
+
uint256 fee = getCurrentFee();
|
|
525
|
+
(bool success, bytes memory result) = address(inco).call{value: fee}(callData);
|
|
526
|
+
if (!success) {
|
|
527
|
+
fee = inco.getFee();
|
|
528
|
+
_setFee(fee);
|
|
529
|
+
(success, result) = address(inco).call{value: fee}(callData);
|
|
530
|
+
require(success, CallFailedAfterFeeRefresh());
|
|
531
|
+
}
|
|
532
|
+
return abi.decode(result, (bytes32));
|
|
533
|
+
}
|
|
478
534
|
}
|
package/src/Lib.template.sol
CHANGED
|
@@ -16,6 +16,8 @@ function typeOf(bytes32 handle) pure returns (ETypes) {
|
|
|
16
16
|
|
|
17
17
|
library e {
|
|
18
18
|
|
|
19
|
+
error CallFailedAfterFeeRefresh();
|
|
20
|
+
|
|
19
21
|
function sanitize(euint256 a) internal returns (euint256) {
|
|
20
22
|
if (euint256.unwrap(a) == bytes32(0)) {
|
|
21
23
|
return asEuint256(0);
|
|
@@ -355,20 +357,24 @@ library e {
|
|
|
355
357
|
|
|
356
358
|
/// @dev costs the inco fee
|
|
357
359
|
function rand() internal returns (euint256) {
|
|
358
|
-
|
|
360
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.eRand.selector, ETypes.Uint256));
|
|
361
|
+
return euint256.wrap(result);
|
|
359
362
|
}
|
|
360
363
|
|
|
361
364
|
/// @dev costs the inco fee
|
|
362
365
|
function randBounded(uint256 upperBound) internal returns (euint256) {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
366
|
+
bytes32 boundHandle = euint256.unwrap(asEuint256(upperBound));
|
|
367
|
+
bytes32 result =
|
|
368
|
+
_callWithFeeRetry(abi.encodeWithSelector(inco.eRandBounded.selector, boundHandle, ETypes.Uint256));
|
|
369
|
+
return euint256.wrap(result);
|
|
367
370
|
}
|
|
368
371
|
|
|
369
372
|
/// @dev costs the inco fee
|
|
370
373
|
function randBounded(euint256 upperBound) internal returns (euint256) {
|
|
371
|
-
|
|
374
|
+
bytes32 boundHandle = euint256.unwrap(s(upperBound));
|
|
375
|
+
bytes32 result =
|
|
376
|
+
_callWithFeeRetry(abi.encodeWithSelector(inco.eRandBounded.selector, boundHandle, ETypes.Uint256));
|
|
377
|
+
return euint256.wrap(result);
|
|
372
378
|
}
|
|
373
379
|
|
|
374
380
|
function asEuint256(uint256 a) internal returns (euint256) {
|
|
@@ -400,7 +406,8 @@ library e {
|
|
|
400
406
|
/// @notice Creates a new encrypted uint256 for the given user.
|
|
401
407
|
/// @dev costs the inco fee
|
|
402
408
|
function newEuint256(bytes memory ciphertext, address user) internal returns (euint256) {
|
|
403
|
-
|
|
409
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.newEuint256.selector, ciphertext, user));
|
|
410
|
+
return euint256.wrap(result);
|
|
404
411
|
}
|
|
405
412
|
|
|
406
413
|
/// @notice Creates a new encrypted bool assuming msg.sender is the user
|
|
@@ -412,7 +419,8 @@ library e {
|
|
|
412
419
|
/// @notice Creates a new encrypted bool for the given user.
|
|
413
420
|
/// @dev costs the inco fee
|
|
414
421
|
function newEbool(bytes memory ciphertext, address user) internal returns (ebool) {
|
|
415
|
-
|
|
422
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.newEbool.selector, ciphertext, user));
|
|
423
|
+
return ebool.wrap(result);
|
|
416
424
|
}
|
|
417
425
|
|
|
418
426
|
/// @notice Creates a new encrypted address assuming msg.sender is the user
|
|
@@ -424,7 +432,8 @@ library e {
|
|
|
424
432
|
/// @notice Creates a new encrypted address for the given user.
|
|
425
433
|
/// @dev costs the inco fee
|
|
426
434
|
function newEaddress(bytes memory ciphertext, address user) internal returns (eaddress) {
|
|
427
|
-
|
|
435
|
+
bytes32 result = _callWithFeeRetry(abi.encodeWithSelector(inco.newEaddress.selector, ciphertext, user));
|
|
436
|
+
return eaddress.wrap(result);
|
|
428
437
|
}
|
|
429
438
|
|
|
430
439
|
function allow(euint256 a, address to) internal {
|
|
@@ -479,4 +488,51 @@ library e {
|
|
|
479
488
|
return eaddress.wrap(inco.eIfThenElse(s(control), eaddress.unwrap(s(ifTrue)), eaddress.unwrap(s(ifFalse))));
|
|
480
489
|
}
|
|
481
490
|
|
|
491
|
+
/// @dev slot to store the fee for inco operations
|
|
492
|
+
bytes32 private constant FEE_SLOT = keccak256("inco.fee");
|
|
493
|
+
|
|
494
|
+
/// @dev Store fee in the custom slot
|
|
495
|
+
/// @param _fee The fee to store
|
|
496
|
+
function _setFee(uint256 _fee) private {
|
|
497
|
+
bytes32 slot = FEE_SLOT;
|
|
498
|
+
assembly {
|
|
499
|
+
sstore(slot, _fee)
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/// @dev Retrieve fee from the custom slot
|
|
504
|
+
/// @return fee The stored fee
|
|
505
|
+
function _getFee() private view returns (uint256 fee) {
|
|
506
|
+
bytes32 slot = FEE_SLOT;
|
|
507
|
+
assembly {
|
|
508
|
+
fee := sload(slot)
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/// @dev Get current fee with fallback to inco.getFee() if not cached
|
|
513
|
+
function getCurrentFee() private returns (uint256) {
|
|
514
|
+
uint256 cachedFee = _getFee();
|
|
515
|
+
if (cachedFee == 0) {
|
|
516
|
+
cachedFee = inco.getFee();
|
|
517
|
+
_setFee(cachedFee);
|
|
518
|
+
}
|
|
519
|
+
return cachedFee;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/// @dev Execute a call to inco with fee, retrying with fresh fee if it fails
|
|
523
|
+
/// @param callData The encoded function call (use abi.encodeWithSelector)
|
|
524
|
+
/// @return result The bytes32 result from the call
|
|
525
|
+
function _callWithFeeRetry(bytes memory callData) private returns (bytes32) {
|
|
526
|
+
uint256 fee = getCurrentFee();
|
|
527
|
+
(bool success, bytes memory result) = address(inco).call{value: fee}(callData);
|
|
528
|
+
if (!success) {
|
|
529
|
+
// Fee might be outdated, get fresh fee and retry
|
|
530
|
+
fee = inco.getFee();
|
|
531
|
+
_setFee(fee);
|
|
532
|
+
(success, result) = address(inco).call{value: fee}(callData);
|
|
533
|
+
require(success, CallFailedAfterFeeRefresh());
|
|
534
|
+
}
|
|
535
|
+
return abi.decode(result, (bytes32));
|
|
536
|
+
}
|
|
537
|
+
|
|
482
538
|
}
|