Skip to content

Commit

Permalink
Market-token: Implement new query auth interface with both permits an…
Browse files Browse the repository at this point in the history
…d viewing keys
  • Loading branch information
ueco-jb committed Dec 13, 2023
1 parent 1ba645b commit c078030
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 20 deletions.
89 changes: 74 additions & 15 deletions contracts/lending/token/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
#[cfg(not(feature = "library"))]
use lending_utils::amount::{base_to_token, token_to_base};
use shade_protocol::c_std::shd_entry_point;
use shade_protocol::{
c_std::{
shd_entry_point, to_binary, Addr, Binary, Decimal, Deps, DepsMut, Env, MessageInfo,
Response, StdResult, Uint128,
to_binary, Addr, Binary, Decimal, Deps, DepsMut, Env, MessageInfo, Response, StdError,
StdResult, Uint128,
},
contract_interfaces::snip20::Snip20ReceiveMsg,
query_auth::helpers::{authenticate_permit, authenticate_vk, PermitAuthentication},
snip20,
utils::Query,
};

use crate::error::ContractError;
use crate::msg::{
BalanceResponse, ControllerQuery, ExecuteMsg, FundsResponse, InstantiateMsg,
MultiplierResponse, QueryMsg, TokenInfoResponse, TransferableAmountResp,
};
use crate::state::{
Distribution, TokenInfo, WithdrawAdjustment, Withdrawable, BALANCES, CONTROLLER, DISTRIBUTION,
MULTIPLIER, POINTS_SCALE, TOKEN_INFO, TOTAL_SUPPLY, VIEWING_KEY, WITHDRAW_ADJUSTMENT,
use crate::{
error::ContractError,
msg::{
AuthPermit, Authentication, BalanceResponse, ControllerQuery, ExecuteMsg, FundsResponse,
InstantiateMsg, MultiplierResponse, QueryMsg, TokenInfoResponse, TransferableAmountResp,
},
state::{
Distribution, TokenInfo, WithdrawAdjustment, Withdrawable, BALANCES, CONTROLLER,
DISTRIBUTION, MULTIPLIER, POINTS_SCALE, QUERY_AUTH, TOKEN_INFO, TOTAL_SUPPLY, VIEWING_KEY,
WITHDRAW_ADJUSTMENT,
},
};
use lending_utils::amount::{base_to_token, token_to_base};

#[cfg_attr(not(feature = "library"), shd_entry_point)]
pub fn instantiate(
Expand All @@ -42,9 +47,10 @@ pub fn instantiate(
distributed_total: Uint128::zero(),
withdrawable_total: Uint128::zero(),
};

DISTRIBUTION.save(deps.storage, &distribution)?;

QUERY_AUTH.save(deps.storage, &msg.query_auth)?;

TOTAL_SUPPLY.save(deps.storage, &Uint128::zero())?;
CONTROLLER.save(deps.storage, &msg.controller.into_valid(deps.api)?)?;
MULTIPLIER.save(deps.storage, &Decimal::from_ratio(1u128, 100_000u128))?;
Expand Down Expand Up @@ -565,19 +571,72 @@ pub fn query_withdrawable_funds(deps: Deps, owner: String) -> StdResult<FundsRes
})
}

pub fn authenticate(deps: Deps, auth: Authentication, account: Addr) -> StdResult<()> {
match auth {
Authentication::ViewingKey { key, address } => {
let address = deps.api.addr_validate(&address)?;
if !authenticate_vk(
address.clone(),
key,
&deps.querier,
&QUERY_AUTH.load(deps.storage)?,
)? {
return Err(StdError::generic_err("Invalid Viewing Key"));
}
if address != account {
return Err(StdError::generic_err(
"Trying to query using viewing key not matching the account",
));
}
Ok(())
}
Authentication::Permit(permit) => {
let res: PermitAuthentication<AuthPermit> =
authenticate_permit(permit, &deps.querier, QUERY_AUTH.load(deps.storage)?)?;
if res.revoked {
return Err(StdError::generic_err("Permit Revoked"));
}
if res.sender != CONTROLLER.load(deps.storage)?.address {
return Err(StdError::generic_err(
"Unauthorized: Only proper market contract can query using permit",
));
}
Ok(())
}
}
}

