Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 4afb6e6

Browse files
committed
Add timestamp, rename to "multiplier"
1 parent 772f34f commit 4afb6e6

File tree

6 files changed

+282
-102
lines changed

6 files changed

+282
-102
lines changed

token/client/src/token.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ pub enum ExtensionInitializationParams {
191191
},
192192
ScaledUiAmountConfig {
193193
authority: Option<Pubkey>,
194-
scale: f64,
194+
multiplier: f64,
195195
},
196196
}
197197
impl ExtensionInitializationParams {
@@ -322,9 +322,15 @@ impl ExtensionInitializationParams {
322322
authority,
323323
member_address,
324324
),
325-
Self::ScaledUiAmountConfig { authority, scale } => {
326-
scaled_ui_amount::instruction::initialize(token_program_id, mint, authority, scale)
327-
}
325+
Self::ScaledUiAmountConfig {
326+
authority,
327+
multiplier,
328+
} => scaled_ui_amount::instruction::initialize(
329+
token_program_id,
330+
mint,
331+
authority,
332+
multiplier,
333+
),
328334
}
329335
}
330336
}
@@ -1814,23 +1820,25 @@ where
18141820
.await
18151821
}
18161822

1817-
/// Update scale
1818-
pub async fn update_scale<S: Signers>(
1823+
/// Update multiplier
1824+
pub async fn update_multiplier<S: Signers>(
18191825
&self,
18201826
authority: &Pubkey,
1821-
new_scale: f64,
1827+
new_multiplier: f64,
1828+
new_multiplier_effective_timestamp: i64,
18221829
signing_keypairs: &S,
18231830
) -> TokenResult<T::Output> {
18241831
let signing_pubkeys = signing_keypairs.pubkeys();
18251832
let multisig_signers = self.get_multisig_signers(authority, &signing_pubkeys);
18261833

18271834
self.process_ixs(
1828-
&[scaled_ui_amount::instruction::update_scale(
1835+
&[scaled_ui_amount::instruction::update_multiplier(
18291836
&self.program_id,
18301837
self.get_address(),
18311838
authority,
18321839
&multisig_signers,
1833-
new_scale,
1840+
new_multiplier,
1841+
new_multiplier_effective_timestamp,
18341842
)?],
18351843
signing_keypairs,
18361844
)

token/program-2022-test/tests/scaled_ui_amount.rs

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ use {
3333

3434
#[tokio::test]
3535
async fn success_initialize() {
36-
for (scale, authority) in [
36+
for (multiplier, authority) in [
3737
(f64::MIN_POSITIVE, None),
3838
(f64::MAX, Some(Pubkey::new_unique())),
3939
] {
4040
let mut context = TestContext::new().await;
4141
context
4242
.init_token_with_mint(vec![ExtensionInitializationParams::ScaledUiAmountConfig {
4343
authority,
44-
scale,
44+
multiplier,
4545
}])
4646
.await
4747
.unwrap();
@@ -50,42 +50,95 @@ async fn success_initialize() {
5050
let state = token.get_mint_info().await.unwrap();
5151
let extension = state.get_extension::<ScaledUiAmountConfig>().unwrap();
5252
assert_eq!(Option::<Pubkey>::from(extension.authority), authority,);
53-
assert_eq!(f64::from(extension.scale), scale);
53+
assert_eq!(f64::from(extension.multiplier), multiplier);
54+
assert_eq!(f64::from(extension.new_multiplier), multiplier);
55+
assert_eq!(i64::from(extension.new_multiplier_effective_timestamp), 0);
5456
}
5557
}
5658

5759
#[tokio::test]
58-
async fn update_scale() {
60+
async fn fail_initialize_with_interest_bearing() {
61+
let authority = None;
62+
let mut context = TestContext::new().await;
63+
let err = context
64+
.init_token_with_mint(vec![
65+
ExtensionInitializationParams::ScaledUiAmountConfig {
66+
authority,
67+
multiplier: 1.0,
68+
},
69+
ExtensionInitializationParams::InterestBearingConfig {
70+
rate_authority: None,
71+
rate: 0,
72+
},
73+
])
74+
.await
75+
.unwrap_err();
76+
assert_eq!(
77+
err,
78+
TokenClientError::Client(Box::new(TransportError::TransactionError(
79+
TransactionError::InstructionError(
80+
3,
81+
InstructionError::Custom(TokenError::InvalidExtensionCombination as u32)
82+
)
83+
)))
84+
);
85+
}
86+
87+
#[tokio::test]
88+
async fn update_multiplier() {
5989
let authority = Keypair::new();
60-
let initial_scale = 5.0;
90+
let initial_multiplier = 5.0;
6191
let mut context = TestContext::new().await;
6292
context
6393
.init_token_with_mint(vec![ExtensionInitializationParams::ScaledUiAmountConfig {
6494
authority: Some(authority.pubkey()),
65-
scale: initial_scale,
95+
multiplier: initial_multiplier,
6696
}])
6797
.await
6898
.unwrap();
6999
let TokenContext { token, .. } = context.token_context.take().unwrap();
70100

71101
let state = token.get_mint_info().await.unwrap();
72102
let extension = state.get_extension::<ScaledUiAmountConfig>().unwrap();
73-
assert_eq!(f64::from(extension.scale), initial_scale);
103+
assert_eq!(f64::from(extension.multiplier), initial_multiplier);
104+
assert_eq!(f64::from(extension.new_multiplier), initial_multiplier);
74105

75106
// correct
76-
let new_scale = 10.0;
107+
let new_multiplier = 10.0;
108+
token
109+
.update_multiplier(&authority.pubkey(), new_multiplier, 0, &[&authority])
110+
.await
111+
.unwrap();
112+
let state = token.get_mint_info().await.unwrap();
113+
let extension = state.get_extension::<ScaledUiAmountConfig>().unwrap();
114+
assert_eq!(f64::from(extension.multiplier), new_multiplier);
115+
assert_eq!(f64::from(extension.new_multiplier), new_multiplier);
116+
assert_eq!(i64::from(extension.new_multiplier_effective_timestamp), 0);
117+
118+
// correct in the future
119+
let newest_multiplier = 100.0;
77120
token
78-
.update_scale(&authority.pubkey(), new_scale, &[&authority])
121+
.update_multiplier(
122+
&authority.pubkey(),
123+
newest_multiplier,
124+
i64::MAX,
125+
&[&authority],
126+
)
79127
.await
80128
.unwrap();
81129
let state = token.get_mint_info().await.unwrap();
82130
let extension = state.get_extension::<ScaledUiAmountConfig>().unwrap();
83-
assert_eq!(f64::from(extension.scale), new_scale);
131+
assert_eq!(f64::from(extension.multiplier), new_multiplier);
132+
assert_eq!(f64::from(extension.new_multiplier), newest_multiplier);
133+
assert_eq!(
134+
i64::from(extension.new_multiplier_effective_timestamp),
135+
i64::MAX
136+
);
84137

85138
// wrong signer
86139
let wrong_signer = Keypair::new();
87140
let err = token
88-
.update_scale(&wrong_signer.pubkey(), 1.0, &[&wrong_signer])
141+
.update_multiplier(&wrong_signer.pubkey(), 1.0, 0, &[&wrong_signer])
89142
.await
90143
.unwrap_err();
91144
assert_eq!(
@@ -102,12 +155,12 @@ async fn update_scale() {
102155
#[tokio::test]
103156
async fn set_authority() {
104157
let authority = Keypair::new();
105-
let initial_scale = 500.0;
158+
let initial_multiplier = 500.0;
106159
let mut context = TestContext::new().await;
107160
context
108161
.init_token_with_mint(vec![ExtensionInitializationParams::ScaledUiAmountConfig {
109162
authority: Some(authority.pubkey()),
110-
scale: initial_scale,
163+
multiplier: initial_multiplier,
111164
}])
112165
.await
113166
.unwrap();
@@ -132,11 +185,11 @@ async fn set_authority() {
132185
Some(new_authority.pubkey()).try_into().unwrap(),
133186
);
134187
token
135-
.update_scale(&new_authority.pubkey(), 10.0, &[&new_authority])
188+
.update_multiplier(&new_authority.pubkey(), 10.0, 0, &[&new_authority])
136189
.await
137190
.unwrap();
138191
let err = token
139-
.update_scale(&authority.pubkey(), 100.0, &[&authority])
192+
.update_multiplier(&authority.pubkey(), 100.0, 0, &[&authority])
140193
.await
141194
.unwrap_err();
142195
assert_eq!(
@@ -166,7 +219,7 @@ async fn set_authority() {
166219

167220
// now all fail
168221
let err = token
169-
.update_scale(&new_authority.pubkey(), 50.0, &[&new_authority])
222+
.update_multiplier(&new_authority.pubkey(), 50.0, 0, &[&new_authority])
170223
.await
171224
.unwrap_err();
172225
assert_eq!(
@@ -179,7 +232,7 @@ async fn set_authority() {
179232
)))
180233
);
181234
let err = token
182-
.update_scale(&authority.pubkey(), 5.5, &[&authority])
235+
.update_multiplier(&authority.pubkey(), 5.5, 0, &[&authority])
183236
.await
184237
.unwrap_err();
185238
assert_eq!(
@@ -256,11 +309,11 @@ async fn amount_conversions() {
256309
context,
257310
token_context: None,
258311
};
259-
let initial_scale = 5.0;
312+
let initial_multiplier = 5.0;
260313
context
261314
.init_token_with_mint(vec![ExtensionInitializationParams::ScaledUiAmountConfig {
262315
authority: Some(authority.pubkey()),
263-
scale: initial_scale,
316+
multiplier: initial_multiplier,
264317
}])
265318
.await
266319
.unwrap();

token/program-2022/src/extension/scaled_ui_amount/instruction.rs

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
33
use {
44
crate::{
55
check_program_account,
6-
extension::scaled_ui_amount::PodF64,
6+
extension::scaled_ui_amount::{PodF64, UnixTimestamp},
77
instruction::{encode_instruction, TokenInstruction},
88
},
99
bytemuck::{Pod, Zeroable},
@@ -41,23 +41,27 @@ pub enum ScaledUiAmountMintInstruction {
4141
/// Data expected by this instruction:
4242
/// `crate::extension::scaled_ui_amount::instruction::InitializeInstructionData`
4343
Initialize,
44-
/// Update the scale. Only supported for mints that include the
44+
/// Update the multiplier. Only supported for mints that include the
4545
/// `ScaledUiAmount` extension.
4646
///
47+
/// The authority provides a new multiplier and a unix timestamp on which
48+
/// it should take effect. If the timestamp is before the current time,
49+
/// immediately sets the multiplier.
50+
///
4751
/// Accounts expected by this instruction:
4852
///
4953
/// * Single authority
5054
/// 0. `[writable]` The mint.
51-
/// 1. `[signer]` The mint scale authority.
55+
/// 1. `[signer]` The multiplier authority.
5256
///
5357
/// * Multisignature authority
5458
/// 0. `[writable]` The mint.
55-
/// 1. `[]` The mint's multisignature scale authority.
59+
/// 1. `[]` The mint's multisignature multiplier authority.
5660
/// 2. `..2+M` `[signer]` M signer accounts.
5761
///
5862
/// Data expected by this instruction:
59-
/// `crate::extension::scaled_ui_amount::PodF64`
60-
UpdateScale,
63+
/// `crate::extension::scaled_ui_amount::instruction::UpdateMultiplierInstructionData`
64+
UpdateMultiplier,
6165
}
6266

6367
/// Data expected by `ScaledUiAmountMint::Initialize`
@@ -66,18 +70,30 @@ pub enum ScaledUiAmountMintInstruction {
6670
#[derive(Clone, Copy, Pod, Zeroable)]
6771
#[repr(C)]
6872
pub struct InitializeInstructionData {
69-
/// The public key for the account that can update the scale
73+
/// The public key for the account that can update the multiplier
7074
pub authority: OptionalNonZeroPubkey,
71-
/// The initial scale
72-
pub scale: PodF64,
75+
/// The initial multiplier
76+
pub multiplier: PodF64,
77+
}
78+
79+
/// Data expected by `ScaledUiAmountMint::UpdateMultiplier`
80+
#[cfg_attr(feature = "serde-traits", derive(Serialize, Deserialize))]
81+
#[cfg_attr(feature = "serde-traits", serde(rename_all = "camelCase"))]
82+
#[derive(Clone, Copy, Pod, Zeroable)]
83+
#[repr(C)]
84+
pub struct UpdateMultiplierInstructionData {
85+
/// The new multiplier
86+
pub multiplier: PodF64,
87+
/// Timestamp at which the new multiplier will take effect
88+
pub effective_timestamp: UnixTimestamp,
7389
}
7490

7591
/// Create an `Initialize` instruction
7692
pub fn initialize(
7793
token_program_id: &Pubkey,
7894
mint: &Pubkey,
7995
authority: Option<Pubkey>,
80-
scale: f64,
96+
multiplier: f64,
8197
) -> Result<Instruction, ProgramError> {
8298
check_program_account(token_program_id)?;
8399
let accounts = vec![AccountMeta::new(*mint, false)];
@@ -88,18 +104,19 @@ pub fn initialize(
88104
ScaledUiAmountMintInstruction::Initialize,
89105
&InitializeInstructionData {
90106
authority: authority.try_into()?,
91-
scale: scale.into(),
107+
multiplier: multiplier.into(),
92108
},
93109
))
94110
}
95111

96-
/// Create an `UpdateScale` instruction
97-
pub fn update_scale(
112+
/// Create an `UpdateMultiplier` instruction
113+
pub fn update_multiplier(
98114
token_program_id: &Pubkey,
99115
mint: &Pubkey,
100116
authority: &Pubkey,
101117
signers: &[&Pubkey],
102-
scale: f64,
118+
multiplier: f64,
119+
effective_timestamp: i64,
103120
) -> Result<Instruction, ProgramError> {
104121
check_program_account(token_program_id)?;
105122
let mut accounts = vec![
@@ -113,7 +130,10 @@ pub fn update_scale(
113130
token_program_id,
114131
accounts,
115132
TokenInstruction::ScaledUiAmountExtension,
116-
ScaledUiAmountMintInstruction::UpdateScale,
117-
&PodF64::from(scale),
133+
ScaledUiAmountMintInstruction::UpdateMultiplier,
134+
&UpdateMultiplierInstructionData {
135+
effective_timestamp: effective_timestamp.into(),
136+
multiplier: multiplier.into(),
137+
},
118138
))
119139
}

0 commit comments

Comments
 (0)