Skip to content

Commit

Permalink
gas optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
code-z2 committed Oct 19, 2024
1 parent adc19f9 commit 2c098f4
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 68 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.1.6

* Remove repetated function call in safe plugin
* Split gas overrides individually
* Change point of gas override

## 0.1.5

* improve gas fees estimation
Expand Down
138 changes: 73 additions & 65 deletions lib/src/4337/wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,61 +85,66 @@ class SmartWallet with _PluginManager, _GasSettings implements SmartWalletBase {
UserOperation buildUserOperation({
required Uint8List callData,
BigInt? customNonce,
}) =>
UserOperation.partial(
callData: callData,
initCode: _initCode,
sender: _walletAddress,
nonce: customNonce);
}) {
return UserOperation.partial(
callData: callData,
initCode: _initCode,
sender: _walletAddress,
nonce: customNonce);
}

@override
Future<UserOperationResponse> send(
EthereumAddress recipient, EtherAmount amount) =>
sendUserOperation(buildUserOperation(
callData: Contract.execute(_walletAddress,
to: recipient, amount: amount, isSafe: isSafe)));
EthereumAddress recipient, EtherAmount amount) {
final cd = Contract.execute(_walletAddress,
to: recipient, amount: amount, isSafe: isSafe);
return sendUserOperation(buildUserOperation(callData: cd));
}

@override
Future<UserOperationResponse> sendTransaction(
EthereumAddress to, Uint8List encodedFunctionData,
{EtherAmount? amount}) =>
sendUserOperation(buildUserOperation(
callData: Contract.execute(_walletAddress,
to: to,
amount: amount,
innerCallData: encodedFunctionData,
isSafe: isSafe)));
EthereumAddress to, Uint8List encodedFunctionData,
{EtherAmount? amount}) {
final cd = Contract.execute(_walletAddress,
to: to,
amount: amount,
innerCallData: encodedFunctionData,
isSafe: isSafe);
return sendUserOperation(buildUserOperation(callData: cd));
}

@override
Future<UserOperationResponse> sendBatchedTransaction(
List<EthereumAddress> recipients, List<Uint8List> calls,
{List<EtherAmount>? amounts}) {
Uint8List cd;
if (isSafe) {
final innerCall = plugin<_SafePlugin>('safe')
.getSafeMultisendCallData(recipients, amounts, calls);
return sendUserOperation(buildUserOperation(
callData: Contract.executeBatch(
walletAddress: _walletAddress,
recipients: [Constants.safeMultiSendaddress],
amounts: [],
innerCalls: [innerCall],
isSafe: true)));
cd = Contract.executeBatch(
walletAddress: _walletAddress,
recipients: [Constants.safeMultiSendaddress],
amounts: [],
innerCalls: [innerCall],
isSafe: true);
return sendUserOperation(buildUserOperation(callData: cd));
} else {
return sendUserOperation(buildUserOperation(
callData: Contract.executeBatch(
walletAddress: _walletAddress,
recipients: recipients,
amounts: amounts,
innerCalls: calls)));
cd = Contract.executeBatch(
walletAddress: _walletAddress,
recipients: recipients,
amounts: amounts,
innerCalls: calls);
return sendUserOperation(buildUserOperation(callData: cd));
}
}

@override
Future<UserOperationResponse> sendSignedUserOperation(UserOperation op) =>
plugin<BundlerProviderBase>('bundler')
.sendUserOperation(
op.toMap(_chain.entrypoint.version), _chain.entrypoint)
.catchError((e) => throw SendError(e.toString(), op));
Future<UserOperationResponse> sendSignedUserOperation(UserOperation op) {
return plugin<BundlerProviderBase>('bundler')
.sendUserOperation(
op.toMap(_chain.entrypoint.version), _chain.entrypoint)
.catchError((e) => throw SendError(e.toString(), op));
}

