<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: rahimklaber</title>
    <description>The latest articles on Forem by rahimklaber (@rahimklaber).</description>
    <link>https://forem.com/rahimklaber</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F623486%2F83d80e42-6d4f-4810-a240-6ef4fe074c1a.jpeg</url>
      <title>Forem: rahimklaber</title>
      <link>https://forem.com/rahimklaber</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rahimklaber"/>
    <language>en</language>
    <item>
      <title>Stacker - autocompounding vaults</title>
      <dc:creator>rahimklaber</dc:creator>
      <pubDate>Sun, 18 Aug 2024 21:47:31 +0000</pubDate>
      <link>https://forem.com/rahimklaber/stacker-autocompounding-vaults-4n6g</link>
      <guid>https://forem.com/rahimklaber/stacker-autocompounding-vaults-4n6g</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/stellar"&gt;Build Better on Stellar: Smart Contract Challenge &lt;/a&gt;: Build a dApp&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built something called Stacker. Its a collection of vaults that allow allow someone to deposit yield-bearing assets. The yield is periodically claimed and reinvested to receive more of the yield-bearing asset.&lt;/p&gt;

&lt;p&gt;The vault takes a fee for its service.&lt;/p&gt;

&lt;p&gt;Currently there is one vault. It allows you to deposit Aquarius &lt;a href="https://aqua.network/pools/CA6GAFOJCW4MGQQBUCQUSA3CLIH25G4SNKB2JHYKZCVWZTNW5VXMSC4O/" rel="noopener noreferrer"&gt;AQUA/USDC LP&lt;/a&gt; shares. Some Aquarius pools are receive aqua rewards. Everyday, A bot (or a person 🤔) claims the rewards, sells them and deposits back into the lp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;The app is live on mainnet and can be found here: &lt;a href="https://stacker.rahimklaber.me/" rel="noopener noreferrer"&gt;https://stacker.rahimklaber.me/&lt;/a&gt;.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/c196f0fcd6d3410296fbcad86cf349d7"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  My Code
&lt;/h2&gt;

&lt;p&gt;The code can be found here: &lt;a href="https://github.com/rahimklaber/stacker" rel="noopener noreferrer"&gt;https://github.com/rahimklaber/stacker&lt;/a&gt;. Some more implentation details can be found there.&lt;/p&gt;

&lt;p&gt;The repo contains a frontend and the contract. The frontend is written in Kotlin and uses &lt;a href="https://github.com/rahimklaber/stellar_kt" rel="noopener noreferrer"&gt;https://github.com/rahimklaber/stellar_kt&lt;/a&gt; to interact with Stellar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Journey
&lt;/h2&gt;

&lt;p&gt;I came up with the idea last week while claiming my &lt;a href="https://www.blend.capital/" rel="noopener noreferrer"&gt;blend&lt;/a&gt; rewards. I always forget to claim them and thought it would be cool if it was automagic. &lt;/p&gt;

&lt;p&gt;Initially, i spent quite a bit of time understanding how vaults work. After that, the hard part of integrating with aquarius and understanding how the lp pools work.&lt;/p&gt;

&lt;p&gt;I'm quite happy that I was able to use my own Stellar SDK for this and that it worked correctly 😁.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I learned
&lt;/h3&gt;

&lt;p&gt;Cross contracts calls involving token transfers (or any kind of deep auth) is extremely annoying. You have to explicityly authorize the deep contract call. On one hand, this is nice because it limits the risk of exploits. On the other hand, it is very annoying while programming.&lt;/p&gt;

&lt;p&gt;I now kinda know how vaults work and about some attacks against them. Hopefully, the safeguards I coded are good enough 😅.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>stellarchallenge</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>Token-based DAO on Soroban.</title>
      <dc:creator>rahimklaber</dc:creator>
      <pubDate>Thu, 23 Mar 2023 18:07:25 +0000</pubDate>
      <link>https://forem.com/rahimklaber/token-based-dao-on-soroban-lk3</link>
      <guid>https://forem.com/rahimklaber/token-based-dao-on-soroban-lk3</guid>
      <description>&lt;p&gt;In this post I will be walking through a DAO contract on Soroban.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are DAOs?
&lt;/h2&gt;

&lt;p&gt;According to Ethreum.org: "A DAO is a collectively-owned, blockchain-governed organization working towards a shared mission."&lt;/p&gt;

&lt;p&gt;DAOs leverage smart-contracts to allow shared decision making and shared ownership of wealth. &lt;/p&gt;

&lt;p&gt;I previously wrote a &lt;a href="https://github.com/rahimklaber/soroban_dao"&gt;DAO contract&lt;/a&gt; that uses reputation to determing voting power and membership. However DAOs normally use a token as a way to determine membership, and the more tokens you have, the more voting power you have.&lt;/p&gt;

&lt;h2&gt;
  
  
  Soroban DAO
&lt;/h2&gt;

