Skip to content

Commit

Permalink
fix: make functions #[payable] (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
mitinarseny authored Nov 5, 2024
1 parent 894b00f commit 1e74de8
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 8 deletions.
47 changes: 42 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use near_sdk::serde::{Deserialize, Serialize};
use near_sdk::serde_json::{json, Value};
use near_sdk::store::IterableMap;
use near_sdk::{
env, ext_contract, near, require, AccountId, Gas, NearToken, PanicOnDefault, Promise,
PromiseResult, PublicKey,
assert_one_yocto, env, ext_contract, near, require, AccountId, Gas, NearToken, PanicOnDefault,
Promise, PromiseResult, PublicKey,
};

use crate::event::Event;
Expand Down Expand Up @@ -116,7 +116,9 @@ impl AuroraControllerFactory {

/// Attaches new full access key to the controller contract.
#[access_control_any(roles(Role::DAO))]
#[payable]
pub fn attach_full_access_key(&mut self, public_key: PublicKey) -> Promise {
assert_one_yocto();
event::emit(
Event::AttachFullAccessKey,
&json!({"public_key": &public_key}),
Expand All @@ -126,21 +128,30 @@ impl AuroraControllerFactory {

/// Delegates an execution of actions to the specified receiver.
#[access_control_any(roles(Role::DAO))]
#[payable]
pub fn delegate_execution(
&self,
&mut self,
receiver_id: AccountId,
actions: Vec<FunctionCallArgs>,
) -> Promise {
require!(
!env::attached_deposit().is_zero(),
"required at least 1 yoctonear",
);
event::emit(
Event::DelegatedExecution,
&json!({
"receiver_id": &receiver_id,
"actions": &actions
}),
);
let mut total = env::attached_deposit();
actions
.into_iter()
.fold(Promise::new(receiver_id), |promise, action| {
total = total
.checked_sub(action.amount)
.unwrap_or_else(|| env::panic_str("not enough deposit attached"));
promise.function_call(
action.function_name,
action.arguments.into(),
Expand All @@ -152,11 +163,13 @@ impl AuroraControllerFactory {

/// Pauses the contract with provided account id.
#[access_control_any(roles(Role::DAO, Role::Pauser))]
#[payable]
pub fn delegate_pause(
&self,
&mut self,
receiver_id: AccountId,
pause_method_name: Option<String>,
) -> Promise {
assert_one_yocto();
let function_name = match pause_method_name {
Some(method) if ALLOWED_PAUSE_METHODS.contains(&method.as_str()) => method,
Some(method) => panic!("pause method: {method} is not allowed"),
Expand All @@ -177,6 +190,7 @@ impl AuroraControllerFactory {

/// Adds new contract release info.
#[access_control_any(roles(Role::DAO))]
#[payable]
pub fn add_release_info(
&mut self,
hash: String,
Expand All @@ -185,6 +199,7 @@ impl AuroraControllerFactory {
downgrade_hash: Option<String>,
description: Option<String>,
) {
assert_one_yocto();
require!(
self.releases.get(&hash).is_none(),
"release info for the hash is already exist"
Expand All @@ -207,7 +222,9 @@ impl AuroraControllerFactory {
}

/// Adds bytes of the contract smart contract to the corresponding release info.
#[payable]
pub fn add_release_blob(&mut self) {
assert_one_yocto();
let blob = env::input().unwrap_or_else(|| panic!("no blob's bytes were provided"));
let hash = utils::hash_256(&blob);
let release_info = self.releases.get_mut(&hash).unwrap_or_else(|| {
Expand All @@ -222,7 +239,9 @@ impl AuroraControllerFactory {

/// Marks the release with the hash: `hash` as latest.
#[access_control_any(roles(Role::DAO, Role::Releaser))]
#[payable]
pub fn set_latest_release(&mut self, hash: &String) {
assert_one_yocto();
let new_latest = self.releases.get(hash).unwrap_or_else(|| {
panic!("release info doesn't exist for hash: {hash}");
});
Expand All @@ -240,7 +259,9 @@ impl AuroraControllerFactory {

/// Removes the release info for hash: `hash`.
#[access_control_any(roles(Role::DAO))]
#[payable]
pub fn remove_release(&mut self, hash: &String) {
assert_one_yocto();
let release_info = self.releases.remove(hash).unwrap_or_else(|| {
panic!("release info doesn't exist for hash: {hash}");
});
Expand Down Expand Up @@ -281,13 +302,18 @@ impl AuroraControllerFactory {

/// Deploys a new contract on the release info that corresponds to the provided hash.
#[access_control_any(roles(Role::DAO, Role::Deployer))]
#[payable]
pub fn deploy(
&self,
&mut self,
new_contract_id: AccountId,
init_method: String,
init_args: Value,
blob_hash: Option<String>,
) -> Promise {
require!(
!env::attached_deposit().is_zero(),
"required at least 1 yoctonear"
);
// Check that the `new_contract_id` wasn't used for another contract before.
require!(
self.deployments.get(&new_contract_id).is_none(),
Expand Down Expand Up @@ -342,7 +368,9 @@ impl AuroraControllerFactory {
/// Adds new deployment info of previously deployed contract.
/// E.g. the contract which has been deployed by not this controller contract.
#[access_control_any(roles(Role::DAO))]
#[payable]
pub fn add_deployment_info(&mut self, contract_id: AccountId, deployment_info: DeploymentInfo) {
assert_one_yocto();
event::emit(
Event::AddDeploymentInfo,
&json!({"contract_id": contract_id, "deployment_info": deployment_info}),
Expand Down Expand Up @@ -376,12 +404,15 @@ impl AuroraControllerFactory {

/// Upgrades a contract with account id and provided or the latest hash.
#[access_control_any(roles(Role::DAO, Role::Updater))]
#[payable]
pub fn upgrade(
&mut self,
contract_id: AccountId,
hash: Option<String>,
state_migration_gas: Option<u64>,
) -> Promise {
assert_one_yocto();

self.upgrade_internal(
contract_id,
hash,
Expand All @@ -393,12 +424,14 @@ impl AuroraControllerFactory {

/// Upgrades a contract with account id and provided hash without checking version.
#[access_control_any(roles(Role::DAO))]
#[payable]
pub fn unrestricted_upgrade(
&mut self,
contract_id: AccountId,
hash: String,
state_migration_gas: Option<u64>,
) -> Promise {
assert_one_yocto();
self.upgrade_internal(
contract_id,
Some(hash),
Expand All @@ -410,7 +443,9 @@ impl AuroraControllerFactory {

/// Downgrades the contract with account id.
#[access_control_any(roles(Role::DAO))]
#[payable]
pub fn downgrade(&mut self, contract_id: AccountId) -> Promise {
assert_one_yocto();
let mut deployment_info =
self.deployments
.get(&contract_id)
Expand Down Expand Up @@ -517,6 +552,7 @@ impl AuroraControllerFactory {
UPGRADE_GAS.saturating_add(Gas::from_gas(gas))
}),
)
.with_attached_deposit(NearToken::from_yoctonear(1))
.upgrade(args.code, args.state_migration_gas)
.then(
Self::ext(env::current_account_id())
Expand All @@ -528,6 +564,7 @@ impl AuroraControllerFactory {

#[ext_contract(ext_aurora)]
pub trait ExtAurora {
/// Requires 1yN attached for security purposes
fn upgrade(
&mut self,
#[serializer(borsh)] code: Vec<u8>,
Expand Down
12 changes: 10 additions & 2 deletions src/tests/sdk/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use near_sdk::AccountId;
use near_sdk::{AccountId, NearToken};

use crate::types::ReleaseInfo;
use crate::AuroraControllerFactory;
Expand All @@ -18,6 +18,7 @@ fn test_adding_blob() {
set_env!(
predecessor_account_id: predecessor_account_id(),
input: vec![1; 256],
attached_deposit: NearToken::from_yoctonear(1),
);
let mut contract = AuroraControllerFactory::new(dao());

Expand Down Expand Up @@ -45,6 +46,7 @@ fn test_adding_blob() {
set_env!(
predecessor_account_id: predecessor_account_id(),
input: vec![2; 256],
attached_deposit: NearToken::from_yoctonear(1),
);

contract.add_release_info(
Expand Down Expand Up @@ -87,6 +89,7 @@ fn test_adding_blob_without_adding_hash() {
set_env!(
predecessor_account_id: predecessor_account_id(),
input: vec![1; 256],
attached_deposit: NearToken::from_yoctonear(1),
);

let mut contract = AuroraControllerFactory::new(dao());
Expand All @@ -98,6 +101,7 @@ fn test_check_latest_release() {
set_env!(
predecessor_account_id: predecessor_account_id(),
input: vec![1; 256],
attached_deposit: NearToken::from_yoctonear(1),
);
let mut contract = AuroraControllerFactory::new(dao());

Expand All @@ -121,6 +125,7 @@ fn test_check_latest_release() {
set_env!(
predecessor_account_id: predecessor_account_id(),
input: vec![2; 256],
attached_deposit: NearToken::from_yoctonear(1),
);

contract.add_release_info(
Expand Down Expand Up @@ -162,6 +167,7 @@ fn test_check_latest_release_blob_without_adding() {
fn test_set_latest_with_lower_version() {
set_env!(
predecessor_account_id: predecessor_account_id(),
attached_deposit: NearToken::from_yoctonear(1),
);
let mut contract = AuroraControllerFactory::new(dao());

Expand Down Expand Up @@ -190,6 +196,7 @@ fn test_set_latest_with_lower_version() {
fn test_add_latest_with_lower_version() {
set_env!(
predecessor_account_id: predecessor_account_id(),
attached_deposit: NearToken::from_yoctonear(1),
);

let mut contract = AuroraControllerFactory::new(dao());
Expand All @@ -216,9 +223,10 @@ fn test_add_latest_with_lower_version() {
fn test_use_not_allowed_pause_method() {
set_env!(
predecessor_account_id: predecessor_account_id(),
attached_deposit: NearToken::from_yoctonear(1),
);

let contract = AuroraControllerFactory::new(dao());
let mut contract = AuroraControllerFactory::new(dao());
contract.delegate_pause(new_engine(), Some("some_pause_method".to_string()));
}

Expand Down
4 changes: 4 additions & 0 deletions src/tests/workspace/delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ async fn test_delegate_execution() {

let result = factory_owner
.call(factory.id(), "delegate_execution")
.deposit(NearToken::from_yoctonear(1))
.args_json(json!({
"receiver_id": &contract_id,
"actions": vec![FunctionCallArgs {
Expand Down Expand Up @@ -51,6 +52,7 @@ async fn test_delegate_pause() {

let result = factory_owner
.call(factory.id(), "delegate_pause")
.deposit(NearToken::from_yoctonear(1))
.args_json(json!({
"receiver_id": &contract_id,
"pause_method_name": "pause_contract"
Expand Down Expand Up @@ -80,6 +82,7 @@ async fn create_factory() -> (Account, Contract, AccountId) {

let result = factory_owner
.call(factory.id(), "add_release_info")
.deposit(NearToken::from_yoctonear(1))
.args_json(json!({
"hash": HASH_3_6_4,
"version": "3.6.4",
Expand All @@ -93,6 +96,7 @@ async fn create_factory() -> (Account, Contract, AccountId) {

let result = factory_owner
.call(factory.id(), "add_release_blob")
.deposit(NearToken::from_yoctonear(1))
.args(BLOB_3_6_4.to_vec())
.max_gas()
.transact()
Expand Down
10 changes: 10 additions & 0 deletions src/tests/workspace/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ async fn test_deploy_contract() {

let result = factory_owner
.call(factory.id(), "add_release_info")
.deposit(NearToken::from_yoctonear(1))
.args_json(json!({
"hash": HASH_3_6_4,
"version": "3.6.4",
Expand All @@ -33,6 +34,7 @@ async fn test_deploy_contract() {

let result = factory_owner
.call(factory.id(), "add_release_blob")
.deposit(NearToken::from_yoctonear(1))
.args(BLOB_3_6_4.to_vec())
.max_gas()
.transact()
Expand Down Expand Up @@ -89,6 +91,7 @@ async fn test_deploy_more_than_one_contract() {

let result = factory_owner
.call(factory.id(), "add_release_info")
.deposit(NearToken::from_yoctonear(1))
.args_json(json!({
"hash": HASH_3_6_4,
"version": "3.6.4",
Expand All @@ -102,6 +105,7 @@ async fn test_deploy_more_than_one_contract() {

let result = factory_owner
.call(factory.id(), "add_release_blob")
.deposit(NearToken::from_yoctonear(1))
.args(BLOB_3_6_4.to_vec())
.max_gas()
.transact()
Expand Down Expand Up @@ -139,6 +143,7 @@ async fn test_deploy_more_than_one_contract() {

let result = factory_owner
.call(factory.id(), "add_release_info")
.deposit(NearToken::from_yoctonear(1))
.args_json(json!({
"hash": HASH_3_7_0,
"version": "3.7.0",
Expand All @@ -152,6 +157,7 @@ async fn test_deploy_more_than_one_contract() {

let result = factory_owner
.call(factory.id(), "add_release_blob")
.deposit(NearToken::from_yoctonear(1))
.args(BLOB_3_7_0.to_vec())
.max_gas()
.transact()
Expand Down Expand Up @@ -265,6 +271,7 @@ async fn test_add_deployment_info_for_existed_contract() {

let result = factory_owner
.call(factory.id(), "add_deployment_info")
.deposit(NearToken::from_yoctonear(1))
.args_json(json!({
"contract_id": silo_contract.id(),
"deployment_info": &deployment_info
Expand All @@ -277,6 +284,7 @@ async fn test_add_deployment_info_for_existed_contract() {

let result = factory_owner
.call(factory.id(), "add_release_info")
.deposit(NearToken::from_yoctonear(1))
.args_json(json!({
"hash": HASH_3_7_0,
"version": "3.7.0",
Expand All @@ -290,6 +298,7 @@ async fn test_add_deployment_info_for_existed_contract() {

let result = factory_owner
.call(factory.id(), "add_release_blob")
.deposit(NearToken::from_yoctonear(1))
.args(BLOB_3_7_0.to_vec())
.max_gas()
.transact()
Expand All @@ -299,6 +308,7 @@ async fn test_add_deployment_info_for_existed_contract() {

let result = factory_owner
.call(factory.id(), "upgrade")
.deposit(NearToken::from_yoctonear(1))
.args_json(json!({
"contract_id": silo_contract.id(),
"state_migration_gas": MIGRATION_GAS
Expand Down
Loading

0 comments on commit 1e74de8

Please sign in to comment.