Skip to content

Commit

Permalink
fix: transfer admin to current contract during setup
Browse files Browse the repository at this point in the history
  • Loading branch information
mootz12 committed May 23, 2024
1 parent 511ebfe commit 214acfc
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 8 deletions.
12 changes: 9 additions & 3 deletions src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,28 @@ pub struct AdminTransfer;

#[contractimpl]
impl AdminTransfer {
/// Set the details for an admin transfer
/// Set the details for an admin transfer. Also sets the admin of the pool to this contract.
/// Must be called by the current admin of the pool.
///
/// ### Arguments
/// * `pool` - The address of the pool the admin transfer is for
/// * `new_admin` - The deadline ledger sequence number of the distribution
/// * `cur_admin` - The current admin of the pool
/// * `new_admin` - The new admin of the pool
///
/// ### Panics
/// * `AdminTransferExists` - If the contract has already been initialized
pub fn set_admin_transfer(e: Env, pool: Address, new_admin: Address) {
pub fn set_admin_transfer(e: Env, pool: Address, cur_admin: Address, new_admin: Address) {
assert_with_error!(
&e,
!storage::has_admin_transfer(&e, &pool),
ContractError::AdminTransferExists
);
cur_admin.require_auth();
storage::extend_instance(&e);

let pool_client = Client::new(&e, &pool);
pool_client.set_admin(&e.current_contract_address());

storage::set_admin_transfer(&e, &pool, &new_admin);
}

Expand Down
70 changes: 65 additions & 5 deletions src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,79 @@ fn test_admin_transfer() {
);

// create admin transfer
let pool_client = PoolClient::new(&env, &pool);
pool_client.mock_all_auths().set_admin(&admin_transfer_id);
admin_transfer_client.set_admin_transfer(&pool, &new_admin);
admin_transfer_client
.mock_auths(&[MockAuth {
address: &admin,
invoke: &MockAuthInvoke {
contract: &admin_transfer_id,
fn_name: &"set_admin_transfer",
args: vec![
&env,
pool.clone().into_val(&env),
admin.clone().into_val(&env),
new_admin.clone().into_val(&env),
],
sub_invokes: &[MockAuthInvoke {
contract: &pool,
fn_name: &"set_admin",
args: vec![&env, admin_transfer_id.clone().into_val(&env)],
sub_invokes: &[],
}],
},
}])
.set_admin_transfer(&pool, &admin, &new_admin);

// -> validate auths
assert_eq!(env.auths().len(), 0);
assert_eq!(
env.auths()[0],
(
admin.clone(),
AuthorizedInvocation {
function: AuthorizedFunction::Contract((
admin_transfer_id.clone(),
Symbol::new(&env, "set_admin_transfer"),
vec![
&env,
pool.clone().into_val(&env),
admin.clone().into_val(&env),
new_admin.clone().into_val(&env),
]
)),
sub_invocations: std::vec![AuthorizedInvocation {
function: AuthorizedFunction::Contract((
pool.clone(),
Symbol::new(&env, "set_admin"),
vec![&env, admin_transfer_id.clone().into_val(&env),]
)),
sub_invocations: std::vec![]
}]
}
)
);

// -> validate chain state
let result = admin_transfer_client.get_admin_transfer(&pool);
assert_eq!(result, Some(new_admin.clone()));

// -> validate admin is no longer the admin
let pool_client = PoolClient::new(&env, &pool);
let result = pool_client
.mock_auths(&[MockAuth {
address: &admin,
invoke: &MockAuthInvoke {
contract: &pool,
fn_name: &"set_status",
args: vec![&env, 4u32.into_val(&env)],
sub_invokes: &[],
},
}])
.try_set_status(&4);
assert!(result.is_err());

// validate another admin transfer cannot be created
let result = admin_transfer_client.try_set_admin_transfer(&pool, &sauron);
let result = admin_transfer_client
.mock_all_auths()
.try_set_admin_transfer(&pool, &admin, &sauron);
assert_eq!(
result.err(),
Some(Ok(Error::from_contract_error(
Expand Down

0 comments on commit 214acfc

Please sign in to comment.