# Funds

One unit of ZIL as a native token is equal to 1000000000000 QA. (1 ZIL = 10^12 QA). When we deal with ZIL as a unit in Scilla, it is represented as an `Uint128`. The below example shows how to accept/send funds to/from a smart contract.

##### danger

The example does not implement ownership logic, therefore anyone can withdraw funds. Do not use this contract.

## Accept ZIL contract#

`Deposit` takes any ZIL presented to it with the `accept` keyword.

`Withdraw` checks the amount wanting to be withdrawn against what the contract currently has.

`Empty` sends all of the contract funds to the `_sender` of the function.

``````scilla_version 0(*********************************************************************************)(* Receive, store and send funds [QA = 10^{-12} ZIL, LI = 10^{-6} ZIL = 10^6 QA] *)(* in a smart contract                                                           *)(*********************************************************************************)import IntUtils
library Funds
let one_msg = (* Wrap single message into singleton list *)  fun (msg : Message) =>    let nil_msg = Nil {Message} in    Cons {Message} msg nil_msg
let msg_as_list_wo_tag = (* Create transaction message as singleton list without a tag *)  fun (recipient : ByStr20) =>  fun (amount : Uint128) =>    let msg = {_tag : ""; _recipient : recipient; _amount : amount } in    one_msg msg
let is_positive = (* check if a uint is > 0 *)  fun (n : Uint128) =>    let zero = Uint128 0 in    uint128_gt n zero
contract Funds()
procedure TransferTo(to : ByStr20, amount : Uint128)  msgs = msg_as_list_wo_tag to amount;  send msgsend
transition Deposit() (* send QA to contract to receive and store it in contract *)  received = is_positive _amount;  match received with  |True  =>    accept;    b <- _balance;    ev = {_eventname: "DepositSuccess"; amount_received: _amount; new_balance: b};    event ev  |False =>  endend
transition Withdraw(amount : Uint128) (* withdraw an amount from the contract *)  b <- _balance;  is_more_than_balance = uint128_gt amount b;  match is_more_than_balance with  |True => (* requested more than the balance, do not fullfil request *)    ev = {_eventname: "WithdrawFailue"; amount_requested: amount; new_balance: b};    event ev  |False =>    new_b = builtin sub b amount;    TransferTo _sender amount;    ev = {_eventname: "WithdrawSuccess"; amount_withdrawn: amount; new_balance: new_b};    event ev  endend
transition Empty() (* withdraw everything *)  b <- _balance;  zero = Uint128 0;  TransferTo _sender b;  new_b <- _balance;  ev = {_eventname: "EmptySuccess"; amount_withdrawn: b; new_balance: new_b};  event evend``````

## Refund mechanism#

This function checks the `_amount` against a passed parameter `cap`. If the amount sent is less than cap, the procedure does nothing, but in the case where you send more than `cap`, it can calculate the difference equal to where you send exactly the right amount and returns the excess amount to the user.

``procedure AcceptWithCap (cap : Uint128)  sent_more_than_necessary = builtin lt cap _amount;  match sent_more_than_necessary with  | True =>      amount_to_refund = builtin sub _amount cap;      accept;      msg = { _tag : ""; _recipient: _sender; _amount: amount_to_refund };      msgs = one_msg msg;      send msgs  | False =>  endend``