Skip to content

Commit

Permalink
chore(merge): merge branch 'main'
Browse files Browse the repository at this point in the history
  • Loading branch information
palace22 committed Jun 5, 2024
2 parents 4a91783 + d0a9714 commit 11129b1
Show file tree
Hide file tree
Showing 8 changed files with 302 additions and 21 deletions.
16 changes: 15 additions & 1 deletion src/chains/evm/common/utils/contract.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getContract } from "viem";
import { BaseError, ContractFunctionRevertedError, getContract } from "viem";

import { ChainType } from "../../../../common/types/chain.js";
import { convertFromGenericAddress } from "../../../../common/utils/address.js";
Expand Down Expand Up @@ -69,3 +69,17 @@ export function getCCIPDataAdapterContract(
client: { public: provider },
});
}

export function extractRevertErrorName(err: unknown): string | undefined {
if (err instanceof BaseError) {
const revertError = err.walk(
(err) => err instanceof ContractFunctionRevertedError,
);
if (
revertError instanceof ContractFunctionRevertedError &&
revertError.data?.errorName
) {
return revertError.data.errorName;
}
}
}
28 changes: 26 additions & 2 deletions src/chains/evm/common/utils/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,12 @@ export function buildEvmMessageData(
]);
}
case Action.Repay: {
throw new Error("Not implemented yet: Action.Repay case");
return concat([
data.loanId,
convertNumberToBytes(data.poolId, UINT8_LENGTH),
convertNumberToBytes(data.amount, UINT256_LENGTH),
convertNumberToBytes(data.maxOverRepayment, UINT256_LENGTH),
]);
}
case Action.RepayWithCollateral: {
throw new Error("Not implemented yet: Action.RepayWithCollateral case");
Expand Down Expand Up @@ -390,7 +395,26 @@ export function buildEvmMessageToSend(
return message;
}
case Action.Repay: {
throw new Error("Not implemented yet: Action.Repay case");
const message: MessageToSend = {
params,
sender,
destinationChainId,
handler,
payload: buildMessagePayload(
Action.Repay,
accountId,
getRandomGenericAddress(),
data,
),
finalityLevel: FINALITY.FINALISED,
extraArgs: buildSendTokenExtraArgsWhenAdding(
extraArgs.tokenType,
extraArgs.spokeTokenAddress,
extraArgs.hubPoolAddress,
extraArgs.amount,
),
};
return message;
}
case Action.RepayWithCollateral: {
throw new Error("Not implemented yet: Action.RepayWithCollateral case");
Expand Down
19 changes: 13 additions & 6 deletions src/chains/evm/hub/modules/folks-hub-account.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { multicall } from "viem/actions";

import { getFolksChainIdsByNetwork } from "../../../../common/utils/chain.js";
import { extractRevertErrorName } from "../../common/utils/contract.js";
import { getHubChain } from "../utils/chain.js";
import { getAccountManagerContract } from "../utils/contract.js";

Expand Down Expand Up @@ -117,16 +118,22 @@ export async function getAccountIdByAddressOnChain(
network: NetworkType,
address: GenericAddress,
folksChainId: FolksChainId,
): Promise<AccountId> {
): Promise<AccountId | null> {
const hubChain = getHubChain(network);
const accountManager = getAccountManagerContract(
provider,
hubChain.accountManagerAddress,
);

const accountId = await accountManager.read.getAccountIdOfAddressOnChain([
address,
folksChainId,
]);
return accountId as AccountId;
try {
const accountId = await accountManager.read.getAccountIdOfAddressOnChain([
address,
folksChainId,
]);
return accountId as AccountId;
} catch (err: unknown) {
const errorName = extractRevertErrorName(err);
if (errorName === "NoAccountRegisteredTo") return null;
throw err;
}
}
80 changes: 80 additions & 0 deletions src/chains/evm/spoke/modules/folks-evm-loan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import type {
PrepareCreateLoanCall,
PrepareDeleteLoanCall,
PrepareDepositCall,
PrepareRepayCall,
PrepareWithdrawCall,
} from "../../common/types/module.js";
import type { TokenRateLimit } from "../types/pool.js";
Expand Down Expand Up @@ -254,6 +255,47 @@ export const prepare = {
spokeCommonAddress,
};
},

async repay(
provider: Client,
sender: EvmAddress,
messageToSend: MessageToSend,
accountId: AccountId,
loanId: LoanId,
amount: bigint,
maxOverRepayment: bigint,
spokeChain: SpokeChain,
spokeTokenData: SpokeTokenData,
transactionOptions: EstimateGasParameters = { account: sender },
): Promise<PrepareRepayCall> {
const spokeToken = getSpokeTokenContract(
provider,
spokeTokenData.spokeAddress,
);
const bridgeRouter = getBridgeRouterSpokeContract(
provider,
spokeChain.bridgeRouterAddress,
);

// get adapter fees
const msgValue = await bridgeRouter.read.getSendFee([messageToSend]);

// get gas limits
const gasLimit = await spokeToken.estimateGas.repay(
[messageToSend.params, accountId, loanId, amount, maxOverRepayment],
{
value: msgValue,
...transactionOptions,
},
);

return {
msgValue,
gasLimit,
messageParams: messageToSend.params,
token: spokeTokenData,
};
},
};

