diff --git a/src/methods/boost/transactions/lock/common.ts b/src/methods/boost/transactions/lock/common.ts
index 12414b63..37a8984d 100644
--- a/src/methods/boost/transactions/lock/common.ts
+++ b/src/methods/boost/transactions/lock/common.ts
@@ -1,4 +1,4 @@
-import { ZeroAddress } from 'ethers'
+import { MaxUint256, ZeroAddress } from 'ethers'
import type { LockInput } from './types'
import { validateArgs } from '../../../../utils'
@@ -14,12 +14,19 @@ type CommonLogicInput = LockInput & {
export const commonLogic = async (values: CommonLogicInput) => {
const {
contracts, options, provider, amount, vaultAddress, userAddress, referrerAddress = ZeroAddress,
- permitParams, mockPermitSignature,
+ mockPermitSignature,
} = values
validateArgs.bigint({ amount })
validateArgs.address({ vaultAddress, userAddress, referrerAddress })
+ const code = await provider.getCode(userAddress)
+ const isMultiSig = code !== '0x'
+
+ let multiSigData = null
+
+ const permitParams = isMultiSig ? null : values.permitParams
+
if (permitParams) {
validateArgs.object({ permitParams })
@@ -66,7 +73,15 @@ export const commonLogic = async (values: CommonLogicInput) => {
const isPermitRequired = allowance < amount
if (isPermitRequired) {
- if (mockPermitSignature) {
+ // It is hard to make permit action for MultiSig e.g. Safe wallet,
+ // so we need to use approve instead
+ if (isMultiSig) {
+ multiSigData = {
+ contract: contracts.tokens.mintToken,
+ approveArgs: [ strategyProxy, MaxUint256 ] as [ string, bigint ],
+ }
+ }
+ else if (mockPermitSignature) {
params.push({
method: 'permit',
args: [
@@ -105,9 +120,12 @@ export const commonLogic = async (values: CommonLogicInput) => {
})
return {
- ...multicallArgs,
- request: {
- params,
+ multiSigData,
+ multicallArgs: {
+ ...multicallArgs,
+ request: {
+ params,
+ },
},
}
}
diff --git a/src/methods/boost/transactions/lock/index.ts b/src/methods/boost/transactions/lock/index.ts
index c99dac8a..7dbe3069 100644
--- a/src/methods/boost/transactions/lock/index.ts
+++ b/src/methods/boost/transactions/lock/index.ts
@@ -6,7 +6,18 @@ import { boostMulticall } from '../../../../contracts'
const lock: Lock = async (values) => {
- const multicallArgs = await commonLogic(values)
+ const { provider, userAddress } = values
+
+ const { multiSigData, multicallArgs } = await commonLogic(values)
+
+ if (multiSigData) {
+ const signer = await provider.getSigner(userAddress)
+ const signedContract = multiSigData.contract.connect(signer)
+
+ const { hash } = await signedContract.approve(...multiSigData.approveArgs)
+
+ await provider.waitForTransaction(hash)
+ }
const result = await boostMulticall<{ hash: string }>(multicallArgs)
diff --git a/src/methods/boost/transactions/lock/lock.md b/src/methods/boost/transactions/lock/lock.md
index cd2d9e21..76c9f48c 100644
--- a/src/methods/boost/transactions/lock/lock.md
+++ b/src/methods/boost/transactions/lock/lock.md
@@ -9,14 +9,14 @@ Boost your osToken apy using leverage staking
#### Arguments:
-| Name | Type | Required | Description |
-|-----------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| amount | `bigint` | **Yes** | Boost amount |
-| userAddress | `string` | **Yes** | The user address |
-| vaultAddress | `string` | **Yes** | The address of the vault that will mint osTokens for leverage staking |
-| boostAddress | `string` | **Yes** | The address of the strategy proxy (TODO method) |
-| referrerAddress | `string` | **No** | The address of the referrer |
-| permitParams | `PermitParams` | **No** | The permit signature it is required only if there is not enough osToken allowance for the strategy proxy contract. It will be obtained automatically using the [utils.getPermitSignature](/utils/getpermitsignature) method |
+| Name | Type | Required | Description |
+|-----------------|----------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| amount | `bigint` | **Yes** | Boost amount |
+| userAddress | `string` | **Yes** | The user address |
+| vaultAddress | `string` | **Yes** | The address of the vault that will mint osTokens for leverage staking |
+| boostAddress | `string` | **Yes** | The address of the strategy proxy using the [sdk.boost.getLeverageStrategyProxy](/boost/requests/getleveragestrategyproxy) method |
+| referrerAddress | `string` | **No** | The address of the referrer |
+| permitParams | `PermitParams` | **No** | The permit signature is required if there isn’t enough osToken allowance for the strategy proxy contract.
**For MultiSig**
The permit signature is not necessary for Multi Sig (e.g. Safe Wallet), as it should use `sdk.contracts.mintToken.approve(boostAddress, MaxUint256)` instead of a permit call to set up osToken allowance. This will be called in the action if needed.
**For other wallets**
The permit signature is optional since it will be obtained automatically using the [utils.getPermitSignature](/utils/getpermitsignature) method. |
```ts
type PermitParams = {
@@ -42,7 +42,10 @@ const params = {
// Send transaction
const hash = await sdk.boost.lock(params)
// When you sign transactions on the backend (for custodians)
-const { data, to, value } = await sdk.boost.lock.encode(params)
+// `lockTxData` will always be returned, while `approveTxData` will only be returned for MultiSig e.g. Safe Wallet
+// if there isn’t enough osToken allowance, otherwise it will be null
+const { lockTxData, approveTxData } = await sdk.boost.lock.encode(params)
+
// Get an approximate gas per transaction
const gas = await sdk.boost.lock.estimateGas(params)
```
diff --git a/src/methods/boost/transactions/lock/lockEncode.ts b/src/methods/boost/transactions/lock/lockEncode.ts
index 6e9d4a1d..32187000 100644
--- a/src/methods/boost/transactions/lock/lockEncode.ts
+++ b/src/methods/boost/transactions/lock/lockEncode.ts
@@ -3,16 +3,31 @@ import { commonLogic } from './common'
import { boostMulticall } from '../../../../contracts'
-const lockEncode = async (values: LockInput): Promise => {
- const multicallArgs = await commonLogic(values)
+type Output = {
+ lockTxData: StakeWise.TransactionData
+ approveTxData: StakeWise.TransactionData | null
+}
+
+const lockEncode = async (values: LockInput): Promise