Skip to content

Commit 5339724

Browse files
authored
Merge pull request #163 from m0-foundation/proto-337-adevar-anyone-can-redeem-bridge-to-portal-m-token-account
PROTO-337: HAL-01 (H): anyone can redeem bridge to portal m token account
2 parents 3dc5fc1 + b13e42d commit 5339724

File tree

4 files changed

+69
-15
lines changed

4 files changed

+69
-15
lines changed

programs/portal/src/instructions/release_inbound.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,22 @@ pub struct ReleaseInboundArgs {
7474
pub fn release_inbound_mint<'info>(
7575
ctx: Context<'_, '_, '_, 'info, ReleaseInboundMint<'info>>,
7676
args: ReleaseInboundArgs,
77+
) -> Result<()> {
78+
release_inbound_mint_common(ctx, args, false)
79+
}
80+
81+
pub fn release_inbound_mint_common<'info>(
82+
ctx: Context<'_, '_, '_, 'info, ReleaseInboundMint<'info>>,
83+
args: ReleaseInboundArgs,
84+
release_extension: bool,
7785
) -> Result<()> {
7886
let inbox_item = &mut ctx.accounts.inbox_item;
7987

8088
// Validate token account depending on call context
8189
validate_recipient_token_account(
8290
&ctx.accounts.recipient.key(),
8391
&inbox_item,
92+
release_extension,
8493
&ctx.accounts.token_authority.key(),
8594
&ctx.accounts.mint.key(),
8695
&ctx.accounts.token_program.key(),
@@ -179,13 +188,14 @@ pub fn release_inbound_mint<'info>(
179188
fn validate_recipient_token_account(
180189
recipient: &Pubkey,
181190
inbox_item: &InboxItem,
191+
is_extension: bool,
182192
token_authority: &Pubkey,
183193
m_mint: &Pubkey,
184194
token_program: &Pubkey,
185195
) -> Result<()> {
186196
let expected = get_inbox_recipient_token_account(
187197
&inbox_item.transfer.recipient,
188-
&inbox_item.destination_mint,
198+
is_extension,
189199
inbox_item.transfer.amount,
190200
token_authority,
191201
m_mint,
@@ -201,7 +211,7 @@ fn validate_recipient_token_account(
201211

202212
pub fn get_inbox_recipient_token_account(
203213
recipient: &Pubkey,
204-
destination_mint: &Pubkey,
214+
is_extension: bool,
205215
amount: u64,
206216
token_authority: &Pubkey,
207217
m_mint: &Pubkey,
@@ -212,18 +222,16 @@ pub fn get_inbox_recipient_token_account(
212222
return None;
213223
}
214224

215-
// Bridging to extension, require intermediate portal token account
216-
if !destination_mint.eq(m_mint) {
217-
return Some(get_associated_token_address_with_program_id(
218-
token_authority,
219-
m_mint,
220-
token_program,
221-
));
222-
}
225+
let authority = if is_extension {
226+
// Bridging to extension, require intermediate portal token account
227+
token_authority
228+
} else {
229+
// Bridging $M, require user token account
230+
recipient
231+
};
223232

224-
// Bridging $M, require user token account
225233
Some(get_associated_token_address_with_program_id(
226-
&recipient,
234+
&authority,
227235
m_mint,
228236
token_program,
229237
))

programs/portal/src/instructions/release_inbound_extension.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use earn::state::GLOBAL_SEED;
44
use ext_swap::accounts::SwapGlobal;
55
use ext_swap::program::ExtSwap;
66

7-
use crate::instructions::{ext_swap, release_inbound_mint};
7+
use crate::instructions::{ext_swap, release_inbound_mint_common};
88
use crate::instructions::{ReleaseInboundArgs, ReleaseInboundMint};
99
use crate::ReleaseInboundMintBumps;
1010
use crate::__client_accounts_release_inbound_mint;
@@ -94,7 +94,7 @@ pub fn release_inbound_mint_extension<'info>(
9494
let token_auth_bump = ctx.bumps.common.token_authority;
9595

9696
// Release bridged $M
97-
release_inbound_mint(
97+
release_inbound_mint_common(
9898
Context::new(
9999
ctx.program_id,
100100
&mut ctx.accounts.common,
@@ -108,6 +108,7 @@ pub fn release_inbound_mint_extension<'info>(
108108
// always revert on delay or wrap will fail
109109
revert_when_not_ready: true,
110110
},
111+
true,
111112
)?;
112113

113114
ctx.accounts.common.recipient.reload()?;

programs/portal/src/instructions/resolve_execute.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ pub fn resolve_execute_vaa_v1<'a>(
312312

313313
let recipient = get_inbox_recipient_token_account(
314314
&ntt_recipient,
315-
&destination_mint,
315+
!destination_mint.eq(&config_data.mint),
316316
amount,
317317
&token_auth,
318318
&config_data.mint,

tests/unit/portal.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,51 @@ describe('Portal unit tests', () => {
11141114
expect(extParsedTokenAccount.amount).toBe(9198n);
11151115
});
11161116

1117+
it('extension tokens - redeem to portal authority', async () => {
1118+
const [portalAuth] = PublicKey.findProgramAddressSync([Buffer.from('token_authority')], config.PORTAL_PROGRAM_ID);
1119+
1120+
const getRedeemTxns = redeem(
1121+
[],
1122+
undefined,
1123+
true,
1124+
undefined,
1125+
true, // skip release ix
1126+
);
1127+
1128+
await ssw(ctx, getRedeemTxns(), signer);
1129+
1130+
// try to release to portal authority
1131+
const ix = await NTT.createReleaseInboundMintInstruction(ntt.program, await ntt.getConfig(), {
1132+
payer: payer.publicKey,
1133+
nttMessage: payload,
1134+
recipient: portalAuth,
1135+
chain: 'Ethereum',
1136+
revertOnDelay: false,
1137+
});
1138+
1139+
// add additional keys required for portal CPI
1140+
ix.keys.push(
1141+
{
1142+
pubkey: config.EARN_PROGRAM,
1143+
isSigner: false,
1144+
isWritable: false,
1145+
},
1146+
{
1147+
pubkey: config.EARN_GLOBAL_ACCOUNT,
1148+
isSigner: false,
1149+
isWritable: true,
1150+
},
1151+
);
1152+
1153+
const tx = new Transaction().add(ix);
1154+
tx.feePayer = payer.publicKey;
1155+
tx.recentBlockhash = svm.latestBlockhash();
1156+
tx.sign(payer);
1157+
1158+
const result = svm.sendTransaction!(tx) as FailedTransactionMetadata;
1159+
expect(result.meta().logs()[2]).toContain('Error Code: InvalidRecipientAddress');
1160+
});
1161+
11171162
it('tokens with merkle roots', async () => {
11181163
const additionalPayload = Buffer.concat([
11191164
new BN(123456).toArrayLike(Buffer, 'be', 8), // index

0 commit comments

Comments
 (0)