export const write = {
Expand Down Expand Up @@ -426,6 +468,44 @@ export const write = {
},
);
},

async repay(
provider: Client,
signer: WalletClient,
accountId: AccountId,
loanId: LoanId,
amount: bigint,
maxOverRepayment: bigint,
includeApprove = true,
prepareCall: PrepareRepayCall,
) {
const { msgValue, gasLimit, messageParams, token } = prepareCall;

const spokeToken = getSpokeTokenContract(
provider,
token.spokeAddress,
signer,
);

if (includeApprove && token.tokenType !== TokenType.NATIVE)
await sendERC20Approve(
provider,
token.spokeAddress,
signer,
spokeToken.address as EvmAddress,
amount,
);

return await spokeToken.write.repay(
[messageParams, accountId, loanId, amount, maxOverRepayment],
{
account: getEvmSignerAccount(signer),
chain: signer.chain,
gasLimit: gasLimit,
value: msgValue,
},
);
},
};

export const read = {
Expand Down
24 changes: 22 additions & 2 deletions src/common/types/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@ export type BorrowMessageData = {
maxStableRate: bigint;
};

export type RepayMessageData = {
loanId: LoanId;
poolId: number;
amount: bigint;
maxOverRepayment: bigint;
};

// Extra args
export type DefaultExtraArgs = "0x";

Expand All @@ -126,6 +133,13 @@ export type DepositExtraArgs = {
amount: bigint;
};

export type RepayExtraArgs = {
tokenType: TokenType;
spokeTokenAddress: GenericAddress;
hubPoolAddress: GenericAddress;
amount: bigint;
};

// Params
export type DefaultMessageDataParams = {
action:
Expand All @@ -134,7 +148,6 @@ export type DefaultMessageDataParams = {
| Action.RemoveDelegate
| Action.DepositFToken
| Action.WithdrawFToken
| Action.Repay
| Action.RepayWithCollateral
| Action.Liquidate
| Action.SwitchBorrowType
Expand Down Expand Up @@ -193,6 +206,12 @@ export type BorrowMessageDataParams = {
extraArgs: DefaultExtraArgs;
};

export type RepayMessageDataParams = {
action: Action.Repay;
data: RepayMessageData;
extraArgs: RepayExtraArgs;
};

export type MessageDataParams =
| DefaultMessageDataParams
| CreateAccountMessageDataParams
Expand All @@ -202,7 +221,8 @@ export type MessageDataParams =
| DeleteLoanMessageDataParams
| DepositMessageDataParams
| WithdrawMessageDataParams
| BorrowMessageDataParams;
| BorrowMessageDataParams
| RepayMessageDataParams;

export type MessageBuilderParams = {
userAddress: GenericAddress;
Expand Down
2 changes: 2 additions & 0 deletions src/common/types/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
PrepareWithdrawCall as PrepareWithdrawEVMCall,
PrepareCall as PrepareEVMCall,
PrepareBorrowCall as PrepareBorrowEVMCall,
PrepareRepayCall as PrepareRepayEVMCall,
} from "../../chains/evm/common/types/module.js";

export enum LoanType {
Expand All @@ -28,3 +29,4 @@ export type PrepareDeleteLoanCall = PrepareDeleteLoanEVMCall;
export type PrepareDepositCall = PrepareDepositEVMCall;
export type PrepareWithdrawCall = PrepareWithdrawEVMCall;
export type PrepareBorrowCall = PrepareBorrowEVMCall;
export type PrepareRepayCall = PrepareRepayEVMCall;
2 changes: 1 addition & 1 deletion src/xchain/modules/folks-account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ export const read = {
async accountIdByAddressOnChain(
address: GenericAddress,
folksChainId: FolksChainId,
): Promise<AccountId> {
): Promise<AccountId | null> {
return FolksHubAccount.getAccountIdByAddressOnChain(
FolksCore.getHubProvider(),
FolksCore.getSelectedNetwork(),
Expand Down
Loading

0 comments on commit 11129b1

Please sign in to comment.