# Tipping Bot Functional Description This document describes the commands and inner functions of the tipping bot as it was implemented. ## Basics The bot is using a central wallet, not smartcontract, to store the funds deposited by users. This means the bot has access to the private key for the deposit wallet during runtime and has full control over any funds received. ## Commands When the Discord user uses *any* command for the first time the bot will reply with a prompt to read and accept the TOS instead of the usual command output. This looks like this: ![image](https://hackmd.io/_uploads/rys9ReX_a.png) In this example the user tried to use the `/balance` command. The bot noticed the user has not accepted the Terms of Service yet and instead replied with this prompt. Accepting the TOS creates a record in our database with the timestamp and Discord user id. This allows us to keep track of user consent to our TOS. ![image](https://hackmd.io/_uploads/ByHv1Z7Oa.png) > If the TOS ever change we can set a flag on this database record and the bot will ask the user for consent again Additionaly the user is sent a direct message. > This only works if the user has enabled direct messages. The direct message the user receives includes the link to the TOS at the time of acceptance and the timestamp as well as a welcome message that guides them towards the next step for using the bot: ![image](https://hackmd.io/_uploads/BkjF1-m_6.png) --- ### `/set-wallet <wallet>` The `/set-wallet` command allows a discord user to link their Ronin Address with their Discord account. The command supports ronin addresses and RNS names: ![image](https://hackmd.io/_uploads/H15JgWQ_a.png) ![image](https://hackmd.io/_uploads/HJAggbmdT.png) If the command executes successfull the following message is shown: #### To the user setting their wallet ![image](https://hackmd.io/_uploads/rkE4gWXda.png) > The part about the "RNS Information" is only shown when the user used a .ron name instead of a ronin address. The RNS is not stored and only used to retrieve the connected wallet ID once. If the ronin address associated with the RNS name changes the user has to use the `/set-wallet` command again! If the user has enabled direct messages the same message is also send to them as a DM. #### To the admin log channel: ![image](https://hackmd.io/_uploads/HyaYgb7uT.png) --- ### `/deposit` The deposit command takes no arguments and provides information about the address where the user has to send token to deposit them into the bot, the address they have to sent from (The address they set using `/set-wallet`) and the supported Token: ![image](https://hackmd.io/_uploads/B1Exb-7_6.png) > Supported token are manged by Discord Server Administrators > If a user deposits an unsupported token they won't be able to get it back for now. The bot does not keep records about deposits for unsupported tokens. In the future the bot may offer admins a refund interface to send these deposits back. The latter is not implemented yet and I just put this here as an internal note. For now: Send unsupported token => Token lost --- ### `/balance` The `/balance` command provides the user with an overview of their current off-chain tipping balances. ![image](https://hackmd.io/_uploads/H1tqZ-m_6.png) --- ### `/withdraw <token> <amount>` The `/withdraw` command allows the user to withdraw a fraction or all of their token from the bot to their connected wallet. ![image](https://hackmd.io/_uploads/HJDyMbX_p.png) > The available token in this particular list is filtered. Only token where the user has an off-chain balance larger than 0 are shown. If the user has no balances the list will be empty. The user can withdraw any amount of token that is less or equal to their balance: ![image](https://hackmd.io/_uploads/HklQG-XOp.png) ![image](https://hackmd.io/_uploads/S1CQMWXua.png) If they simply wish to withdraw everything they can use `all` in the amount field. The bot automatically substitutes this for the correct value. Upon sending the command the user will see the following message: ![image](https://hackmd.io/_uploads/SkerCIA_p.png) > Users can keep track of all their deposits and withdrawals with the `/history` command It shows the user their old and new balance as well as providing a link to te app.ronin explorer. Cases in which the user attempts to withdraw more than what they have an error message is shown instead: ![image](https://hackmd.io/_uploads/B1ZfmZ7OT.png) > The minimum withdraw amount is currently based on the tokens decimals. In a future update this will become configurable. Reason is that a minimum withdrawl of 0.0001 RON is fine where as for WETH that does not seem ideal. --- ### `/history <type>` Shows your five most recent deposits or withdrawals and includes a button to open the full overview in your browser: ![image](https://hackmd.io/_uploads/rypjAL0dp.png) The web view: ![image](https://hackmd.io/_uploads/BJ8aALRup.png) > The limit on the web is 250 to discourage people from spamming small transactions to cause the server and site to lag. Another service to get a complete export may be added in the future. In this screenshot you can also see a pending withdrawal: ![image](https://hackmd.io/_uploads/SJnm1wRdp.png) > For privacy reasons all links expire after 15 minutes. ![image](https://hackmd.io/_uploads/BJGdyDCu6.png) --- ### `/wallet` Shows the user their currently connected wallet: ![image](https://hackmd.io/_uploads/SJ8DQZQua.png) ### `/tip <user> <amount> <token>` Now this command is what the bot is all about. Tipping token. The `<user>` allows to select a user from the server member list. It updates as you start typing. The `<amount>` field is, similar to the one on the `/withdraw` command, supports full numbers `1`,`2` etc as well as fractions: `1.2`,`0,9` > I intentionally wrote `0,9` witha a comma. As different parts of the world either use . or , as a decimal point the bot accepts both. `0,9` is simply converted to `0.9` internally. ![image](https://hackmd.io/_uploads/ByrwNW7Op.png) When sent the tip is not immediately executed. Instead the bot replies with a prompt the tipping user can confirm or cancel. > At this point no checks have been run if the user actually has the amount of token they want to tip. As this is only really required once the user confirms the tip we save on computing ressources. ![image](https://hackmd.io/_uploads/S1noNZ7_6.png) Given the user clicks confirm three things happen: 1. The tipping user sees the following message: ![image](https://hackmd.io/_uploads/H111Hb7ua.png) It gives them a quick overview about their old and new balance. 2. A public message is send by the bot in the same channel the tip command was issued: ![image](https://hackmd.io/_uploads/rkGzHbXd6.png) 3. A message is also send to the admin log channel: ![image](https://hackmd.io/_uploads/B1HXrbXdT.png) --- ### `/rain <token> <amount>` The `/rain` command allows for interactive token distribution. When a `/rain` starts everyone that has connected their wallet can join and in the end will receive a small portion of `<amount>`. > While the `/rain` command has an input for `<token>` only RON is currently supported ![image](https://hackmd.io/_uploads/ryMcr-QOT.png) As with the `/tip` command the `/rain` command asks for confirmation before it is executed: ![image](https://hackmd.io/_uploads/BJJhS-7ua.png) If canceled nothing happens. If confirmed the following message is send to the channel: ![image](https://hackmd.io/_uploads/ryqaBWQua.png) Now everyone, including the person who initiated the `/rain`, can click the join button. The "Participant" counter is updated every 5 seconds. > A visual indicator for the update is the changing color of the left border of the message. Furthermore the `in 5 Minutes` is automatically updated by Discord and even counts down the last few seconds. When a user clicks the "Join The Rain" button a confirmation is send to them: ![image](https://hackmd.io/_uploads/S1mU8W7da.png) > Once joined you cannot leave the game. If the user clicks the button again they receive this message instead: ![image](https://hackmd.io/_uploads/Sy9Jv-Qda.png) > I say game and the bot wishes the user good luck because the final distribution has a certain "luck" element built into it. The full code can be found on GitHub. In my example two people joined the rain. The game concludes after 5 minutes. The join button is disabled and the results are posted to the channel: ![image](https://hackmd.io/_uploads/rJSwPZQda.png) In this particular example my "luck" was slightly higher than that of the second participant. I got ever so slightly more than them. > While the luck factor has some influence on the final reward distribution I made sure that it does not give an unfair advantage to anyone by limiting it's imapact. --- ### `/help` The `/help` commands provides brief explanations about each command to the user. ![image](https://hackmd.io/_uploads/rkodOZ7up.png) The user can then just click on the highlightes command to open its prompt. --- ### `/ping` Replies with Pong! - It's just a small check to see if the bot is alive. --- ## Technical description of the processing of user deposists Given a user called `Mike` that has connected their wallet to the bot and has previously accepted the TOS: 1. Mike sends 100 RON to `ronin:deposit_address` 2. Transaction is confirmed and included in a block 3. The [SkyMavis Webhook System](https://docs.skymavis.com/tools/webhooks) sends a HTTP request to the tipping bot. 4. The bot performs various checks: - sending address connected to discord user - receiving address is the deposit address - received token is actually supported - transaction hash has not yet been progressed 5. Given all checks pass the received token amount is credited to Mikes off-chain token balance for RON. 6. A notification is send to the admin log channel: ![image](https://hackmd.io/_uploads/By-Y9bXua.png) > Because this happens asynchronous there is no notification send to the user. It is planned to attempt to send a direct message in a future update. --- ## The WebInterface The webinterface for the bot can be found at https://axie.tipping.bot and requires the visitor to login with their discord account. Only if the vistor has the MANAGE_SERVER permission or the bot's admin role access in granted. While most of the web interface is readonly (for now) it will eventually be the place for moderators and supporter to check on user acitivity. Here are a few screenshots of the current WIP version: #### The Dashboard ![image](https://hackmd.io/_uploads/H1bY0bQup.png) #### User list ![image](https://hackmd.io/_uploads/SkQcC-m_p.png) #### Commands ![image](https://hackmd.io/_uploads/SkejAbQ_p.png) > Useful tip: clicking on the sniuppets highligtes in red copies the snipped to your clipboard. Posting it in Discord will create a clickable link to the command. Snippets may change over time. Make sure to always copy the most recent version before posting. #### Custom Commands ![image](https://hackmd.io/_uploads/rJ1G1zmu6.png) Custom commands are a great way to provide additional information to users. They use Discords slash command feature. Their name must be unique. > Due to caching in the discord app it may take a while before the new command shows up in the UI. Restarting/Reloading Discord fixes this immediately. #### Treasury ![image](https://hackmd.io/_uploads/HyDIgMQdp.png) This site lists all on-chain token balances of the bot. > Only shows token enabled in at least one discord server --- ## Thoughts and possible FAQ I suggest the TOS explain that funds send to the bot are no longer owned by the sender once the deposit is processed. If an unsupported token is sent that is the case. The user has no right to a refund. We do our best to keep the bot online. If it's offline for any reason the user cannot request manual withdrawls either. As for GDPR: If we receive a GDPR request we can provide the following data: - When did the user accept the TOS - Deposit / Withdrawl History - Tipping History If we receive a request to delete user data according to the GDPR we can do this. If any balances are left on the account they are withdrawn to the currently connected wallet. Withdrawing to a different wallet should not be possible. The user can just use `/set-wallet` and update it. If a user looses their Discord account eg they get hacked / banned - We cannot restore access to the funds connected with their discord account. > Funds are bound to the discord ID of a user - not their connected ronin address We cannot undo actions the user has done. Eg we cannot reverse a tip or stop a rain. All actions are final. We should reserve the right to exclude any user for any reason we seem fit from using the bot. Using the `/admin` command or the web interface any discord account can be blocked. If blocked a user cannot interact with the bot at all. This includes receiving tips or joining a rain. > We should debate if in these cases their funds should also be locked. As of now a block includes the `/withdraw` command. Due to unforseen issues the bot could break while executing a command. While the bot has strong error handling it is still possible that something goes wrong. (Never say never) - If a user loses funds due to a crash we will do our best to understand the bug and compensate the user. If that is impossbile the funds are unfortunately lost. > To avoid this security team is conducting a code review. Additionally the bot is currently being used by a few axie community server and is also beeing tested on our own testserver. Many bugs have been fixed already.