@override
Future<UserOperationResponse> sendUserOperation(UserOperation op) =>
Expand Down Expand Up @@ -198,39 +203,41 @@ class SmartWallet with _PluginManager, _GasSettings implements SmartWalletBase {
/// Otherwise, retrieves the nonce by calling the 'getNonce' function on the entrypoint.
///
/// If an error occurs during the nonce retrieval process, a [NonceError] exception is thrown.
Future<Uint256> _getNonce() => isDeployed.then((deployed) => !deployed
? Future.value(Uint256.zero)
: plugin<Contract>("contract")
.read(_chain.entrypoint.address, ContractAbis.get('getNonce'),
"getNonce",
params: [_walletAddress, BigInt.zero])
.then((value) => Uint256(value[0]))
.catchError((e) => throw NonceError(e.toString(), _walletAddress)));
Future<Uint256> _getNonce() {
return isDeployed.then((deployed) => !deployed
? Future.value(Uint256.zero)
: plugin<Contract>("contract")
.read(_chain.entrypoint.address, ContractAbis.get('getNonce'),
"getNonce",
params: [_walletAddress, BigInt.zero])
.then((value) => Uint256(value[0]))
.catchError((e) => throw NonceError(e.toString(), _walletAddress)));
}

/// Returns the balance for the Smart Wallet address.
///
/// If an error occurs during the balance retrieval process, a [FetchBalanceError] exception is thrown.
Future<EtherAmount> _getBalance() => plugin<Contract>("contract")
.getBalance(_walletAddress)
.catchError((e) => throw FetchBalanceError(e.toString(), _walletAddress));
Future<EtherAmount> _getBalance() {
return plugin<Contract>("contract").getBalance(_walletAddress).catchError(
(e) => throw FetchBalanceError(e.toString(), _walletAddress));
}

/// Updates the user operation with the latest nonce and gas prices.
///
/// [op] is the user operation to update.
///
/// Returns a [Future] that resolves to the updated [UserOperation] object.
Future<UserOperation> _updateUserOperation(UserOperation op) =>
Future.wait<dynamic>([
_getNonce(),
plugin<JsonRPCProviderBase>('jsonRpc').getGasPrice()
]).then((responses) {
op = op.copyWith(
nonce: op.nonce > BigInt.zero ? op.nonce : responses[0].value,
initCode: responses[0] > Uint256.zero ? Uint8List(0) : null,
signature: dummySignature);

return _updateUserOperationGas(op, responses[1]);
});
Future<UserOperation> _updateUserOperation(UserOperation op) async {
final responses = await Future.wait<dynamic>(
[_getNonce(), plugin<JsonRPCProviderBase>('jsonRpc').getGasPrice()]);

op = op.copyWith(
nonce: op.nonce > BigInt.zero ? op.nonce : responses[0].value,
initCode: responses[0] > Uint256.zero ? Uint8List(0) : null,
signature: dummySignature);

return _updateUserOperationGas(op, responses[1]);
}

/// Updates the gas information for the user operation.
///
Expand All @@ -240,10 +247,11 @@ class SmartWallet with _PluginManager, _GasSettings implements SmartWalletBase {
/// Returns a [Future] that resolves to the updated [UserOperation] object.
///
/// If an error occurs during the gas estimation process, a [GasEstimationError] exception is thrown.
Future<UserOperation> _updateUserOperationGas(UserOperation op, Fee fee) =>
plugin<BundlerProviderBase>('bundler')
.estimateUserOperationGas(
op.toMap(_chain.entrypoint.version), _chain.entrypoint)
.then((opGas) => op.updateOpGas(opGas, fee))
.catchError((e) => throw GasEstimationError(e.toString(), op));
Future<UserOperation> _updateUserOperationGas(UserOperation op, Fee fee) {
return plugin<BundlerProviderBase>('bundler')
.estimateUserOperationGas(
op.toMap(_chain.entrypoint.version), _chain.entrypoint)
.then((opGas) => op.updateOpGas(opGas, fee))
.catchError((e) => throw GasEstimationError(e.toString(), op));
}
}
7 changes: 5 additions & 2 deletions lib/src/common/factories.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,17 @@ class _SafeProxyFactory extends SafeProxyFactory
final setup = {
"owners": owners.toList(),
"threshold": BigInt.from(threshold),
"to": module.setup,
"data": encodeModuleSetup(),
"to": null,
"data": null,
"fallbackHandler": module.address,
};

if (encodeWebauthnSetup != null) {
setup["to"] = Constants.safeMultiSendaddress;
setup["data"] = encodeWebauthnSetup(encodeModuleSetup);
} else {
setup["to"] = module.setup;
setup["data"] = encodeModuleSetup();
}

return Contract.encodeFunctionCall(
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: variance_dart
description: An Account Abstraction (4337) Development kit, for quickly building mobile web3 apps and smart wallets.
version: 0.1.5
version: 0.1.6
documentation: https://docs.variance.space
homepage: https://variance.space
repository: https://github.com/vaariance/variance-dart
Expand Down

0 comments on commit 2c098f4

Please sign in to comment.