&lt;p&gt;The DAO contract can be found here: &lt;a href="https://github.com/rahimklaber/soroban_token_dao"&gt;https://github.com/rahimklaber/soroban_token_dao&lt;/a&gt;, and consists of the DAO contract and a modified token contract.&lt;br&gt;
Note: For usage examples, see &lt;a href="https://github.com/rahimklaber/soroban_token_dao/blob/master/dao/src/test.rs"&gt;https://github.com/rahimklaber/soroban_token_dao/blob/master/dao/src/test.rs&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  DAO Contract
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;DaoTrait&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;dao_token_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BytesN&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;min_prop_duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;min_quorum_percent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;min_prop_power&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;//create proposal and return its id&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;c_prop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proposal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Proposal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;//try to execute prop&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prop_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;proposal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prop_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ProposalExtra&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;//allow a member to vote on a proposal]&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;vote_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prop_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;v_against&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prop_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;v_abstain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prop_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;votes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prop_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;VotesCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;//min power to propose&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;min_prop_p&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i128&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// get minimum duration of proposal&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;min_dur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;//minimum percentage to for proposal to pass.&lt;/span&gt;
    &lt;span class="c1"&gt;// so for (votes + abstain / total_power) * 100 must be &amp;gt; quorum&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;quorum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The contract consists of a few settings that can be set at initialization:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;dao_token_id&lt;/code&gt; : The id of the token used to determine voting power. The DAO contract should be set as the admin of the token.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;min_prop_duration&lt;/code&gt;: The minimum duration of a proposal in seconds.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;min_quorum_percent&lt;/code&gt;: The minimum percentage of votes that is needed for a proposal to pass.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;min_prop_power&lt;/code&gt;: The minimum amount of tokens needed to submit a proposal.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Proposal
&lt;/h4&gt;

&lt;p&gt;Someone with a voting power of atleast &lt;code&gt;min_prop_power&lt;/code&gt; can submit a proposal. a proposal, which other can vote on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[contracttype]&lt;/span&gt;
&lt;span class="nd"&gt;#[derive(Clone,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ProposalInstr&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//contract id&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;c_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BytesN&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RawVal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[contracttype]&lt;/span&gt;
&lt;span class="nd"&gt;#[derive(Clone,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Proposal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;end_time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// instrunctions will be executed in sequence&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;instr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ProposalInstr&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A proposal consists of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;end_time&lt;/code&gt;: The time in unix seconds after which a proposal cannot be voted for and can be executed.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;instr&lt;/code&gt;: Instructions that would be executed in the case that a proposal is executed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;instr&lt;/code&gt; contains the arguments needed to do a cross-contract call, and would be used like this: &lt;code&gt;env.invoke_contract(&amp;amp;instr.c_id,   &amp;amp;instr.fun_name,   instr.args)&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Voting
&lt;/h4&gt;

&lt;p&gt;Users can vote with the vote functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;vote_for&lt;/code&gt;: Vote for the proposal.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vote_against&lt;/code&gt;: Vote against the proposal.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;v_abstain&lt;/code&gt;: Register the fact that you are abstaining. This can be helpfull if there is a minimum participation requirement. Or if you would like to show participation, but do not have a preference.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  DAO Token
&lt;/h3&gt;

&lt;p&gt;The DAO token is a modified version of the Example Token contract from the soroban docs: &lt;a href="https://soroban.stellar.org/docs/how-to-guides/tokens"&gt;https://soroban.stellar.org/docs/how-to-guides/tokens&lt;/a&gt;.&lt;br&gt;
The token was modified by adding functionality such that it can be used with the DAO contract.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;DaoExtensionTrait&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Get voting power of a Address&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;power&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i128&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;power_at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;at_block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i128&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// delegate power `from` to `to`&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;delegate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i128&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// remove delegation&lt;/span&gt;
    &lt;span class="c1"&gt;// amount is the amount we want to remove&lt;/span&gt;
    &lt;span class="c1"&gt;// from is the person who delegated&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;r_delegate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i128&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;//get amount that `from` has delegated to `to`&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_d_a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i128&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I added a file which contains the &lt;code&gt;DaoExtensionTrait&lt;/code&gt; trait. Implementing the the trait and annotating the implementation with &lt;code&gt;#[contractimpl]&lt;/code&gt; means that the DAO code will end up in the final WASM next to the normal token code.&lt;/p&gt;

&lt;p&gt;The extra functions have only 2 uses. Being able to know someones voting power, and being able to delegate power to someone.&lt;/p&gt;

&lt;p&gt;There are a few things to keep in mind when voting:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Before voting, a user must have power delegated to them. They can either delegate to themselves or ask someone else to delegate their tokens. This can be done with the &lt;code&gt;delegate&lt;/code&gt; function. To reduce complexity of the contract, users must explicitly delegate their tokens to themselves.&lt;/li&gt;
&lt;li&gt;A user can only vote using the delegated tokens that they had before the proposal was created. Without this, a user would be able to vote, remove the delegation and add the delegation to another account and vote again. The &lt;code&gt;power_at&lt;/code&gt; function is used to get the power of an address at the time that the proposal was created.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Possible Improvements
&lt;/h2&gt;

&lt;p&gt;Currently the contracts are not as good as they could be.&lt;br&gt;
Here is a list of things to change or to consider when making your own DAO contract:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Currently there is no way to change the DAO contract settings. This includes things like the &lt;code&gt;min_prop_duration&lt;/code&gt; or &lt;code&gt;min_prop_power&lt;/code&gt;. This file can be referenced when trying to implement this. In short, you have to check when the proposal is attempting to execute a function of the DAO contract and then handle that.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;min_quorum_percent&lt;/code&gt; does nothing. For it to work, the current token supply must be known. However, this is not exposed in the Soroban token specification. This can implemented by modifying the Token contract or by tracking the value in the DAO contract. This would work if only the DAO contract is able to mint the tokens.&lt;/li&gt;
&lt;li&gt;A proposal currently contains no metadata. For example, it could be usefull to have a description that explains the proposal. This could be implemented by uploading a document to IPFS and the referencing the IPFS hash of the document when creating the proposal.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>blockchain</category>
    </item>
  </channel>
</rss>
