flowavatar.png

Developer’s response

<aside> 💡 The developer would like to mention that the smart contract is still in development and might change before an actual release.

</aside>

Table of contents

<aside> 💡 Audits are not a guarantee of bug-free contracts, vulnerabilities may still arise after audits.

</aside>

FlovatarInbox contract

Commit: 435b547faedffec9cbcde5a99c43077921ffab88

flovatar/FlovatarInbox.cdc at dust-inbox · crash13override/flovatar

Disclaimer

Observations

Trusting user storage allows a malicious user to steal rewards


<aside> 💡 The issue is patched according to the recommendation.

</aside>

// line 395, 364
pub fun claimFlovatarCommunityDust(id: UInt64, address: Address) {
        if let claimableDust: ClaimableDust = self.getClaimableFlovatarCommunityDust(id: id, address: address){

pub fun getClaimableFlovatarCommunityDust(id: UInt64, address: Address): ClaimableDust? {
        if let flovatarScore: UFix64 = Flovatar.getFlovatarRarityScore(address: address, flovatarId: id){

The claimFlovatarCommunityDust functionality relies on the return value from the Flovatar contract to determine the Flovatar rarity score. As seen in the getFlovatarRarityScore function, any resource that is stored inside the CollectionPublicPath path with {Flovatar.CollectionPublic} interface is blindly trusted as the correct resource.

// line 552 to 562
pub fun getFlovatarRarityScore(address: Address, flovatarId: UInt64) : UFix64? {

        let account = getAccount(address)

        if let flovatarCollection = account.getCapability(self.CollectionPublicPath).borrow<&{Flovatar.CollectionPublic}>()  {
            if let flovatar = flovatarCollection.borrowFlovatar(id: flovatarId) {
                return flovatar.getRarityScore()
            }
        }
        return nil
    }