/// `QueryMsg` entry point
#[cfg_attr(not(feature = "library"), shd_entry_point)]
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
use QueryMsg::*;

match msg {
Balance { address } => to_binary(&query_balance(deps, address)?),
BaseBalance { address } => to_binary(&query_base_balance(deps, address)?),
Balance {
address,
authentication,
} => {
authenticate(deps, authentication, deps.api.addr_validate(&address)?)?;
to_binary(&query_balance(deps, address)?)
}
BaseBalance {
address,
authentication,
} => {
authenticate(deps, authentication, deps.api.addr_validate(&address)?)?;
to_binary(&query_base_balance(deps, address)?)
}
TokenInfo {} => to_binary(&query_token_info(deps)?),
Multiplier {} => to_binary(&query_multiplier(deps)?),
DistributedFunds {} => to_binary(&query_distributed_funds(deps)?),
UndistributedFunds {} => to_binary(&query_undistributed_funds(deps, env)?),
WithdrawableFunds { owner } => to_binary(&query_withdrawable_funds(deps, owner)?),
WithdrawableFunds {
owner,
authentication,
} => {
authenticate(deps, authentication, deps.api.addr_validate(&owner)?)?;
to_binary(&query_withdrawable_funds(deps, owner)?)
}
}
}

Expand Down
31 changes: 26 additions & 5 deletions contracts/lending/token/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use cosmwasm_schema::{cw_serde, QueryResponses};
use shade_protocol::{
c_std::{Binary, Decimal, Uint128},
contract_interfaces::query_auth::QueryPermit,
utils::{
asset::{Contract, RawContract},
Query,
Expand All @@ -18,12 +19,14 @@ pub struct InstantiateMsg {
/// Token precision for displaying
pub decimals: u8,
/// Controller is contract allowed to ming, burn, rebase, and must be checked with to
/// enable transfer. Usually it is an wynd_lend market contract.
/// enable transfer. Usually it is an lend market contract.
pub controller: RawContract,
/// Token which will be distributed via this contract by cw2222 interface
pub distributed_token: RawContract,
/// Key used for reading data in queries
pub viewing_key: String,
/// Address of auth query contract
pub query_auth: Contract,
}

#[cw_serde]
Expand Down Expand Up @@ -86,7 +89,7 @@ pub enum ExecuteMsg {
#[cw_serde]
pub enum ControllerQuery {
TransferableAmount {
/// WyndLend contract address that calls "CanTransfer"
/// Lend contract address that calls "CanTransfer"
token: String,
/// Address that wishes to transfer
account: String,
Expand All @@ -102,15 +105,30 @@ pub struct TransferableAmountResp {
pub transferable: Uint128,
}

#[cw_serde]
pub struct AuthPermit {}

#[cw_serde]
pub enum Authentication {
ViewingKey { key: String, address: String },
Permit(QueryPermit),
}

#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg {
/// Returns the current balance of the given address, 0 if unset.
#[returns(BalanceResponse)]
Balance { address: String },
Balance {
address: String,
authentication: Authentication,
},
/// Like `Balance`, but returns the amount of base tokens.
#[returns(BalanceResponse)]
BaseBalance { address: String },
BaseBalance {
address: String,
authentication: Authentication,
},
/// Returns metadata on the contract - name, decimals, supply, etc.
#[returns(TokenInfoResponse)]
TokenInfo {},
Expand All @@ -125,7 +143,10 @@ pub enum QueryMsg {
UndistributedFunds {},
/// Queries for funds distributed but not yet withdrawn by owner
#[returns(WithdrawableFundsResponse)]
WithdrawableFunds { owner: String },
WithdrawableFunds {
owner: String,
authentication: Authentication,
},
}

impl Query for QueryMsg {
Expand Down
1 change: 1 addition & 0 deletions contracts/lending/token/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,4 @@ pub const DISTRIBUTION: Item<Distribution> = Item::new("distribution");
pub const WITHDRAW_ADJUSTMENT: Map<&Addr, WithdrawAdjustment> = Map::new("withdraw_adjustment");

pub const VIEWING_KEY: Item<String> = Item::new("viewing_key");
pub const QUERY_AUTH: Item<Contract> = Item::new("query_auth");

0 comments on commit c078030

Please sign in to comment.